> On Mar 17, 2017, at 6:29 PM, Joe Groff <[email protected]> wrote:
> 
> 
>> On Mar 17, 2017, at 4:25 PM, Matthew Johnson <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>> 
>> Sent from my iPhone
>> 
>> On Mar 17, 2017, at 6:09 PM, Joe Groff <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>> 
>>>> On Mar 17, 2017, at 4:05 PM, Matthew Johnson <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>> On Mar 17, 2017, at 5:38 PM, Joe Groff via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>>> 
>>>>>> On Mar 17, 2017, at 12:34 PM, David Hart via swift-evolution 
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> Sent off-list by mistake:
>>>>>> 
>>>>>> Nice proposal. I have a few comments inline:
>>>>>> 
>>>>>>> On 17 Mar 2017, at 18:04, Michael LeHew via swift-evolution 
>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>> 
>>>>>>> Hi friendly swift-evolution folks,
>>>>>>> 
>>>>>>> The Foundation and Swift team  would like for you to consider the 
>>>>>>> following proposal:
>>>>>>> 
>>>>>>> Many thanks,
>>>>>>> -Michael
>>>>>>> 
>>>>>>> Smart KeyPaths: Better Key-Value Coding for Swift
>>>>>>> Proposal: SE-NNNN
>>>>>>> Authors: David Smith <https://github.com/Catfish-Man>, Michael LeHew 
>>>>>>> <https://github.com/mlehew>, Joe Groff <https://github.com/jckarter>
>>>>>>> Review Manager: TBD
>>>>>>> Status: Awaiting Review
>>>>>>> Associated PRs:
>>>>>>> #644 <https://github.com/apple/swift-evolution/pull/644>
>>>>>>> Introduction
>>>>>>> We propose a family of concrete Key Path types that represent uninvoked 
>>>>>>> references to properties that can be composed to form paths through 
>>>>>>> many values and directly get/set their underlying values.
>>>>>>> 
>>>>>>> Motivation
>>>>>>> We Can Do Better than String
>>>>>>> 
>>>>>>> On Darwin platforms Swift's existing #keyPath() syntax provides a 
>>>>>>> convenient way to safely refer to properties. Unfortunately, once 
>>>>>>> validated, the expression becomes a String which has a number of 
>>>>>>> important limitations:
>>>>>>> 
>>>>>>> Loss of type information (requiring awkward Any APIs)
>>>>>>> Unnecessarily slow to parse
>>>>>>> Only applicable to NSObjects
>>>>>>> Limited to Darwin platforms
>>>>>>> Use/Mention Distinctions
>>>>>>> 
>>>>>>> While methods can be referred to without invoking them (let x = foo.bar 
>>>>>>> instead of  let x = foo.bar()), this is not currently possible for 
>>>>>>> properties and subscripts.
>>>>>>> 
>>>>>>> Making indirect references to a properties' concrete types also lets us 
>>>>>>> expose metadata about the property, and in the future additional 
>>>>>>> behaviors.
>>>>>>> 
>>>>>> What metadata is attached? How is it accessed? What future features are 
>>>>>> you thinking about?
>>>>> 
>>>>> To begin with, you'd have limited ability to stringify a key path. 
>>>>> Eventually we'd like to support other reflectiony things, including:
>>>>> 
>>>>> - Asking for the primary key paths a type supports
>>>>> - Asking for a key by name or index
>>>>> - Breaking a key path down by components
>>>>> 
>>>>> I also see key path objects as a good way of eventually addressing some 
>>>>> of the design problems we ran up against with property behaviors 
>>>>> (https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
>>>>>  
>>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md>
>>>>>  from last year), including the problem of what exactly a property 
>>>>> behavior declaration *is* (a type? a protocol? a function-like thing? 
>>>>> something completely new?), and the problem of handling "out-of-band" 
>>>>> operations on a property beyond getting and setting, such as clearing a 
>>>>> cached lazy value, registering for notifications on an observable 
>>>>> property, and so on. I think it would be natural to express property 
>>>>> behaviors as a user-defined key path type; the key path type can provide 
>>>>> the get/set logic for the property as well as any other interesting 
>>>>> operations the property supports. This answers the questions of both what 
>>>>> behaviors look like (they're just types that conform to KeyPath) and how 
>>>>> they extend properties with new actions (they're just methods of the key 
>>>>> path value) fairly nicely.
>>>> 
>>>> Very interesting!  This sounds like it would enable a very nice design in 
>>>> a project I'm working on right now.  I'm looking forward to seeing this 
>>>> take shape in the future.
>>>> 
>>>> It sounds like it wouldn't solve one use case I was hoping property 
>>>> behaviors might solve though.  Sometimes we have a property that we would 
>>>> like to make a constant but cont because we can't set it until phase 2.  I 
>>>> would really like to have some notion of a "phase 2 initialized constant" 
>>>> which would provide a much stronger guarantee than IUO does.  There would 
>>>> be a very small window where a trap is possible between phase 1 and when 
>>>> it is set in phase 2.  It would probably make more sense to actually think 
>>>> of this as phase 1.5 where all of these properties must be initialized to 
>>>> a non-nil value, but self can be used in the initializing expressions.
>>> 
>>> I think that kind of use case can be handled even by the previous property 
>>> behaviors proposal, by having a behavior that presents a non-optional 
>>> property that only allows initialization by being set once, and traps if 
>>> gotten before being initialized.
>> 
>> Didn't it require trapping if set more than once?  And it didn't offer a way 
>> to require initialization during phase 2 did it?
> 
> Yes, but perfectly closing those holes requires a much more complex type 
> system than we have. Perfect is the enemy of good, and I think trapping on 
> misuse gets you the lion's share of the benefit, and would still be a massive 
> improvement over IUO.

Yes, I agree that it would be a massive improvement.  I just wish there was a 
way to solve this that didn’t require fancy type system stuff.  We already have 
relatively complex initialization rules that exist outside the type system that 
track initialization.  It would be nice if we could solve this using a small 
enhancement to those rules.  For example, we could have some kind of attribute 
or access control that is only available for IUO properties that restricts the 
setter to only be available in the initializer and guarantees that it is set to 
non-nil on exit of init.  Maybe it’s too much of a special case to do this, but 
it would be really cool to have this hole plugged.

> 
> -Joe

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to