[swift-evolution] Fluent syntax (replacing void with a useful default return value)

Tino Heth 2th at gmx.de
Sun Dec 20 12:18:07 CST 2015


> In order to evaluate this more fully, I'd like to see some examples of real code that would be improved by having this facility, but in general, I'd be concerned that this proposal making mutating/side-effectful method calls look more like purely-functional ones.
Mh, maybe I'm a little bit old-fashioned, but I expect side effects everywhere unless purity is guaranteed ;-)

It's really no big thing - one example is small enough to inline it instead of pushing a playground.
As Kevin pointed out, there are solutions that are probably better, but require a real change in the language.

I think Objective-C didn't copy the chaining-pattern from Smalltalk because it's quite ugly to calculate the number of opening braces in advance, but in Swift, I really like that approach.
Builders are actually the most common use case, but the pattern fits well wherever you have to do configuration.
Of cause, it's always a bit of personal preference how to rate a solution, but for those who like the concept of fluent interfaces, returning self is much more valuable than void (well, considering the traffic, it doesn't seem that many Swift-Users care for the topic ;-).

import Cocoa

func backgroundStuff() {
	print("Working very hard...")
	NSThread.sleepForTimeInterval(0.5)
}

func finish() {
	print("Just imagine I'm doing some GUI-cleanup")
}

func current() {
	let queue = NSOperationQueue()

	let mainOperation = NSBlockOperation(block: backgroundStuff)
	mainOperation.name = "Download-Task"
	mainOperation.queuePriority = .VeryHigh
	queue.addOperation(mainOperation)

	let cleanup = NSBlockOperation(block: finish)
	cleanup.queuePriority = .Low
	cleanup.addDependency(mainOperation)
	NSOperationQueue.mainQueue().addOperation(cleanup)
}

extension NSOperation {
	func addToQueue(queue: NSOperationQueue = NSOperationQueue.mainQueue()) -> Self {
		queue.addOperation(self)
		return self
	}

	func changePriority(priority: NSOperationQueuePriority = .Normal) -> Self {
		queuePriority = priority
		return self
	}

	func changeName(name: String) -> Self {
		self.name = name
		return self
	}

	func waitFor(dependency: NSOperation) -> Self {
		addDependency(dependency)
		return self
	}
}

func fluent() {
	let queue = NSOperationQueue()
	let mainOperation = NSBlockOperation(block: backgroundStuff).changeName("DownloadTask").changePriority(.VeryHigh)
	mainOperation.addToQueue(queue)
	NSBlockOperation(block: finish).changePriority(.Low).waitFor(mainOperation).addToQueue()
}

// second one - this wont actually compile, but the needed code wouldn't be complicated
self.view.layer.changeBorderWidth(3).changeBorderColor(UIColor.redColor().CGColor)



More information about the swift-evolution mailing list