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

Thorsten Seitz tseitz42 at icloud.com
Sun Feb 14 23:59:13 CST 2016


I like this alternative proposal and would like to see it discussed more deeply, as it seems to be very lightweight and natural.

-Thorsten 

Am 14.02.2016 um 18:16 schrieb Michel Fortin via swift-evolution <swift-evolution at swift.org>:

>> 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
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list