[swift-evolution] [Proposal] Property behaviors

Curt Clifton curt at omnigroup.com
Sat Jan 23 19:58:43 CST 2016


This is an excellent update. Simplifying the proposal provides a strong starting point without foreclosing solutions to some of the thorny cases addressed in the original proposal. It will be good to have experience with the simpler behaviors when designing more powerful features later. (For example, I wonder if we'll discover that something like "behavior combinators" are the right way to solve behavior composition.)

Can the core team comment on the likely evolution of proposals like property behaviors that are separated into first steps and future work? That is, should we expect that some of the future work might be in scope for Swift 3, depending on the implementation of the first steps? Or is the hope to lock down the scope for Swift 3 sooner rather than later?

Regarding the foo.[resettable].reset() syntax, I agree that it's an improvement over the original proposal, both because it disambiguates with member access and because it provides better alignment of declaration and use. I'm still not thrilled with it. As noted, it's easy to confuse the new syntax with subscripting. It also occurs to me that reusing common punctuation for an uncommon* language feature might lead to confusion. Will people tend to make what they feel are educated guesses about what a behavior reference means and get in trouble? (*Apart from Kotlin, do other languages have property behaviors?) 

So, I continue to prefer a sigil at both declaration and use. On the other hand, I don't know what sigil we'd use. It seems we're likely to spend the '#' sigil on #selector, #sourceLocation, and friends; '@' is already spoken for; and I suppose that 🗣 would be right out. :-)

I see that the grammar for property-behavior-decl includes the ability to bind the property name, though the first bullet in the section "Bindings within Behavior Declarations" says that this would be a future extension. At the least, these should be reconciled. If the reconciliation favors punting this aspect, I'd like to see it mentioned in the Future Directions section.
 
That said, I'd love to see binding of the property name in the first iteration of behaviors. On the off chance that an example usage would be helpful, here's how we could begin implementing something like Omni's OAAppearance using a behavior:

```
public protocol PropertyListBackable {
    var backingPropertyList: [String: AnyObject] { get }
    func plistValueForKey<T>(key: String) -> T
}

public behavior var [plistBacked] propertyName: Value where Self: PropertyListBackable {
  get {
    return self.plistValueForKey(propertyName)
  }
}

extension PropertyListBackable {
    func plistValueForKey<T>(key: String) -> T {
        let plist = self.backingPropertyList
        let maybeResult = plist[key]
        guard let result = maybeResult as? T else {
            fatalError("Misconfigured property list")
        }
        return result
    }
}

class Appearance: PropertyListBackable {
    let backingPropertyList: [String: AnyObject]
    var [plistBacked] distance: Double    

    /// Returns the contents of property list resource <ClassName>.plist, where ClassName is the name of the receiver type.
    class func propertyListForType() -> [String: AnyObject] {
        let typeName = String(self)
        let maybePlistURL = NSBundle.mainBundle().URLForResource(typeName, withExtension: ".plist")
        guard let plistURL = maybePlistURL else {
            fatalError("Missing property list: \(typeName).plist")
        }
        
        let maybeResult = NSDictionary(contentsOfURL: plistURL)
        guard let result = maybeResult as? [String: AnyObject] else {
            fatalError("Malformed property list file: \(typeName).plist")
        }

        return result
    }
    
    init() {
        let plist = self.dynamicType.propertyListForType()
        backingPropertyList = plist
    }
}

class MyCoolAppAppearance: Appearance {
    var [plistBacked] faveSigil: String
}

let appearance = Appearance()
let distance = appearance.distance
print("distance: \(distance)") // distance: 3.0
        
let mcaAppearance = MyCoolAppAppearance()
let sigil = mcaAppearance.faveSigil
print("sigil: \(sigil)") // sigil: ❤️
```

Cheers,

Curt
-------------------------
Curt Clifton, PhD
Software Developer
The Omni Group
www.curtclifton.net


> On Jan 22, 2016, at 4:33 PM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I've revised my proposal again based on more feedback. Syntax changes include:
> 
> - adopting John McCall's declaration-follows-use syntax for behavior declarations. I think this looks nice and provides a reasonable framework for binding all the fiddly bits of a property, such as its type, name, and initializer.
> - changing the proposed syntax for behavior member lookup to 'property.[behavior].member', as suggested by Tal Atlas and others. I think this has a nice symmetry with the `var [behavior]` declaration syntax, and doesn't occupy any new sigils. On the other had, Curt Clifton and others have raised the point that it could be mistaken for a subscript at a glance.
> 
> To reduce the complexity of the initial feature review, I've also removed many of the bells and whistles from this initial version for separate consideration. For now, I'm saying initializer requirements are always "eager" (can't refer to self) and always inline-initialized. This imposes some inconvenience on some use cases, but is an additive feature. I've also left behavior composition, extending behaviors, overloading behaviors, and name binding as future extensions. Joe Pamer raised some design and technical challenges around how type inference should work with behaviors too, which I think deserve focused discussion, so I'm sidestepping those issues by starting out saying properties with behaviors always need an explicit type. Here's the updated proposal:
> 
> https://gist.github.com/jckarter/66ae8fb361c0d57b3227
> 
> And for reference, previous iterations:
> 
> https://gist.github.com/jckarter/50b838e7f036fe85eaa3
> https://gist.github.com/jckarter/f3d392cf183c6b2b2ac3
> 
> -Joe
> _______________________________________________
> 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