[swift-evolution] [Review] SE-0030 Property Behaviors

Michel Fortin michel.fortin at michelf.ca
Sun Feb 14 11:16:10 CST 2016


> What is your evaluation of the proposal?

I think property behaviors are a nice idea. But I feel the current proposal is trying to handle too many disparate use cases using an approach that doesn't work that well for all of them.

I already expressed my view of this in pre-review, and I'm a bit disappointed to see no mention of my suggestions in the "Alternatives considered" section. Basically I think this proposal should be broken in three or four separate smaller features that can each stand on their own:

1. the ability to add `func`, `var`, and `let` inside any property declaration to handle metadata and meta-operations. For instance:

	var count: Int {
		func reset() { count = 0 }
	}

	count::reset() // or some other syntax

	var root: NSObject {
		var lastModified: NSDate? = nil
		didSet { lastModified = NSDate() }
	}

	print(root::lastAccess)

	var lang: String {
		let xmlName = "xml:lang"
	}

	element.addAttribute(name: lang::xmlName, value: lang)

2. the ability to encapsulate those `func` and `var` inside a behaviour for reuse:

	behavior resettable<T>: T {
		func reset() { currentValue = initValue }
	}
	var [resettable] count: Int

	count::reset() // or some other syntax

	behavior changeMonitored<T>: T {
		var lastModified: NSDate? = nil
		didSet { lastModified = NSDate() }
	}
	var [changeMonitored] root: NSObject

	print(root::lastModified)

3. the ability for the behavior (extending point 2) to change the base storage type of the property:

	behavior synchronized<T>: Synchronized<T> {
		get { return currentValue.value }
		set { currentValue.value = newValue }
	}

	var [synchronized] count: Int

	count = 1

4. a way to define property observers such as `willSet` globally, with no need to attach a particular behavior to a variable:

	observer willSet<T>(newValue: T) {
		set {
			willSet(newValue)
			currentValue = newValue
		}
	}

	var count: Int {
		willSet {
			print("\(count) will become \(newValue)")
		}
	}

I don't have a fully formed proposal, but there's a bit more details in a relatively recent discussion here (I changed the syntax a bit since then):

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007194.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007238.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007295.html


> Is the problem being addressed significant enough to warrant a change to Swift?


There are many disparate problems this proposal is trying to address.

Some of the problems illustrated in the proposal would benefit from it, but not all. In some cases, such as the `observed` behavior, it makes things worse because your observer functions have to be tied to a behavior attached to the variable.


> Does this proposal fit well with the feel and direction of Swift?

Accessing functions inside behaviors such as `resettable` adds two layers of metadata/meta-operations to the property (one is the behavior name, the other is the `reset()` function). I would argue that including `resettable` before calling a `reset()` function is redundant. It is also against the principles of separation between the interface and the implementation since you might want to define `reset()` in your own way for some variables, which would entail the creation of a separate behavior with a different name, which would change the way you make your `reset()` call. To me, the way you can call behavior functions seems rather heavyweight and inflexible.

Swift currently lets you add `willSet` and `didSet` observers without having to opt-in through some special syntax. Requiring that a behavior be added, such as `observed` before being able to use these or other custom kinds of observers seems like a step in the wrong direction to me.

That's the two main points that I think don't work well in the current proposal when compared to the rest of Swift.


> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I haven't.

Though the syntax `property.[behavior].func()` reminds be a bit of how you select an axis when accessing nodes in XPath.


> How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed and participated to the discussions pre-review. I have less time to follow it now, so I might have missed recent developments.


-- 
Michel Fortin
https://michelf.ca



More information about the swift-evolution mailing list