Re: [swift-evolution] Smart KeyPaths

2017-03-31 Thread BJ Homer via swift-evolution

> Is it always in the form of $R?

No. Prefixing a variable with a '$' allows you to create a long-lasting 
variable in lldb. By default, every 'expr' command runs in its own scope, which 
means identifiers defined in one command are not visible from another. Example:

(LLDB) expr let x = 1 + 2
$R0 = 3
(LLDB) print x + 3
Error: Undefined identifier 'x'
(LLDB) expr let $y = 3 + 4
$R1 = 7
(LLDB) print $y + 5
$R2 = 12

Typed on my phone, so the LLDB output is not exact, but you see the point: you 
can prefix an identifier with '$' to make it persist beyond the scope of that 
command. LLDB automatically creates numbered identifiers when running commands, 
but you can also create your own. And you could also have expressions like 
'print $person.name', so looking for a '.' doesn't help. 

-BJ
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-31 Thread Karim Nassar via swift-evolution

> Date: Fri, 31 Mar 2017 04:33:43 -0700
> From: Brent Royal-Gordon <br...@architechies.com>
> To: Haravikk <swift-evolut...@haravikk.me>
> Cc: Haravikk via swift-evolution <swift-evolution@swift.org>
> Subject: Re: [swift-evolution] Smart KeyPaths
> Message-ID: <adb64b59-d79c-41cc-9465-dc4697cb2...@architechies.com>
> Content-Type: text/plain; charset="utf-8"
> 
>> On Mar 31, 2017, at 3:07 AM, Haravikk via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Is it actually in-use or just reserved? Not sure I've ever needed it in the 
>> debugger.
> 
> Pop into the REPL for a minute:
> 
>   $ swift
>   Welcome to Apple Swift version 3.1 (swiftlang-802.0.41 clang-802.0.36). 
> Type :help for assistance.
> 1> "hello"
>   $R0: String = "hello"
> 2> $R0
>   $R1: String = "hello"
> 
> You may not have ever noticed it was there, but it was.
> 
>> What about @? It has a certain appropriateness in how it reads for a path 
>> like: @Person.friend.lastName
> 
> We're already using @ for attributes; I don't think we want to overload its 
> meaning.
> 
>> Another alternative might be something like an unnamed compiler directive, 
>> for example: #(Person.friend.lastName)
>> If you consider the statement to mean "expand this".
> 
> The unnamed compiler directive seems like *really* valuable real estate, 
> arguably much more so than unresolved-member-on-KeyPath-type is. I think it'd 
> be foolish to assign it to anything before we have a macro system designed.


I agree that #() is too valuable to burn at this point. 

So… Crazy Thought: Is KeyPath enough of a term-of-art beyond ObjC that we want 
to carry it’s semantics directly into Swift even when it conflicts with 
established ObjC inter-op? In other words, if we didn’t already know ObjC & 
KVO/KVC, does “KeyPath” mean what we mean by it in Swift?

If the issue is the conflict with the current semantics of #keyPath(), what 
about something like:

```
   let fooProp: Property<Foo, String> = #property(bar.bast)
```

And in the inferred/ambiguous case:

```
let fooProp = #property(bar.bast, of: Foo)
```

It perhaps moves too far from the KeyPath nomenclature, but it reads rather 
nicely (IMHO).

—Karim




___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-31 Thread Haravikk via swift-evolution

> On 31 Mar 2017, at 12:33, Brent Royal-Gordon  wrote:
> 
>> On Mar 31, 2017, at 3:07 AM, Haravikk via swift-evolution 
>> > wrote:
>> 
>> Is it actually in-use or just reserved? Not sure I've ever needed it in the 
>> debugger.
> 
> Pop into the REPL for a minute:
> 
>   $ swift
>   Welcome to Apple Swift version 3.1 (swiftlang-802.0.41 clang-802.0.36). 
> Type :help for assistance.
> 1> "hello"
>   $R0: String = "hello"
> 2> $R0
>   $R1: String = "hello"
> 
> You may not have ever noticed it was there, but it was.

Is it always in the form of $R? If it can't include periods then it doesn't 
seem like it would present a collision (just as overlap with $0, $1 etc. in 
closures does not).

>> What about @? It has a certain appropriateness in how it reads for a path 
>> like: @Person.friend.lastName
> 
> We're already using @ for attributes; I don't think we want to overload its 
> meaning.

Ack, no idea how I forgot about attributes considering I use them all the time. 
Hmm.

>> Another alternative might be something like an unnamed compiler directive, 
>> for example: #(Person.friend.lastName)
>> If you consider the statement to mean "expand this".
> 
> The unnamed compiler directive seems like *really* valuable real estate, 
> arguably much more so than unresolved-member-on-KeyPath-type is. I think it'd 
> be foolish to assign it to anything before we have a macro system designed.

Perhaps, but how many other features might be making a bid for it? There's 
always the possibility of using a more "specialised" bracket for paths instead, 
like #{Person.friend.lastName}
Leaving regular parenthesis up for grabs for something else.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-31 Thread Brent Royal-Gordon via swift-evolution
> On Mar 31, 2017, at 3:07 AM, Haravikk via swift-evolution 
>  wrote:
> 
> Is it actually in-use or just reserved? Not sure I've ever needed it in the 
> debugger.

Pop into the REPL for a minute:

$ swift
Welcome to Apple Swift version 3.1 (swiftlang-802.0.41 clang-802.0.36). 
Type :help for assistance.
  1> "hello"
$R0: String = "hello"
  2> $R0
$R1: String = "hello"

You may not have ever noticed it was there, but it was.

> What about @? It has a certain appropriateness in how it reads for a path 
> like: @Person.friend.lastName

We're already using @ for attributes; I don't think we want to overload its 
meaning.

> Another alternative might be something like an unnamed compiler directive, 
> for example: #(Person.friend.lastName)
> If you consider the statement to mean "expand this".

The unnamed compiler directive seems like *really* valuable real estate, 
arguably much more so than unresolved-member-on-KeyPath-type is. I think it'd 
be foolish to assign it to anything before we have a macro system designed.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-31 Thread Haravikk via swift-evolution

> On 30 Mar 2017, at 17:18, Joe Groff  wrote:
> 
> 
>> On Mar 30, 2017, at 6:54 AM, Haravikk via swift-evolution 
>>  wrote:
>> 
>> 
>>> On 30 Mar 2017, at 14:12, Matthew Johnson via swift-evolution 
>>>  wrote:
 On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
  wrote:
 I'm not a fan of the new syntax for creating key paths. To me, it feels 
 like they've been demoted to second class citizens of the language simply 
 because of how more verbose it now is. The new syntax is also too 
 confusingly similar to string key paths: I had to look closely at the code 
 to see the difference. Is there no symbol we can use to make it ambiguous? 
 Ideas:
 
 Person::friend.lastName
 Person/friend.lastName
 Person#friend.lastName
 
 I'm a fan of the first one as it has similarities to names pacing in C++.
>>> 
>>> I'm a big fan of the last one.  I argued for it earlier as the best syntax 
>>> to use if we deviated from the initial proposal.  I like it for several 
>>> reasons:
>>> 
>>> - # suggests compiler magic is at work which is the case here.
>>> - #friend.lastName works nicely as a shorthand in contexts expecting a key 
>>> path with a fixed Root
>>> - # would work for unbound methods solving the no arguments case.  IMO all 
>>> unbound members should be accessed using the same syntax.
>>> - # enables the possibility of mixing property access and method calls in 
>>> the path as a future enhancement
>>> 
>>> The arguments supporting this approach are pretty strong to me.  I agree 
>>> with David that the #keyPath syntax makes it feel more like a second class 
>>> citizen, not just because of the verbosity but also because it is directly 
>>> borrowed from an Objective-C interop feature.  This is a very powerful 
>>> feature that deserves to be a first class syntactic citizen every bit as 
>>> much as unbound methods do.
>> 
>> Personally I'd prefer the use of a leading dollar sign for this, for example:
>> 
>>  $Person.friend.lastName
>> 
>> I find a symbol midway through the path a bit strange, plus the leading 
>> dollar sign already implies compiler magic in the same way as anonymous 
>> parameters in closures. In fact you can think of anonymous parameters as a 
>> kind of special key-path of sorts, and there should be no ambiguity.
>> 
>> I prefer this to the hash symbol for compiler directives, since those feel 
>> more like things that are done once during compilation, rather than 
>> something you actually use at run-time, so I like the distinction of another 
>> symbol for that.
> 
> $ is reserved for the debugger. We don't really have many free symbols to 
> burn, and it would be unwise to burn one on a new feature before having 
> evidence that it deserves it.

Is it actually in-use or just reserved? Not sure I've ever needed it in the 
debugger.
What about @? It has a certain appropriateness in how it reads for a path like: 
@Person.friend.lastName

Another alternative might be something like an unnamed compiler directive, for 
example: #(Person.friend.lastName)
If you consider the statement to mean "expand this".___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Joe Groff via swift-evolution

> On Mar 30, 2017, at 6:54 AM, Haravikk via swift-evolution 
>  wrote:
> 
> 
>> On 30 Mar 2017, at 14:12, Matthew Johnson via swift-evolution 
>>  wrote:
>>> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
>>>  wrote:
>>> I'm not a fan of the new syntax for creating key paths. To me, it feels 
>>> like they've been demoted to second class citizens of the language simply 
>>> because of how more verbose it now is. The new syntax is also too 
>>> confusingly similar to string key paths: I had to look closely at the code 
>>> to see the difference. Is there no symbol we can use to make it ambiguous? 
>>> Ideas:
>>> 
>>> Person::friend.lastName
>>> Person/friend.lastName
>>> Person#friend.lastName
>>> 
>>> I'm a fan of the first one as it has similarities to names pacing in C++.
>> 
>> I'm a big fan of the last one.  I argued for it earlier as the best syntax 
>> to use if we deviated from the initial proposal.  I like it for several 
>> reasons:
>> 
>> - # suggests compiler magic is at work which is the case here.
>> - #friend.lastName works nicely as a shorthand in contexts expecting a key 
>> path with a fixed Root
>> - # would work for unbound methods solving the no arguments case.  IMO all 
>> unbound members should be accessed using the same syntax.
>> - # enables the possibility of mixing property access and method calls in 
>> the path as a future enhancement
>> 
>> The arguments supporting this approach are pretty strong to me.  I agree 
>> with David that the #keyPath syntax makes it feel more like a second class 
>> citizen, not just because of the verbosity but also because it is directly 
>> borrowed from an Objective-C interop feature.  This is a very powerful 
>> feature that deserves to be a first class syntactic citizen every bit as 
>> much as unbound methods do.
> 
> Personally I'd prefer the use of a leading dollar sign for this, for example:
> 
>   $Person.friend.lastName
> 
> I find a symbol midway through the path a bit strange, plus the leading 
> dollar sign already implies compiler magic in the same way as anonymous 
> parameters in closures. In fact you can think of anonymous parameters as a 
> kind of special key-path of sorts, and there should be no ambiguity.
> 
> I prefer this to the hash symbol for compiler directives, since those feel 
> more like things that are done once during compilation, rather than something 
> you actually use at run-time, so I like the distinction of another symbol for 
> that.

$ is reserved for the debugger. We don't really have many free symbols to burn, 
and it would be unwise to burn one on a new feature before having evidence that 
it deserves it.

-Joe 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Ricardo Parada via swift-evolution

> On Mar 30, 2017, at 9:54 AM, Haravikk via swift-evolution 
>  wrote:
> 
> Personally I'd prefer the use of a leading dollar sign for this, for example:
> 
>   $Person.friend.lastName

That looks clean.  I don't think it could get confused with referencing named 
tuples because the type begins with uppercase.


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Vladimir.S via swift-evolution


On 30.03.2017 16:12, Matthew Johnson via swift-evolution wrote:



Sent from my iPad

On Mar 30, 2017, at 12:35 AM, David Hart via swift-evolution
> wrote:






Sent from my iPhone
On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution
> wrote:


Thanks for the feedback everyone!  We have pushed a changed a bit ago to
the proposal reflecting these desires.

https://github.com/apple/swift-evolution/pull/644/files

-Michael


I'm not a fan of the new syntax for creating key paths. To me, it feels
like they've been demoted to second class citizens of the language simply
because of how more verbose it now is. The new syntax is also too
confusingly similar to string key paths: I had to look closely at the
code to see the difference. Is there no symbol we can use to make it
ambiguous? Ideas:

Person::friend.lastName
Person/friend.lastName
Person#friend.lastName

I'm a fan of the first one as it has similarities to names pacing in C++.


I'm a big fan of the last one.  I argued for it earlier as the best syntax
to use if we deviated from the initial proposal.  I like it for several
reasons:

- # suggests compiler magic is at work which is the case here.
- #friend.lastName works nicely as a shorthand in contexts expecting a key
path with a fixed Root
- # would work for unbound methods solving the no arguments case.  IMO all
unbound members should be accessed using the same syntax.


Strong support. IMO proposal should be currently updated to unify the 
syntax of unbound methods access and key path access, IMO *this* should be 
one of the main targets of the proposal. I.e.


var method1 = MyType#foo() // unbound method
var method2 = MyType#foo(param:) // unbound method
var keypath = MyType#person.name // keypath

Personally I think the '@' could be used also as("type AT path"):

var method = MyType@foo() // unbound method
var keypath = myt...@person.name // keypath

But I agree that '#' is a strong marker that we are dealing with some 
compiler magic here.



- # enables the possibility of mixing property access and method calls in
the path as a future enhancement

The arguments supporting this approach are pretty strong to me.  I agree
with David that the #keyPath syntax makes it feel more like a second class
citizen, not just because of the verbosity but also because it is directly
borrowed from an Objective-C interop feature.  This is a very powerful
feature that deserves to be a first class syntactic citizen every bit as
much as unbound methods do.



David.


On Mar 29, 2017, at 2:49 PM, Douglas Gregor > wrote:



On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution
> wrote:

Hi friendly swift-evolution folks,

The Foundation and Swift team  would like for you to consider the
following proposal:



The Swift core team discussed this proposal draft and had a little bit
of pre-review feedback.


Access and Mutation Through KeyPaths

To get or set values for a given root and key path we effectively add
the following subscripts to all Swift types.

Swift
|extension Any { subscript(path: AnyKeyPath) -> Any? { get }
subscript(path: PartialKeyPath) -> Any { get }
subscript(path: KeyPath) -> Value {
get } subscript(path: WritableKeyPath)
-> Value { set, get } }|


Swift doesn’t currently have the ability to extend Any, so this is
(currently) pseudocode for compiler magic that one day we might be able
to place. Additionally, the “Root: Self” constraint isn’t something we
support in the generics system. A small note indicating that this is
pseudo-code meant to get the point across (rather than real code to
drop into the standard library/Foundation) would be appreciated.

More importantly, this adds an unlabeled subscript to every type, which
raises concerns about introducing ambiguities—even if not hard
ambiguities that prevent code from compiling (e.g., from a
Dictionary)---they can still show up in code completion,
diagnostics, etc.

The core team would prefer that this subscript distinguish itself more,
e.g., by labeling the first parameter “keyPath” (or some better name,
if there is one). Syntactically, that would look like:

person[keyPath: theKeyPathIHave]


Referencing Key Paths

Forming a |KeyPath| borrows from the same syntax used to reference
methods and initializers,|Type.instanceMethod| only now working for
properties and collections. Optionals are handled via
optional-chaining. Multiply dotted expressions are allowed as well,
and work just as if they were composed via the |appending| methods
on |KeyPath|.


The core team was concerned about the use of the Type.instanceProperty
syntax for a few reasons:

* It doesn’t work for forming keypaths to class/static properties (or
is ambiguous with the existing meaning(, so we 

Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Haravikk via swift-evolution

> On 30 Mar 2017, at 14:12, Matthew Johnson via swift-evolution 
>  wrote:
>> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
>> > wrote:
>> I'm not a fan of the new syntax for creating key paths. To me, it feels like 
>> they've been demoted to second class citizens of the language simply because 
>> of how more verbose it now is. The new syntax is also too confusingly 
>> similar to string key paths: I had to look closely at the code to see the 
>> difference. Is there no symbol we can use to make it ambiguous? Ideas:
>> 
>> Person::friend.lastName
>> Person/friend.lastName
>> Person#friend.lastName
>> 
>> I'm a fan of the first one as it has similarities to names pacing in C++.
> 
> I'm a big fan of the last one.  I argued for it earlier as the best syntax to 
> use if we deviated from the initial proposal.  I like it for several reasons:
> 
> - # suggests compiler magic is at work which is the case here.
> - #friend.lastName works nicely as a shorthand in contexts expecting a key 
> path with a fixed Root
> - # would work for unbound methods solving the no arguments case.  IMO all 
> unbound members should be accessed using the same syntax.
> - # enables the possibility of mixing property access and method calls in the 
> path as a future enhancement
> 
> The arguments supporting this approach are pretty strong to me.  I agree with 
> David that the #keyPath syntax makes it feel more like a second class 
> citizen, not just because of the verbosity but also because it is directly 
> borrowed from an Objective-C interop feature.  This is a very powerful 
> feature that deserves to be a first class syntactic citizen every bit as much 
> as unbound methods do.

Personally I'd prefer the use of a leading dollar sign for this, for example:

$Person.friend.lastName

I find a symbol midway through the path a bit strange, plus the leading dollar 
sign already implies compiler magic in the same way as anonymous parameters in 
closures. In fact you can think of anonymous parameters as a kind of special 
key-path of sorts, and there should be no ambiguity.

I prefer this to the hash symbol for compiler directives, since those feel more 
like things that are done once during compilation, rather than something you 
actually use at run-time, so I like the distinction of another symbol for that.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Mar 30, 2017, at 12:35 AM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
> 
> 
> Sent from my iPhone
> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
>  wrote:
> 
>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
>> proposal reflecting these desires.
>> 
>> https://github.com/apple/swift-evolution/pull/644/files
>> 
>> -Michael
> 
> I'm not a fan of the new syntax for creating key paths. To me, it feels like 
> they've been demoted to second class citizens of the language simply because 
> of how more verbose it now is. The new syntax is also too confusingly similar 
> to string key paths: I had to look closely at the code to see the difference. 
> Is there no symbol we can use to make it ambiguous? Ideas:
> 
> Person::friend.lastName
> Person/friend.lastName
> Person#friend.lastName
> 
> I'm a fan of the first one as it has similarities to names pacing in C++.

I'm a big fan of the last one.  I argued for it earlier as the best syntax to 
use if we deviated from the initial proposal.  I like it for several reasons:

- # suggests compiler magic is at work which is the case here.
- #friend.lastName works nicely as a shorthand in contexts expecting a key path 
with a fixed Root
- # would work for unbound methods solving the no arguments case.  IMO all 
unbound members should be accessed using the same syntax.
- # enables the possibility of mixing property access and method calls in the 
path as a future enhancement

The arguments supporting this approach are pretty strong to me.  I agree with 
David that the #keyPath syntax makes it feel more like a second class citizen, 
not just because of the verbosity but also because it is directly borrowed from 
an Objective-C interop feature.  This is a very powerful feature that deserves 
to be a first class syntactic citizen every bit as much as unbound methods do.

> 
> David.
> 
 On Mar 29, 2017, at 2:49 PM, Douglas Gregor  wrote:
 
 
 On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
  wrote:
 
 Hi friendly swift-evolution folks,
 
 The Foundation and Swift team  would like for you to consider the 
 following proposal:
>>> 
>>> 
>>> The Swift core team discussed this proposal draft and had a little bit of 
>>> pre-review feedback.
>>> 
 Access and Mutation Through KeyPaths
 To get or set values for a given root and key path we effectively add the 
 following subscripts to all Swift types. 
 
 Swift
 extension Any {
 subscript(path: AnyKeyPath) -> Any? { get }
 subscript(path: PartialKeyPath) -> Any { get }
 subscript(path: KeyPath) -> Value { 
 get }
 subscript(path: WritableKeyPath) -> 
 Value { set, get }
 }
>>> 
>>> Swift doesn’t currently have the ability to extend Any, so this is 
>>> (currently) pseudocode for compiler magic that one day we might be able to 
>>> place. Additionally, the “Root: Self” constraint isn’t something we support 
>>> in the generics system. A small note indicating that this is pseudo-code 
>>> meant to get the point across (rather than real code to drop into the 
>>> standard library/Foundation) would be appreciated.
>>> 
>>> More importantly, this adds an unlabeled subscript to every type, which 
>>> raises concerns about introducing ambiguities—even if not hard ambiguities 
>>> that prevent code from compiling (e.g., from a Dictionary>> …>)---they can still show up in code completion, diagnostics, etc.
>>> 
>>> The core team would prefer that this subscript distinguish itself more, 
>>> e.g., by labeling the first parameter “keyPath” (or some better name, if 
>>> there is one). Syntactically, that would look like:
>>> 
>>> person[keyPath: theKeyPathIHave]
>>> 
 Referencing Key Paths
 
 Forming a KeyPath borrows from the same syntax used to reference methods 
 and initializers,Type.instanceMethod only now working for properties and 
 collections. Optionals are handled via optional-chaining. Multiply dotted 
 expressions are allowed as well, and work just as if they were composed 
 via the appending methods on KeyPath.
 
>>> The core team was concerned about the use of the Type.instanceProperty 
>>> syntax for a few reasons:
>>> 
>>> * It doesn’t work for forming keypaths to class/static properties (or 
>>> is ambiguous with the existing meaning(, so we would need another syntax to 
>>> deal with that case
>>> * It’s quite subtle, even more so that the existing Type.instanceMethod 
>>> syntax for currying instance methods
>>> 
 There is no change or interaction with the #keyPath() syntax introduced in 
 Swift 3. 
 
>>> The core team felt that extending the #keyPath syntax was a better 
>>> syntactic direction to produce key-paths.
>>> 

Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread Ricardo Parada via swift-evolution


> On Mar 29, 2017, at 10:21 PM, James Berry via swift-evolution 
>  wrote:
> 
> Or migrate swift 3 #keyPath to #objcKeyPath to preserve that legacy intent 
> while retaining #keyPath for our bright and unsullied future? ;)

I like this suggestion. 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-30 Thread David Hart via swift-evolution


> On 30 Mar 2017, at 09:41, Douglas Gregor  wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On Mar 29, 2017, at 10:35 PM, David Hart  wrote:
>> 
>> 
>> 
>> 
>> 
>> Sent from my iPhone
>> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
>>  wrote:
>> 
>>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to 
>>> the proposal reflecting these desires.
>>> 
>>> https://github.com/apple/swift-evolution/pull/644/files
>>> 
>>> -Michael
>> 
>> I'm not a fan of the new syntax for creating key paths. To me, it feels like 
>> they've been demoted to second class citizens of the language simply because 
>> of how more verbose it now is. The new syntax is also too confusingly 
>> similar to string key paths: I had to look closely at the code to see the 
>> difference. Is there no symbol we can use to make it ambiguous? Ideas:
>> 
>> Person::friend.lastName
>> Person/friend.lastName
>> Person#friend.lastName
>> 
>> I'm a fan of the first one as it has similarities to names pacing in C++.
> 
> We might want to reserve :: for actual scope resolution. At least, we need 
> something to be able to disambiguate when the same name occurs as a member in 
> (e.g.) multiple protocols, and :: is familiar-ish. 

Perhaps, but I still believe we would gain a lot by keeping a similar syntax, 
whatever the separation token.

> I'm surprised nobody brought up making
> 
>   #keyPath(Person.friend.lastName)
> 
> Work as either a String or KeyPath. Probably a bad idea. 

If it works, would be better than the current version of the proposal IMHO, 
buts it's still fairly verbose for a feature that can become a first class 
citizen of the language. #keyPath was fine because it was an obscure objc 
bridging feature.

>  - Doug
> 
>> 
>> David.
>> 
> On Mar 29, 2017, at 2:49 PM, Douglas Gregor  wrote:
> 
> 
> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>  wrote:
> 
> Hi friendly swift-evolution folks,
> 
> The Foundation and Swift team  would like for you to consider the 
> following proposal:
 
 
 The Swift core team discussed this proposal draft and had a little bit of 
 pre-review feedback.
 
> Access and Mutation Through KeyPaths
> To get or set values for a given root and key path we effectively add the 
> following subscripts to all Swift types. 
> 
> Swift
> extension Any {
> subscript(path: AnyKeyPath) -> Any? { get }
> subscript(path: PartialKeyPath) -> Any { get }
> subscript(path: KeyPath) -> Value { 
> get }
> subscript(path: WritableKeyPath) -> 
> Value { set, get }
> }
 
 Swift doesn’t currently have the ability to extend Any, so this is 
 (currently) pseudocode for compiler magic that one day we might be able to 
 place. Additionally, the “Root: Self” constraint isn’t something we 
 support in the generics system. A small note indicating that this is 
 pseudo-code meant to get the point across (rather than real code to drop 
 into the standard library/Foundation) would be appreciated.
 
 More importantly, this adds an unlabeled subscript to every type, which 
 raises concerns about introducing ambiguities—even if not hard ambiguities 
 that prevent code from compiling (e.g., from a Dictionary)---they can still show up in code completion, diagnostics, etc.
 
 The core team would prefer that this subscript distinguish itself more, 
 e.g., by labeling the first parameter “keyPath” (or some better name, if 
 there is one). Syntactically, that would look like:
 
person[keyPath: theKeyPathIHave]
 
> Referencing Key Paths
> 
> Forming a KeyPath borrows from the same syntax used to reference methods 
> and initializers,Type.instanceMethod only now working for properties and 
> collections. Optionals are handled via optional-chaining. Multiply dotted 
> expressions are allowed as well, and work just as if they were composed 
> via the appending methods on KeyPath.
> 
 The core team was concerned about the use of the Type.instanceProperty 
 syntax for a few reasons:
 
* It doesn’t work for forming keypaths to class/static properties (or 
 is ambiguous with the existing meaning(, so we would need another syntax 
 to deal with that case
* It’s quite subtle, even more so that the existing Type.instanceMethod 
 syntax for currying instance methods
 
> There is no change or interaction with the #keyPath() syntax introduced 
> in Swift 3. 
> 
 The core team felt that extending the #keyPath syntax was a better 
 syntactic direction to produce key-paths.
 
- Doug
 
>>> 
>>> ___
>>> 

Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread David Hart via swift-evolution




Sent from my iPhone
> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution 
>  wrote:
> 
> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
> proposal reflecting these desires.
> 
> https://github.com/apple/swift-evolution/pull/644/files
> 
> -Michael

I'm not a fan of the new syntax for creating key paths. To me, it feels like 
they've been demoted to second class citizens of the language simply because of 
how more verbose it now is. The new syntax is also too confusingly similar to 
string key paths: I had to look closely at the code to see the difference. Is 
there no symbol we can use to make it ambiguous? Ideas:

Person::friend.lastName
Person/friend.lastName
Person#friend.lastName

I'm a fan of the first one as it has similarities to names pacing in C++.

David.

>>> On Mar 29, 2017, at 2:49 PM, Douglas Gregor  wrote:
>>> 
>>> 
>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>>>  wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>> 
>> 
>> The Swift core team discussed this proposal draft and had a little bit of 
>> pre-review feedback.
>> 
>>> Access and Mutation Through KeyPaths
>>> To get or set values for a given root and key path we effectively add the 
>>> following subscripts to all Swift types. 
>>> 
>>> Swift
>>> extension Any {
>>> subscript(path: AnyKeyPath) -> Any? { get }
>>> subscript(path: PartialKeyPath) -> Any { get }
>>> subscript(path: KeyPath) -> Value { get 
>>> }
>>> subscript(path: WritableKeyPath) -> 
>>> Value { set, get }
>>> }
>> 
>> Swift doesn’t currently have the ability to extend Any, so this is 
>> (currently) pseudocode for compiler magic that one day we might be able to 
>> place. Additionally, the “Root: Self” constraint isn’t something we support 
>> in the generics system. A small note indicating that this is pseudo-code 
>> meant to get the point across (rather than real code to drop into the 
>> standard library/Foundation) would be appreciated.
>> 
>> More importantly, this adds an unlabeled subscript to every type, which 
>> raises concerns about introducing ambiguities—even if not hard ambiguities 
>> that prevent code from compiling (e.g., from a Dictionary> …>)---they can still show up in code completion, diagnostics, etc.
>> 
>> The core team would prefer that this subscript distinguish itself more, 
>> e.g., by labeling the first parameter “keyPath” (or some better name, if 
>> there is one). Syntactically, that would look like:
>> 
>>  person[keyPath: theKeyPathIHave]
>> 
>>> Referencing Key Paths
>>> 
>>> Forming a KeyPath borrows from the same syntax used to reference methods 
>>> and initializers,Type.instanceMethod only now working for properties and 
>>> collections. Optionals are handled via optional-chaining. Multiply dotted 
>>> expressions are allowed as well, and work just as if they were composed via 
>>> the appending methods on KeyPath.
>>> 
>> The core team was concerned about the use of the Type.instanceProperty 
>> syntax for a few reasons:
>> 
>>  * It doesn’t work for forming keypaths to class/static properties (or 
>> is ambiguous with the existing meaning(, so we would need another syntax to 
>> deal with that case
>>  * It’s quite subtle, even more so that the existing Type.instanceMethod 
>> syntax for currying instance methods
>> 
>>> There is no change or interaction with the #keyPath() syntax introduced in 
>>> Swift 3. 
>>> 
>> The core team felt that extending the #keyPath syntax was a better syntactic 
>> direction to produce key-paths.
>> 
>>  - Doug
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Douglas Gregor via swift-evolution


Sent from my iPhone

> On Mar 29, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> 
>>> I would love it if we found a way to retain something as concise as that 
>>> shorthand.  I'm working on a library where users will specify a collection 
>>> of key paths pairs.  This shorthand would be a very nice piece of sugar 
>>> making the code expressing these collections (usually literals) quite a bit 
>>> more readable.
>> 
>> +1 for this.  I think it will be somewhat common to pass around arrays of 
>> these things, and a shorthand syntax of some sort would make that nicer.  
>> That said, I don’t want to slow down the proposal, since I will be using 
>> this feature the very second it becomes available.
> 
> Agreed.
> 
> One more thought on this: I don't think anyone really likes the 
> #keyPath(Type, .key1.key2)` syntax; it's just the best we've come up with. If 
> the syntax were instead this:
> 
>   #keyPath(Type).key1.key2
> 
> I think that would look cleaner and avoid drawing distinctions based on 
> subtle punctuation differences. I don't think it would clash with old-style 
> key paths since you can't have a key path to a type name anyway. And support 
> for the leading-dot syntax would fall out of it quite naturally.

To me, this reads as if you're accessing ".key1.key2" on the KeyPath instance, 
not forming a keypath. I think the whole "path" should say in the parens. 

  - Doug

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread James Berry via swift-evolution

> On Mar 29, 2017, at 7:08 PM, Joe Groff  wrote:
> 
> 
>> On Mar 29, 2017, at 7:00 PM, James Berry  wrote:
>> 
>>> 
>>> On Mar 29, 2017, at 5:37 PM, Joe Groff  wrote:
>>> 
>>> 
 On Mar 29, 2017, at 5:26 PM, Michael J LeHew Jr via swift-evolution 
  wrote:
 
 
> On Mar 29, 2017, at 5:12 PM, James Berry  wrote:
> 
>> Referencing Key Paths
>> 
>> Forming a KeyPath borrows from the same syntax added in Swift 3 to 
>> confirm the existence of a given key path, only now producing concrete 
>> values instead of Strings. Optionals are handled via optional-chaining. 
>> Multiply dotted expressions are allowed as well, and work just as if 
>> they were composed via the appending methods on KeyPath.
>> 
>> There is no change or interaction with the #keyPath() syntax introduced 
>> in Swift 3. #keyPath(Person.bestFriend.name) will still produce a 
>> String, whereas #keyPath(Person, .bestFriend.name) will produce a 
>> KeyPath.
> 
> This distinction seems arbitrary and confusing. The user is supposed tor 
> remember that the #keyPath(Person.bestFriend.name) form produces a string 
> while the #keyPath(Person, .bestFriend.name) form produces a key path 
> object? I don’t think we’re advancing here. What would be the effect if 
> just the former was valid, and (always/now) produced a keypath object 
> that was convertible to string? How bad would the breakage be?
 
 The syntax subtleties here are unfortunate. 
 
 An idea that we discussed was to be able to tell when a #keyPath wants to 
 be considered as a string and either implicitly or having some affordance 
 for doing so. Back then this was harder because we had #keyPaths that 
 could not be represented as a string (an earlier draft had keyPaths that 
 could compose with closures; which while powerful, weren't really key 
 paths any more. That idea was removed from the proposal we shared as they 
 are intrinsically opposed to being able to serializing/deserialize key 
 paths).  
 
 Given that we don't support those kinds of key paths, nor are we really 
 considering adding them back thanks to our desire to support serializing 
 key paths to file in the future, this is a very reasonable idea I think. 
>>> 
>>> One small problem with the Swift 3 key path syntax when generalized to 
>>> allow arbitrary Swift types at the root, and to also allow inference of the 
>>> root, is that [...] can be either a subscript or an Array type reference, 
>>> so it wouldn't be clear whether #keyPath([a].foo) is the path `.foo` rooted 
>>> on the type `[a]` or the path `[a].foo` rooted in the contextual root type. 
>>> We could say that you have to use a different syntax for a contextual 
>>> keypath that begins with a subscript, like `#keyPath(.self[a])` or 
>>> `#keyPath(.[a])`, perhaps.
>> 
>> To me it seems an acceptable compromise to require a leading dot for the 
>> contextual case:
>> 
>>  #keyPath(Person.bestFriend.name)
>>  #keyPath(.bestFriend.name)
>>  #keyPath(.[a])
> 
> Another problem with overloading the same syntax is that ObjC key path 
> checking has a bunch of special case logic to mimic Cocoa's KVC behavior, so 
> that key paths involving string NSDictionary keys, NSArray's implicit mapping 
> behavior, or untyped keys accessed through `id` work as one would expect in 
> ObjC. We would only want to do that checking for ObjC key paths, so we should 
> probably keep them syntactically distinct.

So there are really two cases:

- objc keyPaths, which have special requirements and actually produce a 
string.
- nextGen keyPaths, which produce a keyPath object.

Per Michael, can we detect use of #keyPath as an objcKeyPath, and apply the 
correct special case magic only in that case, perhaps by requiring the objc api 
to flag it as such? Or migrate swift 3 #keyPath to #objcKeyPath to preserve 
that legacy intent while retaining #keyPath for our bright and unsullied 
future? ;)

James

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 29, 2017, at 7:05 PM, Joe Groff  wrote:
> 
> KeyPath objects themselves have properties, so key1 could be a member of 
> KeyPath. This doesn't seem workable. 


Yeah, someone pointed that out to me privately. One solution would be to make 
it so that an uninterrupted chain of property and subscript references is 
treated as constructing a key path, but parenthesizing ends the key path 
construction and accesses its properties instead:

#keyPath(Person).friends[0].name// Key path to the 
`name` property of a `Person`
(#keyPath(Person).friends[0]).name  // Value of the `name` property 
of a `WritableKeyPath`

Optional chaining behaves the same way, and in practice it seems to work fine.

In practice, I'm not sure this would come up very often, because I don't think 
you're likely to construct a key path and immediately start calling properties 
on it. But it is a concern.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2017, at 7:00 PM, James Berry  wrote:
> 
>> 
>> On Mar 29, 2017, at 5:37 PM, Joe Groff  wrote:
>> 
>> 
>>> On Mar 29, 2017, at 5:26 PM, Michael J LeHew Jr via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Mar 29, 2017, at 5:12 PM, James Berry  wrote:
 
> Referencing Key Paths
> 
> Forming a KeyPath borrows from the same syntax added in Swift 3 to 
> confirm the existence of a given key path, only now producing concrete 
> values instead of Strings. Optionals are handled via optional-chaining. 
> Multiply dotted expressions are allowed as well, and work just as if they 
> were composed via the appending methods on KeyPath.
> 
> There is no change or interaction with the #keyPath() syntax introduced 
> in Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath String>.
 
 This distinction seems arbitrary and confusing. The user is supposed tor 
 remember that the #keyPath(Person.bestFriend.name) form produces a string 
 while the #keyPath(Person, .bestFriend.name) form produces a key path 
 object? I don’t think we’re advancing here. What would be the effect if 
 just the former was valid, and (always/now) produced a keypath object that 
 was convertible to string? How bad would the breakage be?
>>> 
>>> The syntax subtleties here are unfortunate. 
>>> 
>>> An idea that we discussed was to be able to tell when a #keyPath wants to 
>>> be considered as a string and either implicitly or having some affordance 
>>> for doing so. Back then this was harder because we had #keyPaths that could 
>>> not be represented as a string (an earlier draft had keyPaths that could 
>>> compose with closures; which while powerful, weren't really key paths any 
>>> more. That idea was removed from the proposal we shared as they are 
>>> intrinsically opposed to being able to serializing/deserialize key paths).  
>>> 
>>> Given that we don't support those kinds of key paths, nor are we really 
>>> considering adding them back thanks to our desire to support serializing 
>>> key paths to file in the future, this is a very reasonable idea I think. 
>> 
>> One small problem with the Swift 3 key path syntax when generalized to allow 
>> arbitrary Swift types at the root, and to also allow inference of the root, 
>> is that [...] can be either a subscript or an Array type reference, so it 
>> wouldn't be clear whether #keyPath([a].foo) is the path `.foo` rooted on the 
>> type `[a]` or the path `[a].foo` rooted in the contextual root type. We 
>> could say that you have to use a different syntax for a contextual keypath 
>> that begins with a subscript, like `#keyPath(.self[a])` or `#keyPath(.[a])`, 
>> perhaps.
> 
> To me it seems an acceptable compromise to require a leading dot for the 
> contextual case:
> 
>   #keyPath(Person.bestFriend.name)
>   #keyPath(.bestFriend.name)
>   #keyPath(.[a])

Another problem with overloading the same syntax is that ObjC key path checking 
has a bunch of special case logic to mimic Cocoa's KVC behavior, so that key 
paths involving string NSDictionary keys, NSArray's implicit mapping behavior, 
or untyped keys accessed through `id` work as one would expect in ObjC. We 
would only want to do that checking for ObjC key paths, so we should probably 
keep them syntactically distinct.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>>  wrote:
>> 
>>> I would love it if we found a way to retain something as concise as that 
>>> shorthand.  I'm working on a library where users will specify a collection 
>>> of key paths pairs.  This shorthand would be a very nice piece of sugar 
>>> making the code expressing these collections (usually literals) quite a bit 
>>> more readable.
>> 
>> +1 for this.  I think it will be somewhat common to pass around arrays of 
>> these things, and a shorthand syntax of some sort would make that nicer.  
>> That said, I don’t want to slow down the proposal, since I will be using 
>> this feature the very second it becomes available.
> 
> Agreed.
> 
> One more thought on this: I don't think anyone really likes the 
> #keyPath(Type, .key1.key2)` syntax; it's just the best we've come up with. If 
> the syntax were instead this:
> 
>   #keyPath(Type).key1.key2
> 
> I think that would look cleaner and avoid drawing distinctions based on 
> subtle punctuation differences. I don't think it would clash with old-style 
> key paths since you can't have a key path to a type name anyway. And support 
> for the leading-dot syntax would fall out of it quite naturally.

KeyPath objects themselves have properties, so key1 could be a member of 
KeyPath. This doesn't seem workable. 

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2017, at 6:45 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
>> 
>> On Mar 29, 2017, at 6:32 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> 
 I would love it if we found a way to retain something as concise as that 
 shorthand.  I'm working on a library where users will specify a collection 
 of key paths pairs.  This shorthand would be a very nice piece of sugar 
 making the code expressing these collections (usually literals) quite a 
 bit more readable.
>>> 
>>> +1 for this.  I think it will be somewhat common to pass around arrays of 
>>> these things, and a shorthand syntax of some sort would make that nicer.  
>>> That said, I don’t want to slow down the proposal, since I will be using 
>>> this feature the very second it becomes available.
>> 
>> Agreed.
>> 
>> One more thought on this: I don't think anyone really likes the 
>> #keyPath(Type, .key1.key2)` syntax; it's just the best we've come up with. 
>> If the syntax were instead this:
>> 
>>  #keyPath(Type).key1.key2
>> 
>> I think that would look cleaner and avoid drawing distinctions based on 
>> subtle punctuation differences. I don't think it would clash with old-style 
>> key paths since you can't have a key path to a type name anyway. And support 
>> for the leading-dot syntax would fall out of it quite naturally.
> 
> I could get behind that (although it would stop us from extending KeyPaths).  
> One question in both cases: How do we represent keyPaths for static 
> properties?

Static properties are members of T.Type, so you would specify T.Type as the 
root.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread James Berry via swift-evolution

> On Mar 29, 2017, at 5:37 PM, Joe Groff  wrote:
> 
> 
>> On Mar 29, 2017, at 5:26 PM, Michael J LeHew Jr via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Mar 29, 2017, at 5:12 PM, James Berry  wrote:
>>> 
 Referencing Key Paths
 
 Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm 
 the existence of a given key path, only now producing concrete values 
 instead of Strings. Optionals are handled via optional-chaining. Multiply 
 dotted expressions are allowed as well, and work just as if they were 
 composed via the appending methods on KeyPath.
 
 There is no change or interaction with the #keyPath() syntax introduced in 
 Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
 whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath.
>>> 
>>> This distinction seems arbitrary and confusing. The user is supposed tor 
>>> remember that the #keyPath(Person.bestFriend.name) form produces a string 
>>> while the #keyPath(Person, .bestFriend.name) form produces a key path 
>>> object? I don’t think we’re advancing here. What would be the effect if 
>>> just the former was valid, and (always/now) produced a keypath object that 
>>> was convertible to string? How bad would the breakage be?
>> 
>> The syntax subtleties here are unfortunate. 
>> 
>> An idea that we discussed was to be able to tell when a #keyPath wants to be 
>> considered as a string and either implicitly or having some affordance for 
>> doing so.   Back then this was harder because we had #keyPaths that could 
>> not be represented as a string (an earlier draft had keyPaths that could 
>> compose with closures; which while powerful, weren't really key paths any 
>> more. That idea was removed from the proposal we shared as they are 
>> intrinsically opposed to being able to serializing/deserialize key paths).  
>> 
>> Given that we don't support those kinds of key paths, nor are we really 
>> considering adding them back thanks to our desire to support serializing key 
>> paths to file in the future, this is a very reasonable idea I think. 
> 
> One small problem with the Swift 3 key path syntax when generalized to allow 
> arbitrary Swift types at the root, and to also allow inference of the root, 
> is that [...] can be either a subscript or an Array type reference, so it 
> wouldn't be clear whether #keyPath([a].foo) is the path `.foo` rooted on the 
> type `[a]` or the path `[a].foo` rooted in the contextual root type. We could 
> say that you have to use a different syntax for a contextual keypath that 
> begins with a subscript, like `#keyPath(.self[a])` or `#keyPath(.[a])`, 
> perhaps.

To me it seems an acceptable compromise to require a leading dot for the 
contextual case:

#keyPath(Person.bestFriend.name)
#keyPath(.bestFriend.name)
#keyPath(.[a])

James
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Matthew Johnson via swift-evolution

> On Mar 29, 2017, at 8:45 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPhone
> 
> On Mar 29, 2017, at 4:52 PM, Brent Royal-Gordon  > wrote:
> 
>>> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>>> > wrote:
>>> 
>>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to 
>>> the proposal reflecting these desires.
>>> 
>>> https://github.com/apple/swift-evolution/pull/644/files 
>>> 
>> Quoting from the proposal:
>> 
>>> luke[keyPath: #keyPath(.friends[0].name)]
>> 
>> Really? I can understand marking one or the other, but both, even when 
>> there's no ambiguity?
>> 
>> Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
>> create a context where we know we have an `AnyKeyPath`, 
>> `PartialKeyPath`, `KeyPath`, or `WritableKeyPath> U>`. So if the core team's concern is about namespace clashes between 
>> `Person`'s static members and key paths, why not hang the key paths off the 
>> various `KeyPath` types? That is, this:
>> 
>>  struct Person {
>>  var friends: [Person]
>>  var name: String
>>  }
>> 
>> Implies this:
>> 
>>  extension PartialKeyPath where Root == Person {
>>  static let friends: WritableKeyPath
>>  static let name: WritableKeyPath
>>  }
>> 
>> And this:
>> 
>>  #keyPath(Person, .friends[0].name)
>> 
>> Desugars to this:
>> 
>>  PartialKeyPath.friends[0].name
>> 
>> So in a context where you already know you're passing a key path, you can 
>> simply write this:
>> 
>>  luke[keyPath: .friends[0].name]
>> 
>> Which applies normal "unresolved member" logic to look it up in 
>> `PartialKeyPath`.
> 
> Yes, this can be done via "unresolved member lookup". It's a little 
> different---unresolved member lookup usually can't handle chaining---but the 
> type checker could support it. 
> 
>> 
>> The result would be that you would have to explicitly, syntactically mark 
>> key paths except when the context already implied you were looking for one. 
>> In an unconstrained generic context, you would not get a key path without 
>> using `#keyPath` or explicitly naming a key path type. You would only need 
>> to worry about clashes if a call was overloaded to accept *both* `T` and 
>> `PartialKeyPath`; if we found that possibility troubling, we could 
>> penalize unresolved member lookups that resolve to key paths, so type 
>> inference would favor static members over key paths even in those cases.
>> 
>> Would that work for people? 
> 
> It's technically feasible. It makes ".foo" more contextually sensitive, which 
> is probably fine. 

It would work nicely for the use cases I have.

> 
>   - Doug
> 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread John McCall via swift-evolution
> On Mar 29, 2017, at 9:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
>> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>>> I would love it if we found a way to retain something as concise as that 
>>> shorthand.  I'm working on a library where users will specify a collection 
>>> of key paths pairs.  This shorthand would be a very nice piece of sugar 
>>> making the code expressing these collections (usually literals) quite a bit 
>>> more readable.
>> 
>> +1 for this.  I think it will be somewhat common to pass around arrays of 
>> these things, and a shorthand syntax of some sort would make that nicer.  
>> That said, I don’t want to slow down the proposal, since I will be using 
>> this feature the very second it becomes available.
> 
> Agreed.
> 
> One more thought on this: I don't think anyone really likes the 
> #keyPath(Type, .key1.key2)` syntax; it's just the best we've come up with. If 
> the syntax were instead this:
> 
>   #keyPath(Type).key1.key2
> 
> I think that would look cleaner and avoid drawing distinctions based on 
> subtle punctuation differences. I don't think it would clash with old-style 
> key paths since you can't have a key path to a type name anyway. And support 
> for the leading-dot syntax would fall out of it quite naturally.

I see the value in terms of "enabling" the leading-dot syntax, but you have to 
admit that this is really weird with the leading #keyPath expression actually 
there.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Jonathan Hull via swift-evolution

> On Mar 29, 2017, at 6:32 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>>> I would love it if we found a way to retain something as concise as that 
>>> shorthand.  I'm working on a library where users will specify a collection 
>>> of key paths pairs.  This shorthand would be a very nice piece of sugar 
>>> making the code expressing these collections (usually literals) quite a bit 
>>> more readable.
>> 
>> +1 for this.  I think it will be somewhat common to pass around arrays of 
>> these things, and a shorthand syntax of some sort would make that nicer.  
>> That said, I don’t want to slow down the proposal, since I will be using 
>> this feature the very second it becomes available.
> 
> Agreed.
> 
> One more thought on this: I don't think anyone really likes the 
> #keyPath(Type, .key1.key2)` syntax; it's just the best we've come up with. If 
> the syntax were instead this:
> 
>   #keyPath(Type).key1.key2
> 
> I think that would look cleaner and avoid drawing distinctions based on 
> subtle punctuation differences. I don't think it would clash with old-style 
> key paths since you can't have a key path to a type name anyway. And support 
> for the leading-dot syntax would fall out of it quite naturally.

I could get behind that (although it would stop us from extending KeyPaths).  
One question in both cases: How do we represent keyPaths for static properties?

Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Douglas Gregor via swift-evolution


Sent from my iPhone

> On Mar 29, 2017, at 4:52 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>>  wrote:
>> 
>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
>> proposal reflecting these desires.
>> 
>> https://github.com/apple/swift-evolution/pull/644/files
> 
> Quoting from the proposal:
> 
>> luke[keyPath: #keyPath(.friends[0].name)]
> 
> Really? I can understand marking one or the other, but both, even when 
> there's no ambiguity?
> 
> Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
> create a context where we know we have an `AnyKeyPath`, 
> `PartialKeyPath`, `KeyPath`, or `WritableKeyPath U>`. So if the core team's concern is about namespace clashes between 
> `Person`'s static members and key paths, why not hang the key paths off the 
> various `KeyPath` types? That is, this:
> 
>   struct Person {
>   var friends: [Person]
>   var name: String
>   }
> 
> Implies this:
> 
>   extension PartialKeyPath where Root == Person {
>   static let friends: WritableKeyPath
>   static let name: WritableKeyPath
>   }
> 
> And this:
> 
>   #keyPath(Person, .friends[0].name)
> 
> Desugars to this:
> 
>   PartialKeyPath.friends[0].name
> 
> So in a context where you already know you're passing a key path, you can 
> simply write this:
> 
>   luke[keyPath: .friends[0].name]
> 
> Which applies normal "unresolved member" logic to look it up in 
> `PartialKeyPath`.

Yes, this can be done via "unresolved member lookup". It's a little 
different---unresolved member lookup usually can't handle chaining---but the 
type checker could support it. 

> 
> The result would be that you would have to explicitly, syntactically mark key 
> paths except when the context already implied you were looking for one. In an 
> unconstrained generic context, you would not get a key path without using 
> `#keyPath` or explicitly naming a key path type. You would only need to worry 
> about clashes if a call was overloaded to accept *both* `T` and 
> `PartialKeyPath`; if we found that possibility troubling, we could 
> penalize unresolved member lookups that resolve to key paths, so type 
> inference would favor static members over key paths even in those cases.
> 
> Would that work for people? 

It's technically feasible. It makes ".foo" more contextually sensitive, which 
is probably fine. 

  - Doug

> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 29, 2017, at 6:21 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
>> I would love it if we found a way to retain something as concise as that 
>> shorthand.  I'm working on a library where users will specify a collection 
>> of key paths pairs.  This shorthand would be a very nice piece of sugar 
>> making the code expressing these collections (usually literals) quite a bit 
>> more readable.
> 
> +1 for this.  I think it will be somewhat common to pass around arrays of 
> these things, and a shorthand syntax of some sort would make that nicer.  
> That said, I don’t want to slow down the proposal, since I will be using this 
> feature the very second it becomes available.

Agreed.

One more thought on this: I don't think anyone really likes the #keyPath(Type, 
.key1.key2)` syntax; it's just the best we've come up with. If the syntax were 
instead this:

#keyPath(Type).key1.key2

I think that would look cleaner and avoid drawing distinctions based on subtle 
punctuation differences. I don't think it would clash with old-style key paths 
since you can't have a key path to a type name anyway. And support for the 
leading-dot syntax would fall out of it quite naturally.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Jonathan Hull via swift-evolution

> On Mar 29, 2017, at 6:08 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> The one big loss I see from the original proposal is that the current design 
> does not allow us to create a type context that provides something as concise 
> as the original dot shorthand to create key paths.  It's still supported in 
> one sense, but require the #keyPath() wrapper around the key path expression. 
>  That's a lot less elegant.   
> 
> I would love it if we found a way to retain something as concise as that 
> shorthand.  I'm working on a library where users will specify a collection of 
> key paths pairs.  This shorthand would be a very nice piece of sugar making 
> the code expressing these collections (usually literals) quite a bit more 
> readable.

+1 for this.  I think it will be somewhat common to pass around arrays of these 
things, and a shorthand syntax of some sort would make that nicer.  That said, 
I don’t want to slow down the proposal, since I will be using this feature the 
very second it becomes available.

Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Mar 29, 2017, at 7:32 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 29, 2017, at 5:29 PM, Michael J LeHew Jr  wrote:
>> 
>> 
 On Mar 29, 2017, at 4:52 PM, Brent Royal-Gordon  
 wrote:
 
 On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
  wrote:
 
 Thanks for the feedback everyone!  We have pushed a changed a bit ago to 
 the proposal reflecting these desires.
 
 https://github.com/apple/swift-evolution/pull/644/files
>>> 
>>> Quoting from the proposal:
>>> 
 luke[keyPath: #keyPath(.friends[0].name)]
>>> 
>>> Really? I can understand marking one or the other, but both, even when 
>>> there's no ambiguity?
>> 
>> I had the same reaction initially -- but then after talking with Joe, he 
>> reminded me that this is the kind of code that only comes up in a 'this is 
>> how it works' context.  Typically the key path will be a value and the 
>> syntax looks like:  luke[keyPath: somePath]
>> 
>> That example is a touch contrived to show that we'll be able to do the type 
>> inference where possible, 
>> 
>>> 
>>> Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
>>> create a context where we know we have an `AnyKeyPath`, 
>>> `PartialKeyPath`, `KeyPath`, or `WritableKeyPath>> U>`. So if the core team's concern is about namespace clashes between 
>>> `Person`'s static members and key paths, why not hang the key paths off the 
>>> various `KeyPath` types? That is, this:
>>> 
>>>struct Person {
>>>var friends: [Person]
>>>var name: String
>>>}
>>> 
>>> Implies this:
>>> 
>>>extension PartialKeyPath where Root == Person {
>>>static let friends: WritableKeyPath
>>>static let name: WritableKeyPath
>>>}
>>> 
>>> And this:
>>> 
>>>#keyPath(Person, .friends[0].name)
>>> 
>>> Desugars to this:
>>> 
>>>PartialKeyPath.friends[0].name
>>> 
>>> So in a context where you already know you're passing a key path, you can 
>>> simply write this:
>>> 
>>>luke[keyPath: .friends[0].name]
>>> 
>>> Which applies normal "unresolved member" logic to look it up in 
>>> `PartialKeyPath`.
>>> 
>>> The result would be that you would have to explicitly, syntactically mark 
>>> key paths except when the context already implied you were looking for one. 
>>> In an unconstrained generic context, you would not get a key path without 
>>> using `#keyPath` or explicitly naming a key path type. You would only need 
>>> to worry about clashes if a call was overloaded to accept *both* `T` and 
>>> `PartialKeyPath`; if we found that possibility troubling, we could 
>>> penalize unresolved member lookups that resolve to key paths, so type 
>>> inference would favor static members over key paths even in those cases.
>>> 
>>> Would that work for people? 
>> 
>> I'll let Joe speak to this aspect since this touches a lot more on 
>> implementation. 
> 
> Yes, that could work, and that's in fact what was proposed in the first 
> draft. The core team is reasonably hesitant to give up syntactic real estate 
> up front without more evidence that this feature is pervasive enough to 
> deserve it. I think keypaths are useful enough that they certainly could be, 
> but it's easier to add more compact syntax later than to take it away.

The one big loss I see from the original proposal is that the current design 
does not allow us to create a type context that provides something as concise 
as the original dot shorthand to create key paths.  It's still supported in one 
sense, but require the #keyPath() wrapper around the key path expression.  
That's a lot less elegant.   

I would love it if we found a way to retain something as concise as that 
shorthand.  I'm working on a library where users will specify a collection of 
key paths pairs.  This shorthand would be a very nice piece of sugar making the 
code expressing these collections (usually literals) quite a bit more readable.

> 
> -Joe
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2017, at 5:26 PM, Michael J LeHew Jr via swift-evolution 
>  wrote:
> 
> 
>> On Mar 29, 2017, at 5:12 PM, James Berry  wrote:
>> 
>>> Referencing Key Paths
>>> 
>>> Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm 
>>> the existence of a given key path, only now producing concrete values 
>>> instead of Strings. Optionals are handled via optional-chaining. Multiply 
>>> dotted expressions are allowed as well, and work just as if they were 
>>> composed via the appending methods on KeyPath.
>>> 
>>> There is no change or interaction with the #keyPath() syntax introduced in 
>>> Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
>>> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath>> String>.
>> 
>> This distinction seems arbitrary and confusing. The user is supposed tor 
>> remember that the #keyPath(Person.bestFriend.name) form produces a string 
>> while the #keyPath(Person, .bestFriend.name) form produces a key path 
>> object? I don’t think we’re advancing here. What would be the effect if just 
>> the former was valid, and (always/now) produced a keypath object that was 
>> convertible to string? How bad would the breakage be?
> 
> The syntax subtleties here are unfortunate. 
> 
>  An idea that we discussed was to be able to tell when a #keyPath wants to be 
> considered as a string and either implicitly or having some affordance for 
> doing so.   Back then this was harder because we had #keyPaths that could not 
> be represented as a string (an earlier draft had keyPaths that could compose 
> with closures; which while powerful, weren't really key paths any more. That 
> idea was removed from the proposal we shared as they are intrinsically 
> opposed to being able to serializing/deserialize key paths).  
> 
> Given that we don't support those kinds of key paths, nor are we really 
> considering adding them back thanks to our desire to support serializing key 
> paths to file in the future, this is a very reasonable idea I think. 

One small problem with the Swift 3 key path syntax when generalized to allow 
arbitrary Swift types at the root, and to also allow inference of the root, is 
that [...] can be either a subscript or an Array type reference, so it wouldn't 
be clear whether #keyPath([a].foo) is the path `.foo` rooted on the type `[a]` 
or the path `[a].foo` rooted in the contextual root type. We could say that you 
have to use a different syntax for a contextual keypath that begins with a 
subscript, like `#keyPath(.self[a])` or `#keyPath(.[a])`, perhaps.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2017, at 5:29 PM, Michael J LeHew Jr  wrote:
> 
> 
>> On Mar 29, 2017, at 4:52 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>>>  wrote:
>>> 
>>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to 
>>> the proposal reflecting these desires.
>>> 
>>> https://github.com/apple/swift-evolution/pull/644/files
>> 
>> Quoting from the proposal:
>> 
>>> luke[keyPath: #keyPath(.friends[0].name)]
>> 
>> Really? I can understand marking one or the other, but both, even when 
>> there's no ambiguity?
> 
> I had the same reaction initially -- but then after talking with Joe, he 
> reminded me that this is the kind of code that only comes up in a 'this is 
> how it works' context.  Typically the key path will be a value and the syntax 
> looks like:  luke[keyPath: somePath]
> 
> That example is a touch contrived to show that we'll be able to do the type 
> inference where possible, 
> 
>> 
>> Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
>> create a context where we know we have an `AnyKeyPath`, 
>> `PartialKeyPath`, `KeyPath`, or `WritableKeyPath> U>`. So if the core team's concern is about namespace clashes between 
>> `Person`'s static members and key paths, why not hang the key paths off the 
>> various `KeyPath` types? That is, this:
>> 
>>  struct Person {
>>  var friends: [Person]
>>  var name: String
>>  }
>> 
>> Implies this:
>> 
>>  extension PartialKeyPath where Root == Person {
>>  static let friends: WritableKeyPath
>>  static let name: WritableKeyPath
>>  }
>> 
>> And this:
>> 
>>  #keyPath(Person, .friends[0].name)
>> 
>> Desugars to this:
>> 
>>  PartialKeyPath.friends[0].name
>> 
>> So in a context where you already know you're passing a key path, you can 
>> simply write this:
>> 
>>  luke[keyPath: .friends[0].name]
>> 
>> Which applies normal "unresolved member" logic to look it up in 
>> `PartialKeyPath`.
>> 
>> The result would be that you would have to explicitly, syntactically mark 
>> key paths except when the context already implied you were looking for one. 
>> In an unconstrained generic context, you would not get a key path without 
>> using `#keyPath` or explicitly naming a key path type. You would only need 
>> to worry about clashes if a call was overloaded to accept *both* `T` and 
>> `PartialKeyPath`; if we found that possibility troubling, we could 
>> penalize unresolved member lookups that resolve to key paths, so type 
>> inference would favor static members over key paths even in those cases.
>> 
>> Would that work for people? 
> 
> I'll let Joe speak to this aspect since this touches a lot more on 
> implementation. 

Yes, that could work, and that's in fact what was proposed in the first draft. 
The core team is reasonably hesitant to give up syntactic real estate up front 
without more evidence that this feature is pervasive enough to deserve it. I 
think keypaths are useful enough that they certainly could be, but it's easier 
to add more compact syntax later than to take it away.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Michael J LeHew Jr via swift-evolution

> On Mar 29, 2017, at 4:52 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>> > wrote:
>> 
>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
>> proposal reflecting these desires.
>> 
>> https://github.com/apple/swift-evolution/pull/644/files 
>> 
> Quoting from the proposal:
> 
>> luke[keyPath: #keyPath(.friends[0].name)]
> 
> Really? I can understand marking one or the other, but both, even when 
> there's no ambiguity?

I had the same reaction initially -- but then after talking with Joe, he 
reminded me that this is the kind of code that only comes up in a 'this is how 
it works' context.  Typically the key path will be a value and the syntax looks 
like:  luke[keyPath: somePath]

That example is a touch contrived to show that we'll be able to do the type 
inference where possible, 

> 
> Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
> create a context where we know we have an `AnyKeyPath`, 
> `PartialKeyPath`, `KeyPath`, or `WritableKeyPath U>`. So if the core team's concern is about namespace clashes between 
> `Person`'s static members and key paths, why not hang the key paths off the 
> various `KeyPath` types? That is, this:
> 
>   struct Person {
>   var friends: [Person]
>   var name: String
>   }
> 
> Implies this:
> 
>   extension PartialKeyPath where Root == Person {
>   static let friends: WritableKeyPath
>   static let name: WritableKeyPath
>   }
> 
> And this:
> 
>   #keyPath(Person, .friends[0].name)
> 
> Desugars to this:
> 
>   PartialKeyPath.friends[0].name
> 
> So in a context where you already know you're passing a key path, you can 
> simply write this:
> 
>   luke[keyPath: .friends[0].name]
> 
> Which applies normal "unresolved member" logic to look it up in 
> `PartialKeyPath`.
> 
> The result would be that you would have to explicitly, syntactically mark key 
> paths except when the context already implied you were looking for one. In an 
> unconstrained generic context, you would not get a key path without using 
> `#keyPath` or explicitly naming a key path type. You would only need to worry 
> about clashes if a call was overloaded to accept *both* `T` and 
> `PartialKeyPath`; if we found that possibility troubling, we could 
> penalize unresolved member lookups that resolve to key paths, so type 
> inference would favor static members over key paths even in those cases.
> 
> Would that work for people? 

I'll let Joe speak to this aspect since this touches a lot more on 
implementation. 

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Michael J LeHew Jr via swift-evolution

> On Mar 29, 2017, at 5:12 PM, James Berry  wrote:
> 
>> Referencing Key Paths
>> 
>> Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm 
>> the existence of a given key path, only now producing concrete values 
>> instead of Strings. Optionals are handled via optional-chaining. Multiply 
>> dotted expressions are allowed as well, and work just as if they were 
>> composed via the appending methods on KeyPath.
>> 
>> There is no change or interaction with the #keyPath() syntax introduced in 
>> Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
>> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath> String>.
> 
> This distinction seems arbitrary and confusing. The user is supposed tor 
> remember that the #keyPath(Person.bestFriend.name) form produces a string 
> while the #keyPath(Person, .bestFriend.name) form produces a key path object? 
> I don’t think we’re advancing here. What would be the effect if just the 
> former was valid, and (always/now) produced a keypath object that was 
> convertible to string? How bad would the breakage be?

The syntax subtleties here are unfortunate. 

 An idea that we discussed was to be able to tell when a #keyPath wants to be 
considered as a string and either implicitly or having some affordance for 
doing so.   Back then this was harder because we had #keyPaths that could not 
be represented as a string (an earlier draft had keyPaths that could compose 
with closures; which while powerful, weren't really key paths any more. That 
idea was removed from the proposal we shared as they are intrinsically opposed 
to being able to serializing/deserialize key paths).  

Given that we don't support those kinds of key paths, nor are we really 
considering adding them back thanks to our desire to support serializing key 
paths to file in the future, this is a very reasonable idea I think. 


> 
> James
> 
> 
> 
>> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>> > wrote:
>> 
>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
>> proposal reflecting these desires.
>> 
>> https://github.com/apple/swift-evolution/pull/644/files 
>> 
>> 
>> -Michael
>> 
>>> On Mar 29, 2017, at 2:49 PM, Douglas Gregor >> > wrote:
>>> 
>>> 
 On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
 > wrote:
 
 Hi friendly swift-evolution folks,
 
 The Foundation and Swift team  would like for you to consider the 
 following proposal:
>>> 
>>> 
>>> The Swift core team discussed this proposal draft and had a little bit of 
>>> pre-review feedback.
>>> 
 Access and Mutation Through KeyPaths
 To get or set values for a given root and key path we effectively add the 
 following subscripts to all Swift types. 
 
 Swift
 extension Any {
 subscript(path: AnyKeyPath) -> Any? { get }
 subscript(path: PartialKeyPath) -> Any { get }
 subscript(path: KeyPath) -> Value { 
 get }
 subscript(path: WritableKeyPath) -> 
 Value { set, get }
 }
>>> 
>>> Swift doesn’t currently have the ability to extend Any, so this is 
>>> (currently) pseudocode for compiler magic that one day we might be able to 
>>> place. Additionally, the “Root: Self” constraint isn’t something we support 
>>> in the generics system. A small note indicating that this is pseudo-code 
>>> meant to get the point across (rather than real code to drop into the 
>>> standard library/Foundation) would be appreciated.
>>> 
>>> More importantly, this adds an unlabeled subscript to every type, which 
>>> raises concerns about introducing ambiguities—even if not hard ambiguities 
>>> that prevent code from compiling (e.g., from a Dictionary>> …>)---they can still show up in code completion, diagnostics, etc.
>>> 
>>> The core team would prefer that this subscript distinguish itself more, 
>>> e.g., by labeling the first parameter “keyPath” (or some better name, if 
>>> there is one). Syntactically, that would look like:
>>> 
>>> person[keyPath: theKeyPathIHave]
>>> 
 Referencing Key Paths
 
 Forming a KeyPath borrows from the same syntax used to reference methods 
 and initializers,Type.instanceMethod only now working for properties and 
 collections. Optionals are handled via optional-chaining. Multiply dotted 
 expressions are allowed as well, and work just as if they were composed 
 via the appending methods on KeyPath.
 
>>> The core team was concerned about the use of the Type.instanceProperty 
>>> syntax for a few reasons:
>>> 
>>> * It doesn’t work for forming keypaths to class/static properties (or 

Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Charles Srstka via swift-evolution
> On Mar 29, 2017, at 7:12 PM, James Berry via swift-evolution 
>  wrote:
> 
>> Referencing Key Paths
>> 
>> Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm 
>> the existence of a given key path, only now producing concrete values 
>> instead of Strings. Optionals are handled via optional-chaining. Multiply 
>> dotted expressions are allowed as well, and work just as if they were 
>> composed via the appending methods on KeyPath.
>> 
>> There is no change or interaction with the #keyPath() syntax introduced in 
>> Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
>> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath> String>.
> 
> This distinction seems arbitrary and confusing. The user is supposed tor 
> remember that the #keyPath(Person.bestFriend.name) form produces a string 
> while the #keyPath(Person, .bestFriend.name) form produces a key path object? 
> I don’t think we’re advancing here. What would be the effect if just the 
> former was valid, and (always/now) produced a keypath object that was 
> convertible to string? How bad would the breakage be?

This definitely sounds like the better option to me. Just change the 
Objective-C bridge so that a key path bridges to a string, and make the various 
Cocoa APIs such as value(forKeyPath:) and friends take key paths.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread James Berry via swift-evolution
> Referencing Key Paths
> 
> Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm 
> the existence of a given key path, only now producing concrete values instead 
> of Strings. Optionals are handled via optional-chaining. Multiply dotted 
> expressions are allowed as well, and work just as if they were composed via 
> the appending methods on KeyPath.
> 
> There is no change or interaction with the #keyPath() syntax introduced in 
> Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath String>.

This distinction seems arbitrary and confusing. The user is supposed tor 
remember that the #keyPath(Person.bestFriend.name) form produces a string while 
the #keyPath(Person, .bestFriend.name) form produces a key path object? I don’t 
think we’re advancing here. What would be the effect if just the former was 
valid, and (always/now) produced a keypath object that was convertible to 
string? How bad would the breakage be?

James



> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>  wrote:
> 
> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
> proposal reflecting these desires.
> 
> https://github.com/apple/swift-evolution/pull/644/files 
> 
> 
> -Michael
> 
>> On Mar 29, 2017, at 2:49 PM, Douglas Gregor > > wrote:
>> 
>> 
>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>>> > wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>> 
>> 
>> The Swift core team discussed this proposal draft and had a little bit of 
>> pre-review feedback.
>> 
>>> Access and Mutation Through KeyPaths
>>> To get or set values for a given root and key path we effectively add the 
>>> following subscripts to all Swift types. 
>>> 
>>> Swift
>>> extension Any {
>>> subscript(path: AnyKeyPath) -> Any? { get }
>>> subscript(path: PartialKeyPath) -> Any { get }
>>> subscript(path: KeyPath) -> Value { get 
>>> }
>>> subscript(path: WritableKeyPath) -> 
>>> Value { set, get }
>>> }
>> 
>> Swift doesn’t currently have the ability to extend Any, so this is 
>> (currently) pseudocode for compiler magic that one day we might be able to 
>> place. Additionally, the “Root: Self” constraint isn’t something we support 
>> in the generics system. A small note indicating that this is pseudo-code 
>> meant to get the point across (rather than real code to drop into the 
>> standard library/Foundation) would be appreciated.
>> 
>> More importantly, this adds an unlabeled subscript to every type, which 
>> raises concerns about introducing ambiguities—even if not hard ambiguities 
>> that prevent code from compiling (e.g., from a Dictionary> …>)---they can still show up in code completion, diagnostics, etc.
>> 
>> The core team would prefer that this subscript distinguish itself more, 
>> e.g., by labeling the first parameter “keyPath” (or some better name, if 
>> there is one). Syntactically, that would look like:
>> 
>>  person[keyPath: theKeyPathIHave]
>> 
>>> Referencing Key Paths
>>> 
>>> Forming a KeyPath borrows from the same syntax used to reference methods 
>>> and initializers,Type.instanceMethod only now working for properties and 
>>> collections. Optionals are handled via optional-chaining. Multiply dotted 
>>> expressions are allowed as well, and work just as if they were composed via 
>>> the appending methods on KeyPath.
>>> 
>> The core team was concerned about the use of the Type.instanceProperty 
>> syntax for a few reasons:
>> 
>>  * It doesn’t work for forming keypaths to class/static properties (or 
>> is ambiguous with the existing meaning(, so we would need another syntax to 
>> deal with that case
>>  * It’s quite subtle, even more so that the existing Type.instanceMethod 
>> syntax for currying instance methods
>> 
>>> There is no change or interaction with the #keyPath() syntax introduced in 
>>> Swift 3. 
>>> 
>> The core team felt that extending the #keyPath syntax was a better syntactic 
>> direction to produce key-paths.
>> 
>>  - Doug
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution 
>  wrote:
> 
> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
> proposal reflecting these desires.
> 
> https://github.com/apple/swift-evolution/pull/644/files 
> 
Quoting from the proposal:

> luke[keyPath: #keyPath(.friends[0].name)]

Really? I can understand marking one or the other, but both, even when there's 
no ambiguity?

Let's pretend we're the type checker here. The `luke[keyPath: _]` part will 
create a context where we know we have an `AnyKeyPath`, 
`PartialKeyPath`, `KeyPath`, or `WritableKeyPath`. So if the core team's concern is about namespace clashes between 
`Person`'s static members and key paths, why not hang the key paths off the 
various `KeyPath` types? That is, this:

struct Person {
var friends: [Person]
var name: String
}

Implies this:

extension PartialKeyPath where Root == Person {
static let friends: WritableKeyPath
static let name: WritableKeyPath
}

And this:

#keyPath(Person, .friends[0].name)

Desugars to this:

PartialKeyPath.friends[0].name

So in a context where you already know you're passing a key path, you can 
simply write this:

luke[keyPath: .friends[0].name]

Which applies normal "unresolved member" logic to look it up in 
`PartialKeyPath`.

The result would be that you would have to explicitly, syntactically mark key 
paths except when the context already implied you were looking for one. In an 
unconstrained generic context, you would not get a key path without using 
`#keyPath` or explicitly naming a key path type. You would only need to worry 
about clashes if a call was overloaded to accept *both* `T` and 
`PartialKeyPath`; if we found that possibility troubling, we could penalize 
unresolved member lookups that resolve to key paths, so type inference would 
favor static members over key paths even in those cases.

Would that work for people? 

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Michael J LeHew Jr via swift-evolution
Thanks for the feedback everyone!  We have pushed a changed a bit ago to the 
proposal reflecting these desires.

https://github.com/apple/swift-evolution/pull/644/files

-Michael

> On Mar 29, 2017, at 2:49 PM, Douglas Gregor  wrote:
> 
> 
>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>> > wrote:
>> 
>> Hi friendly swift-evolution folks,
>> 
>> The Foundation and Swift team  would like for you to consider the following 
>> proposal:
> 
> 
> The Swift core team discussed this proposal draft and had a little bit of 
> pre-review feedback.
> 
>> Access and Mutation Through KeyPaths
>> To get or set values for a given root and key path we effectively add the 
>> following subscripts to all Swift types. 
>> 
>> Swift
>> extension Any {
>> subscript(path: AnyKeyPath) -> Any? { get }
>> subscript(path: PartialKeyPath) -> Any { get }
>> subscript(path: KeyPath) -> Value { get }
>> subscript(path: WritableKeyPath) -> 
>> Value { set, get }
>> }
> 
> Swift doesn’t currently have the ability to extend Any, so this is 
> (currently) pseudocode for compiler magic that one day we might be able to 
> place. Additionally, the “Root: Self” constraint isn’t something we support 
> in the generics system. A small note indicating that this is pseudo-code 
> meant to get the point across (rather than real code to drop into the 
> standard library/Foundation) would be appreciated.
> 
> More importantly, this adds an unlabeled subscript to every type, which 
> raises concerns about introducing ambiguities—even if not hard ambiguities 
> that prevent code from compiling (e.g., from a Dictionary …>)---they can still show up in code completion, diagnostics, etc.
> 
> The core team would prefer that this subscript distinguish itself more, e.g., 
> by labeling the first parameter “keyPath” (or some better name, if there is 
> one). Syntactically, that would look like:
> 
>   person[keyPath: theKeyPathIHave]
> 
>> Referencing Key Paths
>> 
>> Forming a KeyPath borrows from the same syntax used to reference methods and 
>> initializers,Type.instanceMethod only now working for properties and 
>> collections. Optionals are handled via optional-chaining. Multiply dotted 
>> expressions are allowed as well, and work just as if they were composed via 
>> the appending methods on KeyPath.
>> 
> The core team was concerned about the use of the Type.instanceProperty syntax 
> for a few reasons:
> 
>   * It doesn’t work for forming keypaths to class/static properties (or 
> is ambiguous with the existing meaning(, so we would need another syntax to 
> deal with that case
>   * It’s quite subtle, even more so that the existing Type.instanceMethod 
> syntax for currying instance methods
> 
>> There is no change or interaction with the #keyPath() syntax introduced in 
>> Swift 3. 
>> 
> The core team felt that extending the #keyPath syntax was a better syntactic 
> direction to produce key-paths.
> 
>   - Doug
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-29 Thread Douglas Gregor via swift-evolution

> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>  wrote:
> 
> Hi friendly swift-evolution folks,
> 
> The Foundation and Swift team  would like for you to consider the following 
> proposal:


The Swift core team discussed this proposal draft and had a little bit of 
pre-review feedback.

> Access and Mutation Through KeyPaths
> To get or set values for a given root and key path we effectively add the 
> following subscripts to all Swift types. 
> 
> Swift
> extension Any {
> subscript(path: AnyKeyPath) -> Any? { get }
> subscript(path: PartialKeyPath) -> Any { get }
> subscript(path: KeyPath) -> Value { get }
> subscript(path: WritableKeyPath) -> Value 
> { set, get }
> }

Swift doesn’t currently have the ability to extend Any, so this is (currently) 
pseudocode for compiler magic that one day we might be able to place. 
Additionally, the “Root: Self” constraint isn’t something we support in the 
generics system. A small note indicating that this is pseudo-code meant to get 
the point across (rather than real code to drop into the standard 
library/Foundation) would be appreciated.

More importantly, this adds an unlabeled subscript to every type, which raises 
concerns about introducing ambiguities—even if not hard ambiguities that 
prevent code from compiling (e.g., from a Dictionary)---they can 
still show up in code completion, diagnostics, etc.

The core team would prefer that this subscript distinguish itself more, e.g., 
by labeling the first parameter “keyPath” (or some better name, if there is 
one). Syntactically, that would look like:

person[keyPath: theKeyPathIHave]

> Referencing Key Paths
> 
> Forming a KeyPath borrows from the same syntax used to reference methods and 
> initializers,Type.instanceMethod only now working for properties and 
> collections. Optionals are handled via optional-chaining. Multiply dotted 
> expressions are allowed as well, and work just as if they were composed via 
> the appending methods on KeyPath.
> 
The core team was concerned about the use of the Type.instanceProperty syntax 
for a few reasons:

* It doesn’t work for forming keypaths to class/static properties (or 
is ambiguous with the existing meaning(, so we would need another syntax to 
deal with that case
* It’s quite subtle, even more so that the existing Type.instanceMethod 
syntax for currying instance methods

> There is no change or interaction with the #keyPath() syntax introduced in 
> Swift 3. 
> 
The core team felt that extending the #keyPath syntax was a better syntactic 
direction to produce key-paths.

- Doug

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-27 Thread Daniel Müllenborn via swift-evolution
I had the same thoughts, the syntax should differ in some way from that of a 
static property. I find : very suitable as a symbol.
What I do not like -> or $, because it reminds me too much of PHP. The @ signs 
are somehow also unsuitable.

> > Le 19 mars 2017 à 16:41, Ricardo Parada via 
> > swift-evolutiona écrit :
> > 
> > I agree that they can get mixed up with static properties. However, I think 
> > I would not mind because it would only cause an ambiguity when having a 
> > static property with the same name as the property which would be an odd 
> > practice I think.
> I disagree. How the reader is supposed to now there is a static property or 
> not ? Having readable code is more important than having easy to write code.
> 
> Without context, the following statement is ambiguous, This ambiguity can 
> easily be avoid by choosing an other syntax. So why would we want to 
> introduce it in the first place ?
> 
> let name = Person:friends[0].name
> 
> 
> 
> > I was defining static properties with the same name as the property in 
> > order to smart key paths. For example:
> > 
> > Class Person {
> > static firstName: KeyPath(“firstName”)
> > static lastName: KeyPath(“lastName”)
> > 
> > var firstName: String
> > var lastName: String
> > 
> > …
> > }
> > 
> > 
> > So that I could create qualifiers, ie. Person.firstName.like(“R*”), and 
> > sort orderings, Person.firstName.asc().
> > 
> > I think with these smart key paths the need for these static properties 
> > that mirror the property on the instance would not be required.
> > 
> > 
> > 
> > 
> > > On Mar 17, 2017, at 2:27 PM, Vladimir.S via 
> > > swift-evolutionwrote:
> > > 
> > > On 17.03.2017 20:04, Michael LeHew via swift-evolution 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
> > > > ...
> > > 
> > > Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
> > > 
> > > Person.friends[0].name - like access to static property. T.method can't 
> > > have subscript for it and then some field. So, I believe such key paths 
> > > deserve its own syntax.
> > > 
> > > luke[path] - very close to access the subscript of instance. In compare 
> > > to T.method, we can call result of T.method(i.e. let m = T.method; m()), 
> > > just like the T.method itself(foo.method()). But here we are calling some 
> > > kind of subscript instead of access property by "path".
> > > 
> > > There is no some 'special' marker for me that saying "hey, there is 
> > > references to properties used" from the first look.
> > > 
> > > Probably we can consider another separators, like
> > > 
> > > Person:friends[0].name
> > > luke:path
> > > 
> > > Person->friends[0].name
> > > luke->path
> > > 
> > > Person[friends[0].name] // single brackets for type
> > > luke[[path]] // double brackets for instance
> > > 
> > > Person@friends[0].name
> > > luke@path
> > > 
> > > or other with help of community.
> > > ___
> > > swift-evolution mailing list
> > > swift-evolution@swift.org
> > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > 
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-23 Thread Karim Nassar via swift-evolution

> I guess I just don't understand why people seem so eager to change this 
> syntax. The biggest complaint seems to be that it's too lightweight and 
> natural; they're worried they might not realize they're using this big, scary 
> new feature. But this feature simply *isn't* big and scary! It's new right 
> now, but in a few years it's going to feel very natural.
> 
> […]
> 
> Key paths are about as nonthreatening as a syntax can be. They overload some 
> things, but the type checker will catch most overloading mistakes. Other than 
> that, there's just no justification for the level of anxiety people seem to 
> have. They don't break type safety, they don't involve unusual or non-obvious 
> control flow, they don't trap, and they can be explained in a couple of 
> sentences. If ever there was a candidate for a lightweight syntax, this is 
> it. 
> 
> As the protest sign says: "I want YOU to stop being afraid". I have yet to be 
> convinced that this feature is too dangerous or mistake-prone to allow the 
> simple, natural syntax the authors propose. If I'm wrong, then by all means 
> show me I'm wrong, but I just don't see it.


I don’t have a strong opinion on the sigil question one way or another, but I’m 
not sure it’s fair to categorize the sigil proponents as being afraid of the 
feature. I do find the argument that some kind of sigil to clarify the 
construction-site of a KeyPath somewhat compelling.

KeyPath declarations as described in the proposal are fairly unique in that 
they have all the appearance of accessing a property value on a type, but are 
in fact a mechanism for “creating” (referencing?) a type entirely different 
from their face-value. That is: a KeyPath shares most of its spelling with the 
value that it points to, and absent knowledge of the programmer’s *intent* it’s 
not immediately obvious whether code is accessing a value or creating a 
KeyPath. They are references to a named member of a type which are derived by 
their name.

IMHO, it’s not *that* unreasonable to want a spelling variation to call 
attention to this difference.

In any case, as I said, I’m not strongly opinionated on this matter, but 
perhaps it *is* worth considering some sigil we could apply to both KeyPath and 
function assignments to clarify both sites in the same way.

—Karim
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Ricardo Parada via swift-evolution
By the way, I am okay with the syntax in the proposal too.  I'm just 
brainstorming so that we can look at all the options.  I am guessing the 
authors (David Smith, Michael LeHew and Joe Groff) probably went through this 
process already and settled with the simpler notation.  :-)


> On Mar 22, 2017, at 4:51 PM, Ricardo Parada via swift-evolution 
>  wrote:
> 
> Yes, I was about to ask the same.  
> 
> It seems like all the sigil characters are taken.  This is one of the reasons 
> why I did not object to the non-sigil notation originally proposed despite 
> the ambiguity with static properties and instance properties with the same 
> name.  But using a sigil seems like it can unify method references and key 
> path references.
> 
> Is the single quote taken?  For example:
> 
> let path = 'Bag.things[0].name
> bag[path] 
> bag['Bag.things[0].name]
> bag['.things[0].name]
> bag.things[0]['.name]
> bag.things[0]['Thing.name]
> 
> And the examples on the proposal would become:
> 
> 'Person.friends[0].name
> luke['.friends[0].name]
> luke.friends[0]['.name]
> 
> If we were to put it between root and the path then it would look like this:
> 
> let path = Bag'things[0].name
> bag[path] 
> bag[Bag'things[0].name]
> bag['things[0].name]
> bag.things[0]['name]
> bag.things[0][Thing'name]
> 
> 
> Right now the compiler tells me that it found an "unterminated string 
> literal".  
> 
> When I add the closing single quote then it tells me "single-quoted string 
> literal found, use '"' instead"
> 
> 
> 
> 
>> On Mar 22, 2017, at 3:16 PM, Brent Royal-Gordon via swift-evolution 
>> > wrote:
>> 
>>> On Mar 22, 2017, at 9:00 AM, Vladimir.S via swift-evolution 
>>> > wrote:
>>> 
>>> bag[#path]
>> 
>> What do these do?
>> 
>>  bag[#file]
>>  bag[#line]
>>  bag[#function]
>>  // etc.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Ricardo Parada via swift-evolution
Yes, I was about to ask the same.  

It seems like all the sigil characters are taken.  This is one of the reasons 
why I did not object to the non-sigil notation originally proposed despite the 
ambiguity with static properties and instance properties with the same name.  
But using a sigil seems like it can unify method references and key path 
references.

Is the single quote taken?  For example:

let path = 'Bag.things[0].name
bag[path] 
bag['Bag.things[0].name]
bag['.things[0].name]
bag.things[0]['.name]
bag.things[0]['Thing.name]

And the examples on the proposal would become:

'Person.friends[0].name
luke['.friends[0].name]
luke.friends[0]['.name]

If we were to put it between root and the path then it would look like this:

let path = Bag'things[0].name
bag[path] 
bag[Bag'things[0].name]
bag['things[0].name]
bag.things[0]['name]
bag.things[0][Thing'name]


Right now the compiler tells me that it found an "unterminated string literal". 
 

When I add the closing single quote then it tells me "single-quoted string 
literal found, use '"' instead"




> On Mar 22, 2017, at 3:16 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Mar 22, 2017, at 9:00 AM, Vladimir.S via swift-evolution 
>> > wrote:
>> 
>> bag[#path]
> 
> What do these do?
> 
>   bag[#file]
>   bag[#line]
>   bag[#function]
>   // etc.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 3:30 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 22, 2017, at 11:27 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> One option would be to include `get` and `set` methods on the key path 
>> types.  That would allow us to write the subscripts in the standard library 
>> (if it is allowed to extend Any) and keep all of the magic in the key path 
>> types themselves.  I think I would like that approach.
> 
> 
> This is not a good option. Although we Swift users may write `get` and `set` 
> accessors, the real primitives in Swift are `get` and `materializeForSet`, 
> which is basically "return a pointer that can be modified until another call 
> is made which finalizes the set". `materializeForSet`'s call sequence is too 
> low-level to be written manually; without adding other features to the 
> language, we're basically left with either calling a method that calls a 
> closure with an `inout` parameter, or using a subscript.

This is what I had in mind (synthesized by the compiler):

extension WritableKeyPath {
func get(from root: Root) -> Value { … }
func set(to value: Value, on root: inout Root) { … }
}

And something like this in the standard library:

extension Any {
subscript(path: WritableKeyPath) -> Value { 
get {
return path.get(from: self)
}
set {
path.set(to: value, on: )
}
}
}

Is there a reason this wouldn’t work?  I’m only presenting it for the sake of 
discussion.  I don’t have a strong opinion about it one way or the other.  The 
nice thing about it is that it keeps the magic in the key path types.

> 
> The ownership manifesto includes a generator feature which could, some day, 
> make it possible to write a method wrapping `materializeForSet`. But 
> subscripts allow us to do this today, and it's *perfectly* natural to think 
> of key paths as being a subscript; subscripts are for accessing values inside 
> an instance, and a key path addresses a value inside an instance, too.

I definitely think the subscript syntax should be supported.  I’m only 
suggesting an option that might allow us to keep all of the compiler magic in 
the key path types.

> 
> I guess I just don't understand why people seem so eager to change this 
> syntax. The biggest complaint seems to be that it's too lightweight and 
> natural; they're worried they might not realize they're using this big, scary 
> new feature. But this feature simply *isn't* big and scary! It's new right 
> now, but in a few years it's going to feel very natural.

I’m not eager.  I’m just discussing options that are acceptable to me because a 
lot of people seem to want something different.  I’m happy with the syntax 
included in the proposal as well.

> 
> I can't find it now, but I once read someone state that this is part of what 
> happened to C++: Every time someone proposed a new feature, people were 
> worried that they would use it by accident, so they insisted that it have an 
> unmistakable, obvious syntax so you would know you were using it. The result 
> is that now, almost every syntax in C++ is shouting at you that you're using 
> feature X, Y, or Z, and you can't hear your own code over the din.

A good cautionary tale.  I’m pretty neutral between the syntax in the proposal 
and the # sigil idea.  Regardless of which we go with, I think there is some 
value in exploring how we might keep the compiler magic in the key path types.

> 
> Key paths are about as nonthreatening as a syntax can be. They overload some 
> things, but the type checker will catch most overloading mistakes. Other than 
> that, there's just no justification for the level of anxiety people seem to 
> have. They don't break type safety, they don't involve unusual or non-obvious 
> control flow, they don't trap, and they can be explained in a couple of 
> sentences. If ever there was a candidate for a lightweight syntax, this is 
> it. 

Agree.  They can also be conceptualized as compiler synthesized static 
properties if we move forward with the syntax in the current proposal.  There 
is nothing wrong with this model aside from a minimal risk of ambiguity (which 
I don’t think is worth worrying about).

> 
> As the protest sign says: "I want YOU to stop being afraid". I have yet to be 
> convinced that this feature is too dangerous or mistake-prone to allow the 
> simple, natural syntax the authors propose. If I'm wrong, then by all means 
> show me I'm wrong, but I just don't see it.

I agree that the fear seems to be overblown.  That said, key paths are 
synthesizing special values in a way that has some similarity to #selector.  It 
has also been pointed out that # could resolve some issues we have right now 
with unbound methods.   If it makes people feel better to use # to access 
unbound members and it solves a problem, maybe it’s worth considering.

Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Brent Royal-Gordon via swift-evolution
> On Mar 22, 2017, at 11:27 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> One option would be to include `get` and `set` methods on the key path types. 
>  That would allow us to write the subscripts in the standard library (if it 
> is allowed to extend Any) and keep all of the magic in the key path types 
> themselves.  I think I would like that approach.


This is not a good option. Although we Swift users may write `get` and `set` 
accessors, the real primitives in Swift are `get` and `materializeForSet`, 
which is basically "return a pointer that can be modified until another call is 
made which finalizes the set". `materializeForSet`'s call sequence is too 
low-level to be written manually; without adding other features to the 
language, we're basically left with either calling a method that calls a 
closure with an `inout` parameter, or using a subscript.

The ownership manifesto includes a generator feature which could, some day, 
make it possible to write a method wrapping `materializeForSet`. But subscripts 
allow us to do this today, and it's *perfectly* natural to think of key paths 
as being a subscript; subscripts are for accessing values inside an instance, 
and a key path addresses a value inside an instance, too.

I guess I just don't understand why people seem so eager to change this syntax. 
The biggest complaint seems to be that it's too lightweight and natural; 
they're worried they might not realize they're using this big, scary new 
feature. But this feature simply *isn't* big and scary! It's new right now, but 
in a few years it's going to feel very natural.

I can't find it now, but I once read someone state that this is part of what 
happened to C++: Every time someone proposed a new feature, people were worried 
that they would use it by accident, so they insisted that it have an 
unmistakable, obvious syntax so you would know you were using it. The result is 
that now, almost every syntax in C++ is shouting at you that you're using 
feature X, Y, or Z, and you can't hear your own code over the din.

Key paths are about as nonthreatening as a syntax can be. They overload some 
things, but the type checker will catch most overloading mistakes. Other than 
that, there's just no justification for the level of anxiety people seem to 
have. They don't break type safety, they don't involve unusual or non-obvious 
control flow, they don't trap, and they can be explained in a couple of 
sentences. If ever there was a candidate for a lightweight syntax, this is it. 

As the protest sign says: "I want YOU to stop being afraid". I have yet to be 
convinced that this feature is too dangerous or mistake-prone to allow the 
simple, natural syntax the authors propose. If I'm wrong, then by all means 
show me I'm wrong, but I just don't see it.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Sean Heber via swift-evolution
> One option would be to include `get` and `set` methods on the key path types. 
>  That would allow us to write the subscripts in the standard library (if it 
> is allowed to extend Any) and keep all of the magic in the key path types 
> themselves.  I think I would like that approach.

+1

l8r
Sean

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Brent Royal-Gordon via swift-evolution
> On Mar 22, 2017, at 9:00 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> bag[#path]

What do these do?

bag[#file]
bag[#line]
bag[#function]
// etc.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 12:34 PM, Vladimir.S  wrote:
> 
> On 22.03.2017 19:25, Matthew Johnson wrote:
>> 
>>> On Mar 22, 2017, at 11:00 AM, Vladimir.S >> > wrote:
>>> 
>>> On 22.03.2017 18:47, Matthew Johnson wrote:
 
> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution
> 
> > wrote:
> 
> On 22.03.2017 17:37, Ricardo Parada wrote:
>> 
>> 
>>> On Mar 22, 2017, at 9:30 AM, Vladimir.S >> 
>>> > wrote:
>>> 
>>> let path = @Bag.things[0].name
>>> 
>>> bag@path
>>> bag@.things[0].name
>>> bag@Bag.things  [0].name
>>> bag.things[0]@.name
>>> bag.things[0]@Thing.name
>> 
>> It sounds like the @ character is serving two different purposes which
>> confused me at first.
>> 
>> If I understood correctly, you are using it to get the key path but also
>> to apply the key path to the bag struct and get the corresponding value.
>> 
> 
> Yes. And the initial proposal suggest the following syntax accordingly:
> 
> let path = Bag.things[0].name
> bag[path]
> bag[.things[0].name]
> bag[Bag.things[0].name]
> bag.things[0][.name]
> bag.things[0][Thing.name]
 
 # makes a lot more sense than @ as a sigil.  It follows from #selector and
 #keyPath.  These are the most similar language features right now where the
 compiler produces special values.  I think it’s also worth noticing that
 values produced by #selector and #keyPath are /used/ in normal ways.  There
 is no magic syntax for their use, just a typed value.  If we’re going to
 make a change we should use # instead of `.` for accessing these special
 values but we should stick with subscript for use.
>>> 
>>> Could you clarify, what do you suggest? Something like this:
>>> let path = Bag#things[0]#name
>> 
>> I would only use one # at the start of the key path.  Dots could be used
>> afterwords like this: `Bag#things[0].name`  I think it is important to use
>> normal expression syntax after the key path is introduced.
>> 
> 
> Generally agree.
> 
>>> bag[#path]
>> 
>> No, you would just say `bag[path]`.  `path` is a normal value and the
>> subscript taking a path is a normal subscript.
> 
> That was my main intention - to discuss if we should add some special marker 
> when we create *and* also use key path. To remove confusion when you see 
> 'instance[something]' in one's code and can't be sure if we access a "normal" 
> subscript or 'something' is a key path. Especially if instance is 
> array/dictionary or other collection.
> I believe this feature deserves some highlighting with special syntax even on 
> usage site.
> And subscript in this case IMO is not "normal" subscript - but "special" 
> subscript generated by compiler to work with key path.

The fact that this is a key path exists in the type system and is readily 
available.  It also likely exists in the variable name.  We don’t use special 
syntax when we work with a selector or a KVC key path.  I don’t think we should 
use special syntax here either.

The compiler will synthesizes these subscripts but it also synthesizes other 
code for us now and will synthesize even more in the future.  I don’t see 
compiler synthesis as a compelling reason for using special syntax.  The reason 
it makes some sense for creating the values is because they are values of a 
special type that only the compiler can create.

One option would be to include `get` and `set` methods on the key path types.  
That would allow us to write the subscripts in the standard library (if it is 
allowed to extend Any) and keep all of the magic in the key path types 
themselves.  I think I would like that approach.

> 
> 
> Vladimir.
> 
>> 
>>> bag[#things[0]#name]
>> 
>> Here we have a type context expecting a key path with a root of the type of
>> `bag`.  There is no potential ambiguity involved in using the `.` here
>> unless people extend the key path types with static members themselves.  I
>> think it’s fair to say do that at your own risk.  So there is no *need* to
>> use special synatx - dot shorthand would work just fine with no ambiguity
>> problem.  You could imagine the compiler synthesizing static members on key
>> path types like this:
>> 
>> extension PartialKeyPath where Root == BagType {
>>static var things: KeyPath  // or WriteableKeyPath
>> or ReferenceWritableKeyPath
>> }
>> 
>> You just say: `bag[.things[0]#name]` using the existing dot shorthand for
>> static members that return a value matching the type they are declared on.
>> 
>> On the other hand, it would be more consistent to introduce # shorthand
>> here and not have the imaginary / synthesized static 

Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Vladimir.S via swift-evolution

On 22.03.2017 19:25, Matthew Johnson wrote:



On Mar 22, 2017, at 11:00 AM, Vladimir.S > wrote:

On 22.03.2017 18:47, Matthew Johnson wrote:



On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution

> wrote:

On 22.03.2017 17:37, Ricardo Parada wrote:




On Mar 22, 2017, at 9:30 AM, Vladimir.S 
> wrote:

let path = @Bag.things[0].name

bag@path
bag@.things[0].name
bag@Bag.things  [0].name
bag.things[0]@.name
bag.things[0]@Thing.name


It sounds like the @ character is serving two different purposes which
confused me at first.

If I understood correctly, you are using it to get the key path but also
to apply the key path to the bag struct and get the corresponding value.



Yes. And the initial proposal suggest the following syntax accordingly:

let path = Bag.things[0].name
bag[path]
bag[.things[0].name]
bag[Bag.things[0].name]
bag.things[0][.name]
bag.things[0][Thing.name]


# makes a lot more sense than @ as a sigil.  It follows from #selector and
#keyPath.  These are the most similar language features right now where the
compiler produces special values.  I think it’s also worth noticing that
values produced by #selector and #keyPath are /used/ in normal ways.  There
is no magic syntax for their use, just a typed value.  If we’re going to
make a change we should use # instead of `.` for accessing these special
values but we should stick with subscript for use.


Could you clarify, what do you suggest? Something like this:
let path = Bag#things[0]#name


I would only use one # at the start of the key path.  Dots could be used
afterwords like this: `Bag#things[0].name`  I think it is important to use
normal expression syntax after the key path is introduced.



Generally agree.


bag[#path]


No, you would just say `bag[path]`.  `path` is a normal value and the
subscript taking a path is a normal subscript.


That was my main intention - to discuss if we should add some special 
marker when we create *and* also use key path. To remove confusion when you 
see 'instance[something]' in one's code and can't be sure if we access a 
"normal" subscript or 'something' is a key path. Especially if instance is 
array/dictionary or other collection.
I believe this feature deserves some highlighting with special syntax even 
on usage site.
And subscript in this case IMO is not "normal" subscript - but "special" 
subscript generated by compiler to work with key path.



Vladimir.




bag[#things[0]#name]


Here we have a type context expecting a key path with a root of the type of
`bag`.  There is no potential ambiguity involved in using the `.` here
unless people extend the key path types with static members themselves.  I
think it’s fair to say do that at your own risk.  So there is no *need* to
use special synatx - dot shorthand would work just fine with no ambiguity
problem.  You could imagine the compiler synthesizing static members on key
path types like this:

extension PartialKeyPath where Root == BagType {
static var things: KeyPath  // or WriteableKeyPath
or ReferenceWritableKeyPath
}

You just say: `bag[.things[0]#name]` using the existing dot shorthand for
static members that return a value matching the type they are declared on.

On the other hand, it would be more consistent to introduce # shorthand
here and not have the imaginary / synthesized static members on the key
path types.  I’m neutral, leaning towards using # shorthand for this.



bag[Bag#things[0]#name]


As above, there is no need for a second `#`.  Once the expression has
produced a key path all subsequent chained accesses will also produce a key
path.

bag[Bag#things[0].name]


bag.things[0][#name]


As above, here we have a type context in the subscript that expects a key
path.  We could use the existing dot shorthand and compiler synthesized
static properties on key path types or just introduce a # shorthand.  The
latter is probably better for consistency.


bag.things[0][Thing#name]


Sure, if you don’t like the shorthand.



,and so
let ref = Bag#foo()


Yep.

One interesting thing to note is that we could also get deep references to
unbound methods.  This would effectively combine key paths with unbound
method references:

let doSomething = Bag#things[0].doSomething()

used like this:
doSomthing(bag)

Using # for key paths also allows us to build on it in the future for
collection operators:

Bag#things[#sum].value //  a key path that sums the value of all things in
a bag

Reserving this potential is one important reason to only use # where you
are introducing a special key path expression and not everywhere in the key
path chain.



?

In this case I feel like the following will be more clean syntax:
let path = #Bag.things[0].name
bag[#path]

Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 11:41 AM, Ricardo Parada  wrote:
> 
> Agree.
> 
> Another question.  If `Bag` does have a static thing called `myStaticThingy` 
> would you refer to it as:
> 
> Bag.Type#myStaticThingy

I would expect that to work eventually but I’m not sure if it would be included 
in the initial proposal or not.

> 
> ?
> 
> 
>> On Mar 22, 2017, at 12:37 PM, Matthew Johnson > > wrote:
>> 
>>> 
>>> On Mar 22, 2017, at 11:16 AM, Ricardo Parada >> > wrote:
>>> 
>>> I see three possibilities:
>>> 
>>> 1) # + «space» +«path» like this:
>>> 
>>> let path = # Bag.things[0].name
>>> bag[path] 
>>> bag[# Bag.things[0].name]
>>> bag[# .things[0].name]  // Root is inferred as Bag
>>> bag.things[0][# Thing.name]
>>> bag.things[0][# .name] // Root is inferred as Thing
>>> 
>>> 2) # + «path» like this::
>>> 
>>> let path = #Bag.things[0].name
>>> bag[path] 
>>> bag[#Bag.things[0].name]
>>> bag[# .things[0].name]  // Root is inferred as Bag
>>> bag.things[0][#Thing.name]
>>> bag.things[0][#.name]  // Root is inferred as Thing
>>> 
>>> 3) «Root» + # + «path» like this: 
>>> 
>>> let path = Bag#things[0].name
>>> bag[path] 
>>> bag[Bag#things[0].name]
>>> bag[#things[0].name]
>>> bag.things[0][#name]
>>> bag.things[0][Thing#name]
>> 
>> I prefer the third option.  I don’t think we should go with the first 
>> option.  Allowing (or requiring) a space seems likely to be confusing.  Both 
>> the first and the second still have potential to be confusing.  If `Bag` has 
>> a static property named `things` people could be confused about what 
>> `#Bag.things` refers to.  If we’re going to use a special sigil it should be 
>> positioned such that it eliminates potential for that kind of confusion.
>> 
>>> 
>>> 
>>> 
 On Mar 22, 2017, at 11:47 AM, Matthew Johnson > wrote:
 
 
> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution 
> > wrote:
> 
> On 22.03.2017 17:37, Ricardo Parada wrote:
>> 
>> 
>>> On Mar 22, 2017, at 9:30 AM, Vladimir.S >> > wrote:
>>> 
>>> let path = @Bag.things[0].name
>>> 
>>> bag@path
>>> bag@.things[0].name
>>> bag@Bag.things [0].name
>>> bag.things[0]@.name
>>> bag.things[0]@Thing.name
>> 
>> It sounds like the @ character is serving two different purposes which 
>> confused me at first.
>> 
>> If I understood correctly, you are using it to get the key path but also 
>> to apply the key path to the bag struct and get the corresponding value.
>> 
> 
> Yes. And the initial proposal suggest the following syntax accordingly:
> 
> let path = Bag.things[0].name
> bag[path]
> bag[.things[0].name]
> bag[Bag.things[0].name]
> bag.things[0][.name]
> bag.things[0][Thing.name]
 
 # makes a lot more sense than @ as a sigil.  It follows from #selector and 
 #keyPath.  These are the most similar language features right now where 
 the compiler produces special values.  I think it’s also worth noticing 
 that values produced by #selector and #keyPath are used in normal ways.  
 There is no magic syntax for their use, just a typed value.  If we’re 
 going to make a change we should use # instead of `.` for accessing these 
 special values but we should stick with subscript for use.
 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Ricardo Parada via swift-evolution
Agree.

Another question.  If `Bag` does have a static thing called `myStaticThingy` 
would you refer to it as:

Bag.Type#myStaticThingy

?


> On Mar 22, 2017, at 12:37 PM, Matthew Johnson  wrote:
> 
>> 
>> On Mar 22, 2017, at 11:16 AM, Ricardo Parada > > wrote:
>> 
>> I see three possibilities:
>> 
>> 1) # + «space» +«path» like this:
>> 
>> let path = # Bag.things[0].name
>> bag[path] 
>> bag[# Bag.things[0].name]
>> bag[# .things[0].name]  // Root is inferred as Bag
>> bag.things[0][# Thing.name]
>> bag.things[0][# .name] // Root is inferred as Thing
>> 
>> 2) # + «path» like this::
>> 
>> let path = #Bag.things[0].name
>> bag[path] 
>> bag[#Bag.things[0].name]
>> bag[# .things[0].name]  // Root is inferred as Bag
>> bag.things[0][#Thing.name]
>> bag.things[0][#.name]  // Root is inferred as Thing
>> 
>> 3) «Root» + # + «path» like this: 
>> 
>> let path = Bag#things[0].name
>> bag[path] 
>> bag[Bag#things[0].name]
>> bag[#things[0].name]
>> bag.things[0][#name]
>> bag.things[0][Thing#name]
> 
> I prefer the third option.  I don’t think we should go with the first option. 
>  Allowing (or requiring) a space seems likely to be confusing.  Both the 
> first and the second still have potential to be confusing.  If `Bag` has a 
> static property named `things` people could be confused about what 
> `#Bag.things` refers to.  If we’re going to use a special sigil it should be 
> positioned such that it eliminates potential for that kind of confusion.
> 
>> 
>> 
>> 
>>> On Mar 22, 2017, at 11:47 AM, Matthew Johnson >> > wrote:
>>> 
>>> 
 On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution 
 > wrote:
 
 On 22.03.2017 17:37, Ricardo Parada wrote:
> 
> 
>> On Mar 22, 2017, at 9:30 AM, Vladimir.S > > wrote:
>> 
>> let path = @Bag.things[0].name
>> 
>> bag@path
>> bag@.things[0].name
>> bag@Bag.things [0].name
>> bag.things[0]@.name
>> bag.things[0]@Thing.name
> 
> It sounds like the @ character is serving two different purposes which 
> confused me at first.
> 
> If I understood correctly, you are using it to get the key path but also 
> to apply the key path to the bag struct and get the corresponding value.
> 
 
 Yes. And the initial proposal suggest the following syntax accordingly:
 
 let path = Bag.things[0].name
 bag[path]
 bag[.things[0].name]
 bag[Bag.things[0].name]
 bag.things[0][.name]
 bag.things[0][Thing.name]
>>> 
>>> # makes a lot more sense than @ as a sigil.  It follows from #selector and 
>>> #keyPath.  These are the most similar language features right now where the 
>>> compiler produces special values.  I think it’s also worth noticing that 
>>> values produced by #selector and #keyPath are used in normal ways.  There 
>>> is no magic syntax for their use, just a typed value.  If we’re going to 
>>> make a change we should use # instead of `.` for accessing these special 
>>> values but we should stick with subscript for use.
>>> 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 11:16 AM, Ricardo Parada  wrote:
> 
> I see three possibilities:
> 
> 1) # + «space» +«path» like this:
> 
> let path = # Bag.things[0].name
> bag[path] 
> bag[# Bag.things[0].name]
> bag[# .things[0].name]  // Root is inferred as Bag
> bag.things[0][# Thing.name]
> bag.things[0][# .name] // Root is inferred as Thing
> 
> 2) # + «path» like this::
> 
> let path = #Bag.things[0].name
> bag[path] 
> bag[#Bag.things[0].name]
> bag[# .things[0].name]  // Root is inferred as Bag
> bag.things[0][#Thing.name]
> bag.things[0][#.name]  // Root is inferred as Thing
> 
> 3) «Root» + # + «path» like this: 
> 
> let path = Bag#things[0].name
> bag[path] 
> bag[Bag#things[0].name]
> bag[#things[0].name]
> bag.things[0][#name]
> bag.things[0][Thing#name]

I prefer the third option.  I don’t think we should go with the first option.  
Allowing (or requiring) a space seems likely to be confusing.  Both the first 
and the second still have potential to be confusing.  If `Bag` has a static 
property named `things` people could be confused about what `#Bag.things` 
refers to.  If we’re going to use a special sigil it should be positioned such 
that it eliminates potential for that kind of confusion.

> 
> 
> 
>> On Mar 22, 2017, at 11:47 AM, Matthew Johnson > > wrote:
>> 
>> 
>>> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution 
>>> > wrote:
>>> 
>>> On 22.03.2017 17:37, Ricardo Parada wrote:
 
 
> On Mar 22, 2017, at 9:30 AM, Vladimir.S  > wrote:
> 
> let path = @Bag.things[0].name
> 
> bag@path
> bag@.things[0].name
> bag@Bag.things [0].name
> bag.things[0]@.name
> bag.things[0]@Thing.name
 
 It sounds like the @ character is serving two different purposes which 
 confused me at first.
 
 If I understood correctly, you are using it to get the key path but also 
 to apply the key path to the bag struct and get the corresponding value.
 
>>> 
>>> Yes. And the initial proposal suggest the following syntax accordingly:
>>> 
>>> let path = Bag.things[0].name
>>> bag[path]
>>> bag[.things[0].name]
>>> bag[Bag.things[0].name]
>>> bag.things[0][.name]
>>> bag.things[0][Thing.name]
>> 
>> # makes a lot more sense than @ as a sigil.  It follows from #selector and 
>> #keyPath.  These are the most similar language features right now where the 
>> compiler produces special values.  I think it’s also worth noticing that 
>> values produced by #selector and #keyPath are used in normal ways.  There is 
>> no magic syntax for their use, just a typed value.  If we’re going to make a 
>> change we should use # instead of `.` for accessing these special values but 
>> we should stick with subscript for use.
>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 11:00 AM, Vladimir.S  wrote:
> 
> On 22.03.2017 18:47, Matthew Johnson wrote:
>> 
>>> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution
>>> > wrote:
>>> 
>>> On 22.03.2017 17:37, Ricardo Parada wrote:
 
 
> On Mar 22, 2017, at 9:30 AM, Vladimir.S  > wrote:
> 
> let path = @Bag.things[0].name
> 
> bag@path
> bag@.things[0].name
> bag@Bag.things [0].name
> bag.things[0]@.name
> bag.things[0]@Thing.name
 
 It sounds like the @ character is serving two different purposes which
 confused me at first.
 
 If I understood correctly, you are using it to get the key path but also
 to apply the key path to the bag struct and get the corresponding value.
 
>>> 
>>> Yes. And the initial proposal suggest the following syntax accordingly:
>>> 
>>> let path = Bag.things[0].name
>>> bag[path]
>>> bag[.things[0].name]
>>> bag[Bag.things[0].name]
>>> bag.things[0][.name]
>>> bag.things[0][Thing.name]
>> 
>> # makes a lot more sense than @ as a sigil.  It follows from #selector and
>> #keyPath.  These are the most similar language features right now where the
>> compiler produces special values.  I think it’s also worth noticing that
>> values produced by #selector and #keyPath are /used/ in normal ways.  There
>> is no magic syntax for their use, just a typed value.  If we’re going to
>> make a change we should use # instead of `.` for accessing these special
>> values but we should stick with subscript for use.
> 
> Could you clarify, what do you suggest? Something like this:
> let path = Bag#things[0]#name

I would only use one # at the start of the key path.  Dots could be used 
afterwords like this: `Bag#things[0].name`  I think it is important to use 
normal expression syntax after the key path is introduced.

> bag[#path]

No, you would just say `bag[path]`.  `path` is a normal value and the subscript 
taking a path is a normal subscript.

> bag[#things[0]#name]

Here we have a type context expecting a key path with a root of the type of 
`bag`.  There is no potential ambiguity involved in using the `.` here unless 
people extend the key path types with static members themselves.  I think it’s 
fair to say do that at your own risk.  So there is no need to use special 
synatx - dot shorthand would work just fine with no ambiguity problem.  You 
could imagine the compiler synthesizing static members on key path types like 
this:

extension PartialKeyPath where Root == BagType {
static var things: KeyPath  // or WriteableKeyPath or 
ReferenceWritableKeyPath
}

You just say: `bag[.things[0]#name]` using the existing dot shorthand for 
static members that return a value matching the type they are declared on.

On the other hand, it would be more consistent to introduce # shorthand here 
and not have the imaginary / synthesized static members on the key path types.  
I’m neutral, leaning towards using # shorthand for this.


> bag[Bag#things[0]#name]

As above, there is no need for a second `#`.  Once the expression has produced 
a key path all subsequent chained accesses will also produce a key path.

bag[Bag#things[0].name]

> bag.things[0][#name]

As above, here we have a type context in the subscript that expects a key path. 
 We could use the existing dot shorthand and compiler synthesized static 
properties on key path types or just introduce a # shorthand.  The latter is 
probably better for consistency.

> bag.things[0][Thing#name]

Sure, if you don’t like the shorthand.

> 
> ,and so
> let ref = Bag#foo()

Yep.

One interesting thing to note is that we could also get deep references to 
unbound methods.  This would effectively combine key paths with unbound method 
references:

let doSomething = Bag#things[0].doSomething()

used like this:
doSomthing(bag)

Using # for key paths also allows us to build on it in the future for 
collection operators:

Bag#things[#sum].value //  a key path that sums the value of all things in a bag

Reserving this potential is one important reason to only use # where you are 
introducing a special key path expression and not everywhere in the key path 
chain.

> 
> ?
> 
> In this case I feel like the following will be more clean syntax:
> let path = #Bag.things[0].name
> bag[#path]
> bag[#.things[0].name]
> bag[#Bag.things[0].name]
> bag.things[0][#.name]
> bag.things[0][#Thing.name]
> let ref = #Bag.foo()

This is kind of weird because Bag doesn’t have a static things property.  I 
think it’s better to start put the # in the middle.  That said, this would work 
as well.

> 
> And why subscript is the only good candidate for use?

It is how Swift models parameterized value access.  Building on that model 
makes a ton of sense.  I can’t imagine a compelling argument for using key path 
values.

> Actually, for me 

Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Ricardo Parada via swift-evolution
I see three possibilities:

1) # + «space» +«path» like this:

let path = # Bag.things[0].name
bag[path] 
bag[# Bag.things[0].name]
bag[# .things[0].name]  // Root is inferred as Bag
bag.things[0][# Thing.name]
bag.things[0][# .name] // Root is inferred as Thing

2) # + «path» like this::

let path = #Bag.things[0].name
bag[path] 
bag[#Bag.things[0].name]
bag[# .things[0].name]  // Root is inferred as Bag
bag.things[0][#Thing.name]
bag.things[0][#.name]  // Root is inferred as Thing

3) «Root» + # + «path» like this: 

let path = Bag#things[0].name
bag[path] 
bag[Bag#things[0].name]
bag[#things[0].name]
bag.things[0][#name]
bag.things[0][Thing#name]



> On Mar 22, 2017, at 11:47 AM, Matthew Johnson  wrote:
> 
> 
>> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution 
>> > wrote:
>> 
>> On 22.03.2017 17:37, Ricardo Parada wrote:
>>> 
>>> 
 On Mar 22, 2017, at 9:30 AM, Vladimir.S > wrote:
 
 let path = @Bag.things[0].name
 
 bag@path
 bag@.things[0].name
 bag@Bag.things [0].name
 bag.things[0]@.name
 bag.things[0]@Thing.name
>>> 
>>> It sounds like the @ character is serving two different purposes which 
>>> confused me at first.
>>> 
>>> If I understood correctly, you are using it to get the key path but also to 
>>> apply the key path to the bag struct and get the corresponding value.
>>> 
>> 
>> Yes. And the initial proposal suggest the following syntax accordingly:
>> 
>> let path = Bag.things[0].name
>> bag[path]
>> bag[.things[0].name]
>> bag[Bag.things[0].name]
>> bag.things[0][.name]
>> bag.things[0][Thing.name]
> 
> # makes a lot more sense than @ as a sigil.  It follows from #selector and 
> #keyPath.  These are the most similar language features right now where the 
> compiler produces special values.  I think it’s also worth noticing that 
> values produced by #selector and #keyPath are used in normal ways.  There is 
> no magic syntax for their use, just a typed value.  If we’re going to make a 
> change we should use # instead of `.` for accessing these special values but 
> we should stick with subscript for use.
> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Vladimir.S via swift-evolution

On 22.03.2017 18:47, Matthew Johnson wrote:



On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution
> wrote:

On 22.03.2017 17:37, Ricardo Parada wrote:




On Mar 22, 2017, at 9:30 AM, Vladimir.S > wrote:

let path = @Bag.things[0].name

bag@path
bag@.things[0].name
bag@Bag.things [0].name
bag.things[0]@.name
bag.things[0]@Thing.name


It sounds like the @ character is serving two different purposes which
confused me at first.

If I understood correctly, you are using it to get the key path but also
to apply the key path to the bag struct and get the corresponding value.



Yes. And the initial proposal suggest the following syntax accordingly:

let path = Bag.things[0].name
bag[path]
bag[.things[0].name]
bag[Bag.things[0].name]
bag.things[0][.name]
bag.things[0][Thing.name]


# makes a lot more sense than @ as a sigil.  It follows from #selector and
#keyPath.  These are the most similar language features right now where the
compiler produces special values.  I think it’s also worth noticing that
values produced by #selector and #keyPath are /used/ in normal ways.  There
is no magic syntax for their use, just a typed value.  If we’re going to
make a change we should use # instead of `.` for accessing these special
values but we should stick with subscript for use.


Could you clarify, what do you suggest? Something like this:
let path = Bag#things[0]#name
bag[#path]
bag[#things[0]#name]
bag[Bag#things[0]#name]
bag.things[0][#name]
bag.things[0][Thing#name]

,and so
let ref = Bag#foo()

?

In this case I feel like the following will be more clean syntax:
let path = #Bag.things[0].name
bag[#path]
bag[#.things[0].name]
bag[#Bag.things[0].name]
bag.things[0][#.name]
bag.things[0][#Thing.name]
let ref = #Bag.foo()

And why subscript is the only good candidate for use?
Actually, for me personally, any solution will be good as soon as it 
contains some 'marker' which saying "hey, here key paths are used. be aware."





___
swift-evolution mailing list
swift-evolution@swift.org 
https://lists.swift.org/mailman/listinfo/swift-evolution



___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Matthew Johnson via swift-evolution

> On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 22.03.2017 17:37, Ricardo Parada wrote:
>> 
>> 
>>> On Mar 22, 2017, at 9:30 AM, Vladimir.S  wrote:
>>> 
>>> let path = @Bag.things[0].name
>>> 
>>> bag@path
>>> bag@.things[0].name
>>> bag@Bag.things[0].name
>>> bag.things[0]@.name
>>> bag.things[0]@Thing.name
>> 
>> It sounds like the @ character is serving two different purposes which 
>> confused me at first.
>> 
>> If I understood correctly, you are using it to get the key path but also to 
>> apply the key path to the bag struct and get the corresponding value.
>> 
> 
> Yes. And the initial proposal suggest the following syntax accordingly:
> 
> let path = Bag.things[0].name
> bag[path]
> bag[.things[0].name]
> bag[Bag.things[0].name]
> bag.things[0][.name]
> bag.things[0][Thing.name]

# makes a lot more sense than @ as a sigil.  It follows from #selector and 
#keyPath.  These are the most similar language features right now where the 
compiler produces special values.  I think it’s also worth noticing that values 
produced by #selector and #keyPath are used in normal ways.  There is no magic 
syntax for their use, just a typed value.  If we’re going to make a change we 
should use # instead of `.` for accessing these special values but we should 
stick with subscript for use.

> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Vladimir.S via swift-evolution

On 22.03.2017 17:37, Ricardo Parada wrote:




On Mar 22, 2017, at 9:30 AM, Vladimir.S  wrote:

let path = @Bag.things[0].name

bag@path
bag@.things[0].name
bag@Bag.things[0].name
bag.things[0]@.name
bag.things[0]@Thing.name


It sounds like the @ character is serving two different purposes which confused 
me at first.

If I understood correctly, you are using it to get the key path but also to 
apply the key path to the bag struct and get the corresponding value.



Yes. And the initial proposal suggest the following syntax accordingly:

let path = Bag.things[0].name
bag[path]
bag[.things[0].name]
bag[Bag.things[0].name]
bag.things[0][.name]
bag.things[0][Thing.name]
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Ricardo Parada via swift-evolution


> On Mar 22, 2017, at 9:30 AM, Vladimir.S  wrote:
> 
> let path = @Bag.things[0].name
> 
> bag@path
> bag@.things[0].name
> bag@Bag.things[0].name
> bag.things[0]@.name
> bag.things[0]@Thing.name

It sounds like the @ character is serving two different purposes which confused 
me at first.  

If I understood correctly, you are using it to get the key path but also to 
apply the key path to the bag struct and get the corresponding value. 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-22 Thread Vladimir.S via swift-evolution

On 22.03.2017 6:01, Ricardo Parada via swift-evolution wrote:

Sometimes I feel like we need a winning sigil for this, one that would look 
good, it is not already taken and easy to type in all keyboards.

Maybe we'll have to start looking at emojis :-)


IMO syntax for method references should match the same for key paths, and 
also that both these features desire to be highlighted by that syntax. I 
mean we should understand from first look at code what is happening here.


So my suggestion is to discuss if we can change syntax for method reference 
and apply the same syntax for key paths. Is it worth to discuss this and 
try to 'invent' the best syntax?


For example, '@' operator-like syntax could be proposed:

struct Thing {
var name = ""
}

struct Bag {
func foo() {print("foo")}
var things = [Thing(name:"first")]
}

let ref = @Bag.foo
// probably we should require '()' here to see that this a method ref, not path
//let ref = @Bag.foo()

var bag = Bag()
ref(bag)()

let path = @Bag.things[0].name

bag@path
bag@.things[0].name
bag@Bag.things[0].name
bag.things[0]@.name
bag.things[0]@Thing.name

even these IMO better that just bag[path]
bag@[path]
bag@[.things[0].name]
bag[@path]
bag[@.things[0].name]

IMO it looks and reads("bag at path") well, the syntax is very special, no 
confusion if we access the subscript or the key path, if you ever know 
about method refs or key paths - you see what is happening here. If you 
don't know - you will ask yourself "what does this '@' mean" and have to 
read docs.


Or variant with # modifier:
let ref = #Bag.foo
let path = #Bag.things[0].name
bag#path
bag#.things[0].name
bag#Bag.things[0].name

But it seems I like it less than with @.






On Mar 21, 2017, at 9:13 PM, Matthew Johnson via swift-evolution 
 wrote:



Sent from my iPad


On Mar 21, 2017, at 8:00 PM, Ben Rimmington  wrote:

Re: 


On 21 Mar 2017, at 13:16, Matthew Johnson wrote:

I think the language is best served if all unbound members are accessible using 
the same syntax.  IMO this proposal does the right thing by choosing 
consistency with existing language features.  The current syntax for unbound 
methods works and hasn't caused any confusions I'm aware of in practice.

I don't feel too strongly about what syntax we use as long as it's concise and 
works for accessing all unbound members.  If people want to make the case for 
using `#` instead of `.` to do this I won't object but I won't be a vocal 
advocate either.  However, I think that should be an independent proposal if 
somebody wants to pursue it rather than a bike shed on this proposal which 
would only lead to inconsistency between key paths and unbound methods if it 
succeeds.


A new syntax for key paths and function references could resolve:

* the "compound name syntax for nullary functions" problem;


* the source-breaking change of SE-0042 (if reconsidered for Swift 4);



I would like to see both of these problems resolved.  If somebody put together 
a solid proposal for this I would probably support it (depending on details of 
course).



-- Ben



___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-21 Thread Ricardo Parada via swift-evolution
Sometimes I feel like we need a winning sigil for this, one that would look 
good, it is not already taken and easy to type in all keyboards. 

Maybe we'll have to start looking at emojis :-)



> On Mar 21, 2017, at 9:13 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 21, 2017, at 8:00 PM, Ben Rimmington  wrote:
>> 
>> Re: 
>> 
>>> On 21 Mar 2017, at 13:16, Matthew Johnson wrote:
>>> 
>>> I think the language is best served if all unbound members are accessible 
>>> using the same syntax.  IMO this proposal does the right thing by choosing 
>>> consistency with existing language features.  The current syntax for 
>>> unbound methods works and hasn't caused any confusions I'm aware of in 
>>> practice.  
>>> 
>>> I don't feel too strongly about what syntax we use as long as it's concise 
>>> and works for accessing all unbound members.  If people want to make the 
>>> case for using `#` instead of `.` to do this I won't object but I won't be 
>>> a vocal advocate either.  However, I think that should be an independent 
>>> proposal if somebody wants to pursue it rather than a bike shed on this 
>>> proposal which would only lead to inconsistency between key paths and 
>>> unbound methods if it succeeds.
>> 
>> A new syntax for key paths and function references could resolve:
>> 
>> * the "compound name syntax for nullary functions" problem;
>> 
>> 
>> * the source-breaking change of SE-0042 (if reconsidered for Swift 4);
>> 
> 
> I would like to see both of these problems resolved.  If somebody put 
> together a solid proposal for this I would probably support it (depending on 
> details of course).  
> 
>> 
>> -- Ben
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-21 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Mar 21, 2017, at 8:00 PM, Ben Rimmington  wrote:
> 
> Re: 
> 
>> On 21 Mar 2017, at 13:16, Matthew Johnson wrote:
>> 
>> I think the language is best served if all unbound members are accessible 
>> using the same syntax.  IMO this proposal does the right thing by choosing 
>> consistency with existing language features.  The current syntax for unbound 
>> methods works and hasn't caused any confusions I'm aware of in practice.  
>> 
>> I don't feel too strongly about what syntax we use as long as it's concise 
>> and works for accessing all unbound members.  If people want to make the 
>> case for using `#` instead of `.` to do this I won't object but I won't be a 
>> vocal advocate either.  However, I think that should be an independent 
>> proposal if somebody wants to pursue it rather than a bike shed on this 
>> proposal which would only lead to inconsistency between key paths and 
>> unbound methods if it succeeds.
> 
> A new syntax for key paths and function references could resolve:
> 
> * the "compound name syntax for nullary functions" problem;
>  
> 
> 
> * the source-breaking change of SE-0042 (if reconsidered for Swift 4);
>  
> 

I would like to see both of these problems resolved.  If somebody put together 
a solid proposal for this I would probably support it (depending on details of 
course).  

> 
> -- Ben
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-21 Thread Ben Rimmington via swift-evolution
Re: 

> On 21 Mar 2017, at 13:16, Matthew Johnson wrote:
> 
> I think the language is best served if all unbound members are accessible 
> using the same syntax.  IMO this proposal does the right thing by choosing 
> consistency with existing language features.  The current syntax for unbound 
> methods works and hasn't caused any confusions I'm aware of in practice.  
> 
> I don't feel too strongly about what syntax we use as long as it's concise 
> and works for accessing all unbound members.  If people want to make the case 
> for using `#` instead of `.` to do this I won't object but I won't be a vocal 
> advocate either.  However, I think that should be an independent proposal if 
> somebody wants to pursue it rather than a bike shed on this proposal which 
> would only lead to inconsistency between key paths and unbound methods if it 
> succeeds.

A new syntax for key paths and function references could resolve:

* the "compound name syntax for nullary functions" problem;
  


* the source-breaking change of SE-0042 (if reconsidered for Swift 4);
  


-- Ben

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-21 Thread Haravikk via swift-evolution

> On 21 Mar 2017, at 20:04, David Smith via swift-evolution 
>  wrote:
> 
> 
>> On Mar 20, 2017, at 4:12 AM, David Hart via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> 
>>> +1.  This is my favorite solution so far. 
>>> 
>>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>>> There is no ambiguity for the reader.  With autocomplete it will be very 
>>> little extra typing anyway…
>> 
>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>> too verbose.
> 
> For what it's worth, I'm not especially worried about verbosity. Long-term 
> I'm hoping that this feature and the ones we build on it will see far broader 
> use than keypaths ever did in ObjC, but a little more typing isn't that bad. 
> What *is* a loss though, is something I'll call "conceptual surface area".
> 
> We talk a lot about "conceptual load" when designing APIs, which is the 
> notion that even if each individual concept is simple, the sheer volume of 
> things that you have to keep track of can be exhausting, make learning 
> difficult, and cause mistakes. With some features though, the conceptual load 
> comes more from what isn't there. With unbound methods, you have to know "ok 
> String.init gets me String's initializer as an unbound function I can call, 
> so I can do stuff like [1, 2, 3].map(String.init)" but you *also* have to 
> know "but that doesn't work on subscripts or properties, just methods". So 
> even though there's only one concept here, the hole in the feature is itself 
> an additional concept; an irregularly shaped thing having more mental surface 
> area.
> 
> So the biggest reason I like the current syntax proposal is that it fills in 
> a hole, reducing the conceptual surface area to "ok, Foo.bar gets me an 
> unbound version of anything".
> 
> Unfortunately, as everyone has pointed out, static/class properties make that 
> claim not so true. Hanging keypaths off a ".keypath" class property also 
> conflicts, since there's nothing stopping a method or property from being 
> called "keypath". I see several paths forward from here, not least of which 
> is "it's probably not a huge deal in practice", but I'd like to think about 
> it and listen to the discussion a bit longer before suggesting anything.

Would an operator solve this issue? I have to admit I've never really used 
something like this so I've only really been half-glancing at this thread as 
the messages come up, but it seems like an operator would keep the paths from 
being too verbose, while disambiguating.

This may in fact be something where the dollar sign could be a good fit, i.e: 
$Foo.bar

It's unambiguous with shorthand variables in closures, and keeps the feature in 
the same kind of "sort of compiler magic" category that they exist in, since 
they're not proper variables, but can be used as such, just as a key-path here 
is sort of a property access, but handled in a special way.

Just a thought anyway.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-21 Thread David Smith via swift-evolution

> On Mar 20, 2017, at 4:12 AM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>  wrote:
>> 
>> +1.  This is my favorite solution so far. 
>> 
>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>> There is no ambiguity for the reader.  With autocomplete it will be very 
>> little extra typing anyway…
> 
> But that adds a lot of verbosity. They disregarded #keyPath because it was 
> too verbose.

For what it's worth, I'm not especially worried about verbosity. Long-term I'm 
hoping that this feature and the ones we build on it will see far broader use 
than keypaths ever did in ObjC, but a little more typing isn't that bad. What 
*is* a loss though, is something I'll call "conceptual surface area".

We talk a lot about "conceptual load" when designing APIs, which is the notion 
that even if each individual concept is simple, the sheer volume of things that 
you have to keep track of can be exhausting, make learning difficult, and cause 
mistakes. With some features though, the conceptual load comes more from what 
isn't there. With unbound methods, you have to know "ok String.init gets me 
String's initializer as an unbound function I can call, so I can do stuff like 
[1, 2, 3].map(String.init)" but you *also* have to know "but that doesn't work 
on subscripts or properties, just methods". So even though there's only one 
concept here, the hole in the feature is itself an additional concept; an 
irregularly shaped thing having more mental surface area.

So the biggest reason I like the current syntax proposal is that it fills in a 
hole, reducing the conceptual surface area to "ok, Foo.bar gets me an unbound 
version of anything".

Unfortunately, as everyone has pointed out, static/class properties make that 
claim not so true. Hanging keypaths off a ".keypath" class property also 
conflicts, since there's nothing stopping a method or property from being 
called "keypath". I see several paths forward from here, not least of which is 
"it's probably not a huge deal in practice", but I'd like to think about it and 
listen to the discussion a bit longer before suggesting anything.

David

> 
>> Thanks,
>> Jon
>> 
>>> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>>>  wrote:
>>> 
>>> Key paths of this form:
>>> 
>>> Person.name
>>> 
>>> will always make it harder than necessary to:
>>> 
>>> * search for all places where we are using key paths
>>> 
>>> * do efficient code completion. Eg you’ll get a mix of static properties 
>>> and key paths
>>> 
>>> 
>>> We’ve been using this kind of setup in our projects for some time now:
>>> 
>>> class Person {
>>> 
>>> struct keypath {
>>> 
>>>static let name = #keyPath(Person.name)
>>>…
>>> }
>>> 
>>> …
>>> }
>>> 
>>> where a keypath is then used like this:
>>> 
>>> Person.keypath.name
>>> 
>>> and this has worked very well. It makes it easy to see where we are using a 
>>> keypath rather than accessing some static property, it works very nicely 
>>> with code completion and it makes it very easy to search for all places 
>>> where we are using key paths from the Person type.
>>> 
>>> I would prefer that the proposed keypath model would automatically organize 
>>> key paths like this.
>>> 
>>> 
>>> Regards,
>>> 
>>> Dietmar Planitzer
>>> 
>>> 
 On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
  wrote:
 
 
 
 Sent from my iPad
 
> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
> I think the clarity desired is more similar to that obtained by the `try` 
> keyword. Ya, the compiler knows that this function throws already, but 
> Swift aims for clarity in the source code. Clarity is often achieved by 
> providing potentially redundant information for the programmer.
> 
> As proposed, it is difficult to distinguish a key path from a static 
> variable. Maybe that's not problematic? Well, it's up to the community to 
> decide.
 
 Why don't we just say all instance properties are shadowed by a static 
 constant property of the same name with the appropriate key path type.  
 This makes it not mysterious at all but instead very straightforward.  We 
 could even say that static and class properties are shadowed by a key path 
 property on the meta type.
 
 
> I do think it is a bit worrisome that static variable access might cause 
> side effects (or at least, might take a while to compute) but creating 
> key paths should not, but that's a fringe case probably.
> 
> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 4:47 PM, Charles Srstka 

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Charles Srstka via swift-evolution
Ah, yes, that would be annoying if editing .xib files caused SourceKitService 
dialogs to pop up every five seconds, the way editing .swift files does.

Charles

> On Mar 20, 2017, at 9:39 PM, Kenny Leung via swift-evolution 
>  wrote:
> 
> Wouldn’t this require the Swift compiler and the original binary to work 
> properly?
> 
> -Kenny
> 
> 
>> On Mar 20, 2017, at 6:52 PM, Ricardo Parada  wrote:
>> 
>> That is very interesting: "formatting templates that are well typed."
>> 
>> Would that be like a template and keypaths that were archived to a file, 
>> similar to a .nib file?
>> 
>> 
>>> On Mar 20, 2017, at 7:28 PM, Joe Groff via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Mar 20, 2017, at 4:01 PM, Kenny Leung via swift-evolution 
  wrote:
 
 Hi All.
 
 I’m not sure I’m understanding this proposal properly. In (old) Cocoa, two 
 places where key paths were used extensively was EOF/CoreData, and 
 WebObjects. I’m wondering how Smart KeyPaths will solve these two problems:
 
 1. fetching data from a database and stuff it into objects that are not 
 known at compile time (since you’ve written the framework ahead of time)
 
 2. Token replacing text in a template, like ${person.firstName}
 
 Will there be some conversion of key paths to/from strings?
>>> 
>>> There won't be a conversion from strings in this initial proposal. That 
>>> would be a reasonable thing to add later. For the use case of formatting 
>>> strings, hopefully, there'll eventually be some way to build formatting 
>>> templates that are well-typed instead of relying on parsing strings at 
>>> runtime.
>>> 
>>> -Joe
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Kenny Leung via swift-evolution
Wouldn’t this require the Swift compiler and the original binary to work 
properly?

-Kenny


> On Mar 20, 2017, at 6:52 PM, Ricardo Parada  wrote:
> 
> That is very interesting: "formatting templates that are well typed."
> 
> Would that be like a template and keypaths that were archived to a file, 
> similar to a .nib file?
> 
> 
>> On Mar 20, 2017, at 7:28 PM, Joe Groff via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Mar 20, 2017, at 4:01 PM, Kenny Leung via swift-evolution 
>>>  wrote:
>>> 
>>> Hi All.
>>> 
>>> I’m not sure I’m understanding this proposal properly. In (old) Cocoa, two 
>>> places where key paths were used extensively was EOF/CoreData, and 
>>> WebObjects. I’m wondering how Smart KeyPaths will solve these two problems:
>>> 
>>> 1. fetching data from a database and stuff it into objects that are not 
>>> known at compile time (since you’ve written the framework ahead of time)
>>> 
>>> 2. Token replacing text in a template, like ${person.firstName}
>>> 
>>> Will there be some conversion of key paths to/from strings?
>> 
>> There won't be a conversion from strings in this initial proposal. That 
>> would be a reasonable thing to add later. For the use case of formatting 
>> strings, hopefully, there'll eventually be some way to build formatting 
>> templates that are well-typed instead of relying on parsing strings at 
>> runtime.
>> 
>> -Joe
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Ricardo Parada via swift-evolution
That is very interesting: "formatting templates that are well typed."

Would that be like a template and keypaths that were archived to a file, 
similar to a .nib file?


> On Mar 20, 2017, at 7:28 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 20, 2017, at 4:01 PM, Kenny Leung via swift-evolution 
>>  wrote:
>> 
>> Hi All.
>> 
>> I’m not sure I’m understanding this proposal properly. In (old) Cocoa, two 
>> places where key paths were used extensively was EOF/CoreData, and 
>> WebObjects. I’m wondering how Smart KeyPaths will solve these two problems:
>> 
>> 1. fetching data from a database and stuff it into objects that are not 
>> known at compile time (since you’ve written the framework ahead of time)
>> 
>> 2. Token replacing text in a template, like ${person.firstName}
>> 
>> Will there be some conversion of key paths to/from strings?
> 
> There won't be a conversion from strings in this initial proposal. That would 
> be a reasonable thing to add later. For the use case of formatting strings, 
> hopefully, there'll eventually be some way to build formatting templates that 
> are well-typed instead of relying on parsing strings at runtime.
> 
> -Joe
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Joe Groff via swift-evolution

> On Mar 20, 2017, at 4:01 PM, Kenny Leung via swift-evolution 
>  wrote:
> 
> Hi All.
> 
> I’m not sure I’m understanding this proposal properly. In (old) Cocoa, two 
> places where key paths were used extensively was EOF/CoreData, and 
> WebObjects. I’m wondering how Smart KeyPaths will solve these two problems:
> 
> 1. fetching data from a database and stuff it into objects that are not known 
> at compile time (since you’ve written the framework ahead of time)
> 
> 2. Token replacing text in a template, like ${person.firstName}
> 
> Will there be some conversion of key paths to/from strings?

There won't be a conversion from strings in this initial proposal. That would 
be a reasonable thing to add later. For the use case of formatting strings, 
hopefully, there'll eventually be some way to build formatting templates that 
are well-typed instead of relying on parsing strings at runtime.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Kenny Leung via swift-evolution
Hi All.

I’m not sure I’m understanding this proposal properly. In (old) Cocoa, two 
places where key paths were used extensively was EOF/CoreData, and WebObjects. 
I’m wondering how Smart KeyPaths will solve these two problems:

1. fetching data from a database and stuff it into objects that are not known 
at compile time (since you’ve written the framework ahead of time)

2. Token replacing text in a template, like ${person.firstName}

Will there be some conversion of key paths to/from strings?

Thanks!

-Kenny


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Charles Srstka via swift-evolution
> On Mar 20, 2017, at 9:23 AM, Christopher Kornher via swift-evolution 
>  wrote:
> 
>> On Mar 20, 2017, at 5:12 AM, David Hart via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>> > wrote:
>>> 
>>> +1.  This is my favorite solution so far. 
>>> 
>>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>>> There is no ambiguity for the reader.  With autocomplete it will be very 
>>> little extra typing anyway…
>> 
>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>> too verbose.
> 
> The syntax in the original proposal is terse and elegant, and will probably 
> be fine when a developer who is experienced with Swift and a particular 
> codebase is first writing the code. Using “key path” or “keypaths” of perhaps 
> a shorter term or even a single leading character (`#` ?) will make this 
> feature more discoverable, tool-friendly and its usages more maintainable.
> 
> An extra term or character does add verbosity. How much is subjective, but I 
> would not call it “a lot”. It does not add any nesting or code complexity. 
> KVO code is usually a small fraction of most Objective-C projects (in my 
> experience, at least) and it is probably safe to assume that the usage of 
> this feature in Swift will be similar.
> 
> Verbosity vs clarity is often a tradeoff and I think that on balance, for a 
> feature like this a little extra verbosity is worth it. Swift does not have 
> the most terse syntax possible. `++` was removed, for example.
> 
> Just because an assignment is already implicitly typed in Swift does not mean 
> that the ambiguity has to keep increasing without end for implementation of 
> all new features, especially for ones that are not used very frequently.

+1 to all of this.

Particularly the point that KVO code typically is a small portion of the 
overall code; this not only makes the added verbosity not that 
egregious—certainly less so than “try” or “override”—but it also underscores 
the fact that as a relatively uncommon feature, it’s not what a reader of the 
code is going to be expecting to see. This latter point is why I feel that 
without some kind of additional syntax—even if it’s just one character—key 
paths will frequently get mistaken for property accesses if they are 
implemented this way.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Matthew Johnson via swift-evolution

> On Mar 20, 2017, at 9:23 AM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> 
> 
>> On Mar 20, 2017, at 5:12 AM, David Hart via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> 
>>> +1.  This is my favorite solution so far. 
>>> 
>>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>>> There is no ambiguity for the reader.  With autocomplete it will be very 
>>> little extra typing anyway…
>> 
>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>> too verbose.
> 
> The syntax in the original proposal is terse and elegant, and will probably 
> be fine when a developer who is experienced with Swift and a particular 
> codebase is first writing the code. Using “key path” or “keypaths” of perhaps 
> a shorter term or even a single leading character (`#` ?) will make this 
> feature more discoverable, tool-friendly and its usages more maintainable.

It also makes it inconsistent with how unbound methods behave.  I have yet to 
hear a convincing argument about why key paths should be treated different 
syntactically.

> 
> An extra term or character does add verbosity. How much is subjective, but I 
> would not call it “a lot”. It does not add any nesting or code complexity. 
> KVO code is usually a small fraction of most Objective-C projects (in my 
> experience, at least) and it is probably safe to assume that the usage of 
> this feature in Swift will be similar.
> 
> Verbosity vs clarity is often a tradeoff and I think that on balance, for a 
> feature like this a little extra verbosity is worth it. Swift does not have 
> the most terse syntax possible. `++` was removed, for example.
> 
> Just because an assignment is already implicitly typed in Swift does not mean 
> that the ambiguity has to keep increasing without end for implementation of 
> all new features, especially for ones that are not used very frequently.
> 
> 
>> 
>>> Thanks,
>>> Jon
>>> 
 On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
  wrote:
 
 Key paths of this form:
 
 Person.name
 
 will always make it harder than necessary to:
 
 * search for all places where we are using key paths
 
 * do efficient code completion. Eg you’ll get a mix of static properties 
 and key paths
 
 
 We’ve been using this kind of setup in our projects for some time now:
 
 class Person {
 
 struct keypath {
 
   static let name = #keyPath(Person.name)
   …
 }
 
 …
 }
 
 where a keypath is then used like this:
 
 Person.keypath.name
 
 and this has worked very well. It makes it easy to see where we are using 
 a keypath rather than accessing some static property, it works very nicely 
 with code completion and it makes it very easy to search for all places 
 where we are using key paths from the Person type.
 
 I would prefer that the proposed keypath model would automatically 
 organize key paths like this.
 
 
 Regards,
 
 Dietmar Planitzer
 
 
> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>  wrote:
>> 
>> I think the clarity desired is more similar to that obtained by the 
>> `try` keyword. Ya, the compiler knows that this function throws already, 
>> but Swift aims for clarity in the source code. Clarity is often achieved 
>> by providing potentially redundant information for the programmer.
>> 
>> As proposed, it is difficult to distinguish a key path from a static 
>> variable. Maybe that's not problematic? Well, it's up to the community 
>> to decide.
> 
> Why don't we just say all instance properties are shadowed by a static 
> constant property of the same name with the appropriate key path type.  
> This makes it not mysterious at all but instead very straightforward.  We 
> could even say that static and class properties are shadowed by a key 
> path property on the meta type.
> 
> 
>> I do think it is a bit worrisome that static variable access might cause 
>> side effects (or at least, might take a while to compute) but creating 
>> key paths should not, but that's a fringe case probably.
>> 
>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
 On Mar 19, 2017, at 4:47 PM, Charles Srstka  
 wrote:
 
> This is true of many things.  It is why IDEs make type information 
> 

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Christopher Kornher via swift-evolution


> On Mar 20, 2017, at 5:12 AM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>  wrote:
>> 
>> +1.  This is my favorite solution so far. 
>> 
>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>> There is no ambiguity for the reader.  With autocomplete it will be very 
>> little extra typing anyway…
> 
> But that adds a lot of verbosity. They disregarded #keyPath because it was 
> too verbose.

The syntax in the original proposal is terse and elegant, and will probably be 
fine when a developer who is experienced with Swift and a particular codebase 
is first writing the code. Using “key path” or “keypaths” of perhaps a shorter 
term or even a single leading character (`#` ?) will make this feature more 
discoverable, tool-friendly and its usages more maintainable.

An extra term or character does add verbosity. How much is subjective, but I 
would not call it “a lot”. It does not add any nesting or code complexity. KVO 
code is usually a small fraction of most Objective-C projects (in my 
experience, at least) and it is probably safe to assume that the usage of this 
feature in Swift will be similar.

Verbosity vs clarity is often a tradeoff and I think that on balance, for a 
feature like this a little extra verbosity is worth it. Swift does not have the 
most terse syntax possible. `++` was removed, for example.

Just because an assignment is already implicitly typed in Swift does not mean 
that the ambiguity has to keep increasing without end for implementation of all 
new features, especially for ones that are not used very frequently.


> 
>> Thanks,
>> Jon
>> 
>>> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>>>  wrote:
>>> 
>>> Key paths of this form:
>>> 
>>> Person.name
>>> 
>>> will always make it harder than necessary to:
>>> 
>>> * search for all places where we are using key paths
>>> 
>>> * do efficient code completion. Eg you’ll get a mix of static properties 
>>> and key paths
>>> 
>>> 
>>> We’ve been using this kind of setup in our projects for some time now:
>>> 
>>> class Person {
>>> 
>>> struct keypath {
>>> 
>>>static let name = #keyPath(Person.name)
>>>…
>>> }
>>> 
>>> …
>>> }
>>> 
>>> where a keypath is then used like this:
>>> 
>>> Person.keypath.name
>>> 
>>> and this has worked very well. It makes it easy to see where we are using a 
>>> keypath rather than accessing some static property, it works very nicely 
>>> with code completion and it makes it very easy to search for all places 
>>> where we are using key paths from the Person type.
>>> 
>>> I would prefer that the proposed keypath model would automatically organize 
>>> key paths like this.
>>> 
>>> 
>>> Regards,
>>> 
>>> Dietmar Planitzer
>>> 
>>> 
 On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
  wrote:
 
 
 
 Sent from my iPad
 
> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
> I think the clarity desired is more similar to that obtained by the `try` 
> keyword. Ya, the compiler knows that this function throws already, but 
> Swift aims for clarity in the source code. Clarity is often achieved by 
> providing potentially redundant information for the programmer.
> 
> As proposed, it is difficult to distinguish a key path from a static 
> variable. Maybe that's not problematic? Well, it's up to the community to 
> decide.
 
 Why don't we just say all instance properties are shadowed by a static 
 constant property of the same name with the appropriate key path type.  
 This makes it not mysterious at all but instead very straightforward.  We 
 could even say that static and class properties are shadowed by a key path 
 property on the meta type.
 
 
> I do think it is a bit worrisome that static variable access might cause 
> side effects (or at least, might take a while to compute) but creating 
> key paths should not, but that's a fringe case probably.
> 
> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
>>> wrote:
>>> 
 This is true of many things.  It is why IDEs make type information 
 readily available.
>>> 
>>> Is clarity not a thing to be desired?
>> 
>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>> 
>>   sum :: (Num a, Foldable t) => t a -> a
>>   sum = foldl (+) 0
>> 
>> Here's another:
>> 
>>   int sum(int array[], size_t len) {
>>   int total = 0;
>>   for(size_t i = 0; i < len; i++) {
>>   total += array[i];

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Ricardo Parada via swift-evolution
I like it the way they have it in the proposal because it is consistent with 
referencing methods and initializers. 

And as mentioned previously it can be disambiguated on the edge cases. 



> On Mar 20, 2017, at 9:11 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Mar 20, 2017, at 6:18 AM, Rien via swift-evolution 
>  wrote:
> 
>>> 
>>> On 20 Mar 2017, at 12:12, David Hart via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
 On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
  wrote:
 
 +1.  This is my favorite solution so far. 
 
 With ‘Person.keypath.name' it is obvious that we are creating a key path.  
 There is no ambiguity for the reader.  With autocomplete it will be very 
 little extra typing anyway…
>>> 
>>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>>> too verbose.
>>> 
>> 
>> Then let me add a +1 for the verbose solution as well.
>> 
>> Sometimes verbosity is not bad.
> 
> Huge -1 from me.  What we do should be consistent with unbound methods.  This 
> idea should need to justify why the inconsistency (or changing unbound 
> methods - a breaking change) is worth the benefit you perceive.  I think 
> that's a pretty tough sell.
> 
> If we did go with the verbose option I hope the dot shorthand that only 
> requires a property name would still work in a type context expecting a key 
> path with a concrete root type.
> 
>> 
>> Regards,
>> Rien
>> 
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl
>> 
 Thanks,
 Jon
 
> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>  wrote:
> 
> Key paths of this form:
> 
> Person.name
> 
> will always make it harder than necessary to:
> 
> * search for all places where we are using key paths
> 
> * do efficient code completion. Eg you’ll get a mix of static properties 
> and key paths
> 
> 
> We’ve been using this kind of setup in our projects for some time now:
> 
> class Person {
> 
> struct keypath {
> 
>  static let name = #keyPath(Person.name)
>  …
> }
> 
> …
> }
> 
> where a keypath is then used like this:
> 
> Person.keypath.name
> 
> and this has worked very well. It makes it easy to see where we are using 
> a keypath rather than accessing some static property, it works very 
> nicely with code completion and it makes it very easy to search for all 
> places where we are using key paths from the Person type.
> 
> I would prefer that the proposed keypath model would automatically 
> organize key paths like this.
> 
> 
> Regards,
> 
> Dietmar Planitzer
> 
> 
>> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>>  wrote:
>>> 
>>> I think the clarity desired is more similar to that obtained by the 
>>> `try` keyword. Ya, the compiler knows that this function throws 
>>> already, but Swift aims for clarity in the source code. Clarity is 
>>> often achieved by providing potentially redundant information for the 
>>> programmer.
>>> 
>>> As proposed, it is difficult to distinguish a key path from a static 
>>> variable. Maybe that's not problematic? Well, it's up to the community 
>>> to decide.
>> 
>> Why don't we just say all instance properties are shadowed by a static 
>> constant property of the same name with the appropriate key path type.  
>> This makes it not mysterious at all but instead very straightforward.  
>> We could even say that static and class properties are shadowed by a key 
>> path property on the meta type.
>> 
>> 
>>> I do think it is a bit worrisome that static variable access might 
>>> cause side effects (or at least, might take a while to compute) but 
>>> creating key paths should not, but that's a fringe case probably.
>>> 
>>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
> On Mar 19, 2017, at 4:47 PM, Charles Srstka 
>  wrote:
> 
>> This is true of many things.  It is why IDEs make type information 
>> readily available.
> 
> Is clarity not a thing to be desired?
 
 Clarity is in the eye of the beholder. Here's one notion of clarity:
 
 sum :: (Num a, Foldable t) => t a -> a

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Mar 20, 2017, at 6:18 AM, Rien via swift-evolution 
 wrote:

>> 
>> On 20 Mar 2017, at 12:12, David Hart via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> 
>>> +1.  This is my favorite solution so far. 
>>> 
>>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>>> There is no ambiguity for the reader.  With autocomplete it will be very 
>>> little extra typing anyway…
>> 
>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>> too verbose.
>> 
> 
> Then let me add a +1 for the verbose solution as well.
> 
> Sometimes verbosity is not bad.

Huge -1 from me.  What we do should be consistent with unbound methods.  This 
idea should need to justify why the inconsistency (or changing unbound methods 
- a breaking change) is worth the benefit you perceive.  I think that's a 
pretty tough sell.

If we did go with the verbose option I hope the dot shorthand that only 
requires a property name would still work in a type context expecting a key 
path with a concrete root type.

> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl
> 
>>> Thanks,
>>> Jon
>>> 
 On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
  wrote:
 
 Key paths of this form:
 
 Person.name
 
 will always make it harder than necessary to:
 
 * search for all places where we are using key paths
 
 * do efficient code completion. Eg you’ll get a mix of static properties 
 and key paths
 
 
 We’ve been using this kind of setup in our projects for some time now:
 
 class Person {
 
 struct keypath {
 
   static let name = #keyPath(Person.name)
   …
 }
 
 …
 }
 
 where a keypath is then used like this:
 
 Person.keypath.name
 
 and this has worked very well. It makes it easy to see where we are using 
 a keypath rather than accessing some static property, it works very nicely 
 with code completion and it makes it very easy to search for all places 
 where we are using key paths from the Person type.
 
 I would prefer that the proposed keypath model would automatically 
 organize key paths like this.
 
 
 Regards,
 
 Dietmar Planitzer
 
 
> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>  wrote:
>> 
>> I think the clarity desired is more similar to that obtained by the 
>> `try` keyword. Ya, the compiler knows that this function throws already, 
>> but Swift aims for clarity in the source code. Clarity is often achieved 
>> by providing potentially redundant information for the programmer.
>> 
>> As proposed, it is difficult to distinguish a key path from a static 
>> variable. Maybe that's not problematic? Well, it's up to the community 
>> to decide.
> 
> Why don't we just say all instance properties are shadowed by a static 
> constant property of the same name with the appropriate key path type.  
> This makes it not mysterious at all but instead very straightforward.  We 
> could even say that static and class properties are shadowed by a key 
> path property on the meta type.
> 
> 
>> I do think it is a bit worrisome that static variable access might cause 
>> side effects (or at least, might take a while to compute) but creating 
>> key paths should not, but that's a fringe case probably.
>> 
>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
 On Mar 19, 2017, at 4:47 PM, Charles Srstka  
 wrote:
 
> This is true of many things.  It is why IDEs make type information 
> readily available.
 
 Is clarity not a thing to be desired?
>>> 
>>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>>> 
>>>  sum :: (Num a, Foldable t) => t a -> a
>>>  sum = foldl (+) 0
>>> 
>>> Here's another:
>>> 
>>>  int sum(int array[], size_t len) {
>>>  int total = 0;
>>>  for(size_t i = 0; i < len; i++) {
>>>  total += array[i];
>>>  }
>>>  return total;
>>>  }
>>> 
>>> And another:
>>> 
>>>  SUM PROC
>>>   ; this procedure will calculate the sum of an array
>>>   ; input : SI=offset address of the array
>>>   ;   : 

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Mar 19, 2017, at 11:02 PM, jaden.gel...@gmail.com wrote:
> 
> You mean overloaded, not shadowed, right?

No.  What I mean by shadowed is this:

struct Foo {
   // you write this:
   let bar: Int
   
   // compiler automatically synthesizes a static keypath:
   static let bar: KeyPath
}

Shadowed was perhaps a bad word to use.  :)

> 
>> On Mar 19, 2017, at 8:49 PM, Matthew Johnson  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>>  wrote:
>>> 
>>> I think the clarity desired is more similar to that obtained by the `try` 
>>> keyword. Ya, the compiler knows that this function throws already, but 
>>> Swift aims for clarity in the source code. Clarity is often achieved by 
>>> providing potentially redundant information for the programmer.
>>> 
>>> As proposed, it is difficult to distinguish a key path from a static 
>>> variable. Maybe that's not problematic? Well, it's up to the community to 
>>> decide.
>> 
>> Why don't we just say all instance properties are shadowed by a static 
>> constant property of the same name with the appropriate key path type.  This 
>> makes it not mysterious at all but instead very straightforward.  We could 
>> even say that static and class properties are shadowed by a key path 
>> property on the meta type.
>> 
>> 
>>> I do think it is a bit worrisome that static variable access might cause 
>>> side effects (or at least, might take a while to compute) but creating key 
>>> paths should not, but that's a fringe case probably.
>>> 
 On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
  wrote:
 
>> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
>> wrote:
>> 
>> This is true of many things.  It is why IDEs make type information 
>> readily available.
> 
> Is clarity not a thing to be desired?
 
 Clarity is in the eye of the beholder. Here's one notion of clarity:
 
sum :: (Num a, Foldable t) => t a -> a
sum = foldl (+) 0
 
 Here's another:
 
int sum(int array[], size_t len) {
int total = 0;
for(size_t i = 0; i < len; i++) {
total += array[i];
}
return total;
}
 
 And another:
 
SUM PROC
 ; this procedure will calculate the sum of an array
 ; input : SI=offset address of the array
 ;   : BX=size of the array
 ; output : AX=sum of the array
 
 PUSH CX; push CX onto the STACK
 PUSH DX; push DX onto the STACK
 
 XOR AX, AX ; clear AX
 XOR DX, DX ; clear DX
 MOV CX, BX ; set CX=BX
 
 @SUM:  ; loop label
   MOV DL, [SI] ; set DL=[SI]
   ADD AX, DX   ; set AX=AX+DX
   INC SI   ; set SI=SI+1
 LOOP @SUM  ; jump to label @SUM while CX!=0
 
 POP DX ; pop a value from STACK into DX
 POP CX ; pop a value from STACK into CX
 
 RET; return control to the calling 
 procedure
SUM ENDP
 
 And one more:
 
extension Sequence where Element: Arithmetic {
func sum() {
return reduce(0, +)
}
}
 
 Clarity is not achieved by explicitly stating every detail of your code. 
 It's achieved by explicitly stating what needs to be said, and *not* 
 explicitly stating what *doesn't* need to be said.
 
 The people who oppose using a special syntax for this feature think that, 
 by and large, clarity is best served by *not* explicitly stating when 
 you're using a key path. They believe that you are unlikely to run into 
 ambiguity and, when you do, it will be easy to work around it. This is an 
 opinion, so it's open to disagreement, but that's where they stand on it.
 
 -- 
 Brent Royal-Gordon
 Architechies
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Rien via swift-evolution
> 
> On 20 Mar 2017, at 12:12, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>  wrote:
>> 
>> +1.  This is my favorite solution so far. 
>> 
>> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
>> There is no ambiguity for the reader.  With autocomplete it will be very 
>> little extra typing anyway…
> 
> But that adds a lot of verbosity. They disregarded #keyPath because it was 
> too verbose.
> 

Then let me add a +1 for the verbose solution as well.

Sometimes verbosity is not bad.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl

>> Thanks,
>> Jon
>> 
>>> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>>>  wrote:
>>> 
>>> Key paths of this form:
>>> 
>>> Person.name
>>> 
>>> will always make it harder than necessary to:
>>> 
>>> * search for all places where we are using key paths
>>> 
>>> * do efficient code completion. Eg you’ll get a mix of static properties 
>>> and key paths
>>> 
>>> 
>>> We’ve been using this kind of setup in our projects for some time now:
>>> 
>>> class Person {
>>> 
>>> struct keypath {
>>> 
>>>static let name = #keyPath(Person.name)
>>>…
>>> }
>>> 
>>> …
>>> }
>>> 
>>> where a keypath is then used like this:
>>> 
>>> Person.keypath.name
>>> 
>>> and this has worked very well. It makes it easy to see where we are using a 
>>> keypath rather than accessing some static property, it works very nicely 
>>> with code completion and it makes it very easy to search for all places 
>>> where we are using key paths from the Person type.
>>> 
>>> I would prefer that the proposed keypath model would automatically organize 
>>> key paths like this.
>>> 
>>> 
>>> Regards,
>>> 
>>> Dietmar Planitzer
>>> 
>>> 
 On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
  wrote:
 
 
 
 Sent from my iPad
 
> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
> I think the clarity desired is more similar to that obtained by the `try` 
> keyword. Ya, the compiler knows that this function throws already, but 
> Swift aims for clarity in the source code. Clarity is often achieved by 
> providing potentially redundant information for the programmer.
> 
> As proposed, it is difficult to distinguish a key path from a static 
> variable. Maybe that's not problematic? Well, it's up to the community to 
> decide.
 
 Why don't we just say all instance properties are shadowed by a static 
 constant property of the same name with the appropriate key path type.  
 This makes it not mysterious at all but instead very straightforward.  We 
 could even say that static and class properties are shadowed by a key path 
 property on the meta type.
 
 
> I do think it is a bit worrisome that static variable access might cause 
> side effects (or at least, might take a while to compute) but creating 
> key paths should not, but that's a fringe case probably.
> 
> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
>>> wrote:
>>> 
 This is true of many things.  It is why IDEs make type information 
 readily available.
>>> 
>>> Is clarity not a thing to be desired?
>> 
>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>> 
>>   sum :: (Num a, Foldable t) => t a -> a
>>   sum = foldl (+) 0
>> 
>> Here's another:
>> 
>>   int sum(int array[], size_t len) {
>>   int total = 0;
>>   for(size_t i = 0; i < len; i++) {
>>   total += array[i];
>>   }
>>   return total;
>>   }
>> 
>> And another:
>> 
>>   SUM PROC
>>; this procedure will calculate the sum of an array
>>; input : SI=offset address of the array
>>;   : BX=size of the array
>>; output : AX=sum of the array
>> 
>>PUSH CX; push CX onto the STACK
>>PUSH DX; push DX onto the STACK
>> 
>>XOR AX, AX ; clear AX
>>XOR DX, DX ; clear DX
>>MOV CX, BX ; set CX=BX
>> 
>>@SUM:  ; loop label
>>  MOV DL, [SI] ; set DL=[SI]
>>  ADD AX, DX   ; set AX=AX+DX
>>  INC SI   ; set SI=SI+1
>>LOOP @SUM  ; jump to label @SUM while CX!=0
>> 
>>POP DX   

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread David Hart via swift-evolution


> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>  wrote:
> 
> +1.  This is my favorite solution so far. 
> 
> With ‘Person.keypath.name' it is obvious that we are creating a key path.  
> There is no ambiguity for the reader.  With autocomplete it will be very 
> little extra typing anyway…

But that adds a lot of verbosity. They disregarded #keyPath because it was too 
verbose.

> Thanks,
> Jon
> 
>> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>>  wrote:
>> 
>> Key paths of this form:
>> 
>> Person.name
>> 
>> will always make it harder than necessary to:
>> 
>> * search for all places where we are using key paths
>> 
>> * do efficient code completion. Eg you’ll get a mix of static properties and 
>> key paths
>> 
>> 
>> We’ve been using this kind of setup in our projects for some time now:
>> 
>> class Person {
>> 
>>  struct keypath {
>> 
>> static let name = #keyPath(Person.name)
>> …
>>  }
>> 
>>  …
>> }
>> 
>> where a keypath is then used like this:
>> 
>> Person.keypath.name
>> 
>> and this has worked very well. It makes it easy to see where we are using a 
>> keypath rather than accessing some static property, it works very nicely 
>> with code completion and it makes it very easy to search for all places 
>> where we are using key paths from the Person type.
>> 
>> I would prefer that the proposed keypath model would automatically organize 
>> key paths like this.
>> 
>> 
>> Regards,
>> 
>> Dietmar Planitzer
>> 
>> 
>>> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
>>> Sent from my iPad
>>> 
 On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
  wrote:
 
 I think the clarity desired is more similar to that obtained by the `try` 
 keyword. Ya, the compiler knows that this function throws already, but 
 Swift aims for clarity in the source code. Clarity is often achieved by 
 providing potentially redundant information for the programmer.
 
 As proposed, it is difficult to distinguish a key path from a static 
 variable. Maybe that's not problematic? Well, it's up to the community to 
 decide.
>>> 
>>> Why don't we just say all instance properties are shadowed by a static 
>>> constant property of the same name with the appropriate key path type.  
>>> This makes it not mysterious at all but instead very straightforward.  We 
>>> could even say that static and class properties are shadowed by a key path 
>>> property on the meta type.
>>> 
>>> 
 I do think it is a bit worrisome that static variable access might cause 
 side effects (or at least, might take a while to compute) but creating key 
 paths should not, but that's a fringe case probably.
 
 On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
  wrote:
 
>> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
>> wrote:
>> 
>>> This is true of many things.  It is why IDEs make type information 
>>> readily available.
>> 
>> Is clarity not a thing to be desired?
> 
> Clarity is in the eye of the beholder. Here's one notion of clarity:
> 
>sum :: (Num a, Foldable t) => t a -> a
>sum = foldl (+) 0
> 
> Here's another:
> 
>int sum(int array[], size_t len) {
>int total = 0;
>for(size_t i = 0; i < len; i++) {
>total += array[i];
>}
>return total;
>}
> 
> And another:
> 
>SUM PROC
> ; this procedure will calculate the sum of an array
> ; input : SI=offset address of the array
> ;   : BX=size of the array
> ; output : AX=sum of the array
> 
> PUSH CX; push CX onto the STACK
> PUSH DX; push DX onto the STACK
> 
> XOR AX, AX ; clear AX
> XOR DX, DX ; clear DX
> MOV CX, BX ; set CX=BX
> 
> @SUM:  ; loop label
>   MOV DL, [SI] ; set DL=[SI]
>   ADD AX, DX   ; set AX=AX+DX
>   INC SI   ; set SI=SI+1
> LOOP @SUM  ; jump to label @SUM while CX!=0
> 
> POP DX ; pop a value from STACK into DX
> POP CX ; pop a value from STACK into CX
> 
> RET; return control to the calling 
> procedure
>SUM ENDP
> 
> 
> And one more:
> 
>extension Sequence where Element: Arithmetic {
>func sum() {
>return reduce(0, +)
>}
>}
> 
> Clarity is not 

Re: [swift-evolution] Smart KeyPaths

2017-03-20 Thread Jonathan Hull via swift-evolution
+1.  This is my favorite solution so far. 

 With ‘Person.keypath.name' it is obvious that we are creating a key path.  
There is no ambiguity for the reader.  With autocomplete it will be very little 
extra typing anyway…

Thanks,
Jon

> On Mar 19, 2017, at 9:20 PM, Dietmar Planitzer via swift-evolution 
>  wrote:
> 
> Key paths of this form:
> 
> Person.name
> 
> will always make it harder than necessary to:
> 
> * search for all places where we are using key paths
> 
> * do efficient code completion. Eg you’ll get a mix of static properties and 
> key paths
> 
> 
> We’ve been using this kind of setup in our projects for some time now:
> 
> class Person {
> 
>   struct keypath {
> 
>  static let name = #keyPath(Person.name)
>  …
>   }
> 
>   …
> }
> 
> where a keypath is then used like this:
> 
> Person.keypath.name
> 
> and this has worked very well. It makes it easy to see where we are using a 
> keypath rather than accessing some static property, it works very nicely with 
> code completion and it makes it very easy to search for all places where we 
> are using key paths from the Person type.
> 
> I would prefer that the proposed keypath model would automatically organize 
> key paths like this.
> 
> 
> Regards,
> 
> Dietmar Planitzer
> 
> 
>> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>  wrote:
>> 
>>> I think the clarity desired is more similar to that obtained by the `try` 
>>> keyword. Ya, the compiler knows that this function throws already, but 
>>> Swift aims for clarity in the source code. Clarity is often achieved by 
>>> providing potentially redundant information for the programmer.
>>> 
>>> As proposed, it is difficult to distinguish a key path from a static 
>>> variable. Maybe that's not problematic? Well, it's up to the community to 
>>> decide.
>> 
>> Why don't we just say all instance properties are shadowed by a static 
>> constant property of the same name with the appropriate key path type.  This 
>> makes it not mysterious at all but instead very straightforward.  We could 
>> even say that static and class properties are shadowed by a key path 
>> property on the meta type.
>> 
>> 
>>> I do think it is a bit worrisome that static variable access might cause 
>>> side effects (or at least, might take a while to compute) but creating key 
>>> paths should not, but that's a fringe case probably.
>>> 
>>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
> wrote:
> 
>> This is true of many things.  It is why IDEs make type information 
>> readily available.
> 
> Is clarity not a thing to be desired?
 
 Clarity is in the eye of the beholder. Here's one notion of clarity:
 
sum :: (Num a, Foldable t) => t a -> a
sum = foldl (+) 0
 
 Here's another:
 
int sum(int array[], size_t len) {
int total = 0;
for(size_t i = 0; i < len; i++) {
total += array[i];
}
return total;
}
 
 And another:
 
SUM PROC
 ; this procedure will calculate the sum of an array
 ; input : SI=offset address of the array
 ;   : BX=size of the array
 ; output : AX=sum of the array
 
 PUSH CX; push CX onto the STACK
 PUSH DX; push DX onto the STACK
 
 XOR AX, AX ; clear AX
 XOR DX, DX ; clear DX
 MOV CX, BX ; set CX=BX
 
 @SUM:  ; loop label
   MOV DL, [SI] ; set DL=[SI]
   ADD AX, DX   ; set AX=AX+DX
   INC SI   ; set SI=SI+1
 LOOP @SUM  ; jump to label @SUM while CX!=0
 
 POP DX ; pop a value from STACK into DX
 POP CX ; pop a value from STACK into CX
 
 RET; return control to the calling 
 procedure
SUM ENDP
 
 
 And one more:
 
extension Sequence where Element: Arithmetic {
func sum() {
return reduce(0, +)
}
}
 
 Clarity is not achieved by explicitly stating every detail of your code. 
 It's achieved by explicitly stating what needs to be said, and *not* 
 explicitly stating what *doesn't* need to be said.
 
 The people who oppose using a special syntax for this feature think that, 
 by and large, clarity is best 

Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Dietmar Planitzer via swift-evolution
Key paths of this form:

Person.name

will always make it harder than necessary to:

* search for all places where we are using key paths

* do efficient code completion. Eg you’ll get a mix of static properties and 
key paths


We’ve been using this kind of setup in our projects for some time now:

class Person {

   struct keypath {

  static let name = #keyPath(Person.name)
  …
   }

   …
}

where a keypath is then used like this:

Person.keypath.name

and this has worked very well. It makes it easy to see where we are using a 
keypath rather than accessing some static property, it works very nicely with 
code completion and it makes it very easy to search for all places where we are 
using key paths from the Person type.

I would prefer that the proposed keypath model would automatically organize key 
paths like this.


Regards,

Dietmar Planitzer


> On Mar 19, 2017, at 20:49, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
>> I think the clarity desired is more similar to that obtained by the `try` 
>> keyword. Ya, the compiler knows that this function throws already, but Swift 
>> aims for clarity in the source code. Clarity is often achieved by providing 
>> potentially redundant information for the programmer.
>> 
>> As proposed, it is difficult to distinguish a key path from a static 
>> variable. Maybe that's not problematic? Well, it's up to the community to 
>> decide.
> 
> Why don't we just say all instance properties are shadowed by a static 
> constant property of the same name with the appropriate key path type.  This 
> makes it not mysterious at all but instead very straightforward.  We could 
> even say that static and class properties are shadowed by a key path property 
> on the meta type.
> 
> 
>> I do think it is a bit worrisome that static variable access might cause 
>> side effects (or at least, might take a while to compute) but creating key 
>> paths should not, but that's a fringe case probably.
>> 
>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
 On Mar 19, 2017, at 4:47 PM, Charles Srstka  
 wrote:
 
> This is true of many things.  It is why IDEs make type information 
> readily available.
 
 Is clarity not a thing to be desired?
>>> 
>>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>>> 
>>> sum :: (Num a, Foldable t) => t a -> a
>>> sum = foldl (+) 0
>>> 
>>> Here's another:
>>> 
>>> int sum(int array[], size_t len) {
>>> int total = 0;
>>> for(size_t i = 0; i < len; i++) {
>>> total += array[i];
>>> }
>>> return total;
>>> }
>>> 
>>> And another:
>>> 
>>> SUM PROC
>>>  ; this procedure will calculate the sum of an array
>>>  ; input : SI=offset address of the array
>>>  ;   : BX=size of the array
>>>  ; output : AX=sum of the array
>>> 
>>>  PUSH CX; push CX onto the STACK
>>>  PUSH DX; push DX onto the STACK
>>> 
>>>  XOR AX, AX ; clear AX
>>>  XOR DX, DX ; clear DX
>>>  MOV CX, BX ; set CX=BX
>>> 
>>>  @SUM:  ; loop label
>>>MOV DL, [SI] ; set DL=[SI]
>>>ADD AX, DX   ; set AX=AX+DX
>>>INC SI   ; set SI=SI+1
>>>  LOOP @SUM  ; jump to label @SUM while CX!=0
>>> 
>>>  POP DX ; pop a value from STACK into DX
>>>  POP CX ; pop a value from STACK into CX
>>> 
>>>  RET; return control to the calling 
>>> procedure
>>> SUM ENDP
>>> 
>>> 
>>> And one more:
>>> 
>>> extension Sequence where Element: Arithmetic {
>>> func sum() {
>>> return reduce(0, +)
>>> }
>>> }
>>> 
>>> Clarity is not achieved by explicitly stating every detail of your code. 
>>> It's achieved by explicitly stating what needs to be said, and *not* 
>>> explicitly stating what *doesn't* need to be said.
>>> 
>>> The people who oppose using a special syntax for this feature think that, 
>>> by and large, clarity is best served by *not* explicitly stating when 
>>> you're using a key path. They believe that you are unlikely to run into 
>>> ambiguity and, when you do, it will be easy to work around it. This is an 
>>> opinion, so it's open to disagreement, but that's where they stand on it.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> 

Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Jaden Geller via swift-evolution
You mean overloaded, not shadowed, right?

> On Mar 19, 2017, at 8:49 PM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>>  wrote:
>> 
>> I think the clarity desired is more similar to that obtained by the `try` 
>> keyword. Ya, the compiler knows that this function throws already, but Swift 
>> aims for clarity in the source code. Clarity is often achieved by providing 
>> potentially redundant information for the programmer.
>> 
>> As proposed, it is difficult to distinguish a key path from a static 
>> variable. Maybe that's not problematic? Well, it's up to the community to 
>> decide.
> 
> Why don't we just say all instance properties are shadowed by a static 
> constant property of the same name with the appropriate key path type.  This 
> makes it not mysterious at all but instead very straightforward.  We could 
> even say that static and class properties are shadowed by a key path property 
> on the meta type.
> 
> 
>> I do think it is a bit worrisome that static variable access might cause 
>> side effects (or at least, might take a while to compute) but creating key 
>> paths should not, but that's a fringe case probably.
>> 
>>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
> wrote:
> 
> This is true of many things.  It is why IDEs make type information 
> readily available.
 
 Is clarity not a thing to be desired?
>>> 
>>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>>> 
>>> sum :: (Num a, Foldable t) => t a -> a
>>> sum = foldl (+) 0
>>> 
>>> Here's another:
>>> 
>>> int sum(int array[], size_t len) {
>>> int total = 0;
>>> for(size_t i = 0; i < len; i++) {
>>> total += array[i];
>>> }
>>> return total;
>>> }
>>> 
>>> And another:
>>> 
>>> SUM PROC
>>>  ; this procedure will calculate the sum of an array
>>>  ; input : SI=offset address of the array
>>>  ;   : BX=size of the array
>>>  ; output : AX=sum of the array
>>> 
>>>  PUSH CX; push CX onto the STACK
>>>  PUSH DX; push DX onto the STACK
>>> 
>>>  XOR AX, AX ; clear AX
>>>  XOR DX, DX ; clear DX
>>>  MOV CX, BX ; set CX=BX
>>> 
>>>  @SUM:  ; loop label
>>>MOV DL, [SI] ; set DL=[SI]
>>>ADD AX, DX   ; set AX=AX+DX
>>>INC SI   ; set SI=SI+1
>>>  LOOP @SUM  ; jump to label @SUM while CX!=0
>>> 
>>>  POP DX ; pop a value from STACK into DX
>>>  POP CX ; pop a value from STACK into CX
>>> 
>>>  RET; return control to the calling 
>>> procedure
>>> SUM ENDP
>>> 
>>> And one more:
>>> 
>>> extension Sequence where Element: Arithmetic {
>>> func sum() {
>>> return reduce(0, +)
>>> }
>>> }
>>> 
>>> Clarity is not achieved by explicitly stating every detail of your code. 
>>> It's achieved by explicitly stating what needs to be said, and *not* 
>>> explicitly stating what *doesn't* need to be said.
>>> 
>>> The people who oppose using a special syntax for this feature think that, 
>>> by and large, clarity is best served by *not* explicitly stating when 
>>> you're using a key path. They believe that you are unlikely to run into 
>>> ambiguity and, when you do, it will be easy to work around it. This is an 
>>> opinion, so it's open to disagreement, but that's where they stand on it.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Mar 19, 2017, at 10:31 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
> I think the clarity desired is more similar to that obtained by the `try` 
> keyword. Ya, the compiler knows that this function throws already, but Swift 
> aims for clarity in the source code. Clarity is often achieved by providing 
> potentially redundant information for the programmer.
> 
> As proposed, it is difficult to distinguish a key path from a static 
> variable. Maybe that's not problematic? Well, it's up to the community to 
> decide.

Why don't we just say all instance properties are shadowed by a static constant 
property of the same name with the appropriate key path type.  This makes it 
not mysterious at all but instead very straightforward.  We could even say that 
static and class properties are shadowed by a key path property on the meta 
type.


> I do think it is a bit worrisome that static variable access might cause side 
> effects (or at least, might take a while to compute) but creating key paths 
> should not, but that's a fringe case probably.
> 
>> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
 On Mar 19, 2017, at 4:47 PM, Charles Srstka  
 wrote:
 
 This is true of many things.  It is why IDEs make type information readily 
 available.
>>> 
>>> Is clarity not a thing to be desired?
>> 
>> Clarity is in the eye of the beholder. Here's one notion of clarity:
>> 
>>  sum :: (Num a, Foldable t) => t a -> a
>>  sum = foldl (+) 0
>> 
>> Here's another:
>> 
>>  int sum(int array[], size_t len) {
>>  int total = 0;
>>  for(size_t i = 0; i < len; i++) {
>>  total += array[i];
>>  }
>>  return total;
>>  }
>> 
>> And another:
>> 
>>  SUM PROC
>>   ; this procedure will calculate the sum of an array
>>   ; input : SI=offset address of the array
>>   ;   : BX=size of the array
>>   ; output : AX=sum of the array
>> 
>>   PUSH CX; push CX onto the STACK
>>   PUSH DX; push DX onto the STACK
>> 
>>   XOR AX, AX ; clear AX
>>   XOR DX, DX ; clear DX
>>   MOV CX, BX ; set CX=BX
>> 
>>   @SUM:  ; loop label
>> MOV DL, [SI] ; set DL=[SI]
>> ADD AX, DX   ; set AX=AX+DX
>> INC SI   ; set SI=SI+1
>>   LOOP @SUM  ; jump to label @SUM while CX!=0
>> 
>>   POP DX ; pop a value from STACK into DX
>>   POP CX ; pop a value from STACK into CX
>> 
>>   RET; return control to the calling 
>> procedure
>>  SUM ENDP
>> 
>> And one more:
>> 
>>  extension Sequence where Element: Arithmetic {
>>  func sum() {
>>  return reduce(0, +)
>>  }
>>  }
>> 
>> Clarity is not achieved by explicitly stating every detail of your code. 
>> It's achieved by explicitly stating what needs to be said, and *not* 
>> explicitly stating what *doesn't* need to be said.
>> 
>> The people who oppose using a special syntax for this feature think that, by 
>> and large, clarity is best served by *not* explicitly stating when you're 
>> using a key path. They believe that you are unlikely to run into ambiguity 
>> and, when you do, it will be easy to work around it. This is an opinion, so 
>> it's open to disagreement, but that's where they stand on it.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Jaden Geller via swift-evolution
I think the clarity desired is more similar to that obtained by the `try` 
keyword. Ya, the compiler knows that this function throws already, but Swift 
aims for clarity in the source code. Clarity is often achieved by providing 
potentially redundant information for the programmer.

As proposed, it is difficult to distinguish a key path from a static variable. 
Maybe that's not problematic? Well, it's up to the community to decide. I do 
think it is a bit worrisome that static variable access might cause side 
effects (or at least, might take a while to compute) but creating key paths 
should not, but that's a fringe case probably.

> On Mar 19, 2017, at 6:32 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 4:47 PM, Charles Srstka  
>>> wrote:
>>> 
>>> This is true of many things.  It is why IDEs make type information readily 
>>> available.
>> 
>> Is clarity not a thing to be desired?
> 
> Clarity is in the eye of the beholder. Here's one notion of clarity:
> 
>   sum :: (Num a, Foldable t) => t a -> a
>   sum = foldl (+) 0
> 
> Here's another:
> 
>   int sum(int array[], size_t len) {
>   int total = 0;
>   for(size_t i = 0; i < len; i++) {
>   total += array[i];
>   }
>   return total;
>   }
> 
> And another:
> 
>   SUM PROC
>; this procedure will calculate the sum of an array
>; input : SI=offset address of the array
>;   : BX=size of the array
>; output : AX=sum of the array
> 
>PUSH CX; push CX onto the STACK
>PUSH DX; push DX onto the STACK
> 
>XOR AX, AX ; clear AX
>XOR DX, DX ; clear DX
>MOV CX, BX ; set CX=BX
> 
>@SUM:  ; loop label
>  MOV DL, [SI] ; set DL=[SI]
>  ADD AX, DX   ; set AX=AX+DX
>  INC SI   ; set SI=SI+1
>LOOP @SUM  ; jump to label @SUM while CX!=0
> 
>POP DX ; pop a value from STACK into DX
>POP CX ; pop a value from STACK into CX
> 
>RET; return control to the calling 
> procedure
>   SUM ENDP
> 
> And one more:
> 
>   extension Sequence where Element: Arithmetic {
>   func sum() {
>   return reduce(0, +)
>   }
>   }
> 
> Clarity is not achieved by explicitly stating every detail of your code. It's 
> achieved by explicitly stating what needs to be said, and *not* explicitly 
> stating what *doesn't* need to be said.
> 
> The people who oppose using a special syntax for this feature think that, by 
> and large, clarity is best served by *not* explicitly stating when you're 
> using a key path. They believe that you are unlikely to run into ambiguity 
> and, when you do, it will be easy to work around it. This is an opinion, so 
> it's open to disagreement, but that's where they stand on it.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Brent Royal-Gordon via swift-evolution
> On Mar 19, 2017, at 4:47 PM, Charles Srstka  wrote:
> 
>> This is true of many things.  It is why IDEs make type information readily 
>> available.
> 
> Is clarity not a thing to be desired?

Clarity is in the eye of the beholder. Here's one notion of clarity:

sum :: (Num a, Foldable t) => t a -> a
sum = foldl (+) 0

Here's another:

int sum(int array[], size_t len) {
int total = 0;
for(size_t i = 0; i < len; i++) {
total += array[i];
}
return total;
}

And another:

SUM PROC
 ; this procedure will calculate the sum of an array
 ; input : SI=offset address of the array
 ;   : BX=size of the array
 ; output : AX=sum of the array

 PUSH CX; push CX onto the STACK
 PUSH DX; push DX onto the STACK

 XOR AX, AX ; clear AX
 XOR DX, DX ; clear DX
 MOV CX, BX ; set CX=BX

 @SUM:  ; loop label
   MOV DL, [SI] ; set DL=[SI]
   ADD AX, DX   ; set AX=AX+DX
   INC SI   ; set SI=SI+1
 LOOP @SUM  ; jump to label @SUM while CX!=0

 POP DX ; pop a value from STACK into DX
 POP CX ; pop a value from STACK into CX

 RET; return control to the calling 
procedure
SUM ENDP

And one more:

extension Sequence where Element: Arithmetic {
func sum() {
return reduce(0, +)
}
}

Clarity is not achieved by explicitly stating every detail of your code. It's 
achieved by explicitly stating what needs to be said, and *not* explicitly 
stating what *doesn't* need to be said.

The people who oppose using a special syntax for this feature think that, by 
and large, clarity is best served by *not* explicitly stating when you're using 
a key path. They believe that you are unlikely to run into ambiguity and, when 
you do, it will be easy to work around it. This is an opinion, so it's open to 
disagreement, but that's where they stand on it.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Charles Srstka via swift-evolution
> On Mar 19, 2017, at 4:15 PM, Matthew Johnson  wrote:
> 
> On Mar 19, 2017, at 4:02 PM, Charles Srstka via swift-evolution 
> > wrote:
> 
>>> On Mar 19, 2017, at 3:45 PM, Brent Royal-Gordon >> > wrote:
>>> 
 On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
 > wrote:
 
> I disagree. How the reader is supposed to now there is a static property 
> or not ? Having readable code is more important than having easy to write 
> code.
 
 I’ve got to agree with this. With the proposed syntax, it’s unclear 
 whether you’re referring to a static property or a key path. It’s going to 
 cause confusion. There needs to be some kind of syntactic way to 
 differentiate the two.
>>> 
>>> How often do you have a property with the exact same name and type on both 
>>> the instance and type? When you *do* have one, how often would it be better 
>>> off with a name like `defaultFoo` instead of plain `foo`?
>>> 
>>> Why is this a problem for keypaths, but not for unbound methods?
>>> 
>>> How is this different from a hundred other places in Swift where we allow 
>>> overloading and tolerate ambiguity in order to enjoy nicer syntax?
>>> 
>>> When, in practice, do you expect this to cause trouble?
>> 
>> Even if there *isn’t* a property with the same name, it’s still confusing, 
>> because to a reader unfamiliar with the code, it’s not clear what you’re 
>> looking at.
> 
> This is true of many things.  It is why IDEs make type information readily 
> available.

Is clarity not a thing to be desired?

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Ricardo Parada via swift-evolution
Thanks to both of you for pointing how to disambiguate and how generic types 
can be inferred.  I now think that this is the way to go.  It looks to me like 
it is the simplest and the most elegant solution.



> On Mar 17, 2017, at 6:05 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 17, 2017, at 3:04 PM, BJ Homer > > wrote:
>> 
>> So then this would be disambiguated like this?
>> 
>> let staticValue = Foo.bar // Defaults to accessing the static value, when 
>> there is ambiguity
>> 
>> let value:   Bar   = Foo.bar
>> let keyPath: WritableKeyPath = Foo.bar
>> 
>> It’s a little unfortunately to have to spell out WritableKeyPath 
>> there, but as long as there’s some way to do it, I don’t think it’s a 
>> problem. This is likely a rare edge case.
> 
> You could also just write `: WritableKeyPath` and let the generic arguments 
> be deduced. I agree that, in most situations you want a key path, you'll 
> likely have type context that picks the right thing.
> 
> -Joe
> 
>> -BJ Homer
>> 
>>> On Mar 17, 2017, at 3:56 PM, Joe Groff >> > wrote:
>>> 
 
 On Mar 17, 2017, at 2:53 PM, Michael LeHew > wrote:
 
 
> On Mar 17, 2017, at 2:21 PM, BJ Homer  > wrote:
> 
> This looks great!
> 
> What happens in the case when there is a static property by the same name 
> as an instance property? e.g.
> 
> struct Foo {
> static var bar: Bar
> var bar: Bar
> }
> 
> Foo.bar // What is this?
> 
> Is it still possible to reference both the static property and a KeyPath 
> to the instance method? 
 
 This is essentially the same question that I arrived at in my reply to 
 Vladimir.  I think Joe might be best able to answer here.
>>> 
>>> We already encounter this situation with static vs instance methods, since 
>>> `Foo.bar` can refer to either a static method `bar` or an unbound instance 
>>> method `bar`. We use type context to disambiguate, favoring the static 
>>> member if context doesn't help:
>>> 
>>> struct X {
>>>   static func foo() {}
>>>   func foo() {}
>>> }
>>> 
>>> let foo1 = X.foo // Defaults to static member
>>> let foo2: () -> () = X.foo // Picks static member by type context
>>> let foo3: (X) -> () -> () = X.foo // Picks instance member by type context
>>> 
>>> -Joe
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Matthew Johnson via swift-evolution


Sent from my iPhone

> On Mar 19, 2017, at 4:02 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 3:45 PM, Brent Royal-Gordon  
>>> wrote:
>>> 
 On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
  wrote:
 
 I disagree. How the reader is supposed to now there is a static property 
 or not ? Having readable code is more important than having easy to write 
 code.
>>> 
>>> I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
>>> you’re referring to a static property or a key path. It’s going to cause 
>>> confusion. There needs to be some kind of syntactic way to differentiate 
>>> the two.
>> 
>> How often do you have a property with the exact same name and type on both 
>> the instance and type? When you *do* have one, how often would it be better 
>> off with a name like `defaultFoo` instead of plain `foo`?
>> 
>> Why is this a problem for keypaths, but not for unbound methods?
>> 
>> How is this different from a hundred other places in Swift where we allow 
>> overloading and tolerate ambiguity in order to enjoy nicer syntax?
>> 
>> When, in practice, do you expect this to cause trouble?
> 
> Even if there *isn’t* a property with the same name, it’s still confusing, 
> because to a reader unfamiliar with the code, it’s not clear what you’re 
> looking at.

This is true of many things.  It is why IDEs make type information readily 
available.

> 
> Unbound methods are annoying too. At least with them, though, there are 
> *usually* naming conventions that differentiate the two from each other (but 
> not always. Quick, between FileManager, NSParagraphStyle, 
> IOBluetoothHostController, NSTimeZone, and and NSUserNotificationCenter, 
> which ones require you to put parens after the ‘default’ accessor, and which 
> don’t?).
> 
> Charles
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Ricardo Parada via swift-evolution


Sent from my iPhone

> On Mar 19, 2017, at 4:53 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On Mar 19, 2017, at 3:45 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
 On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
  wrote:
 
 I disagree. How the reader is supposed to now there is a static property 
 or not ? Having readable code is more important than having easy to write 
 code.
>>> 
>>> I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
>>> you’re referring to a static property or a key path. It’s going to cause 
>>> confusion. There needs to be some kind of syntactic way to differentiate 
>>> the two.
>> 
>> How often do you have a property with the exact same name and type on both 
>> the instance and type? When you *do* have one, how often would it be better 
>> off with a name like `defaultFoo` instead of plain `foo`?
>> 

That crossed my mind too. If we have a static property with the same name as a 
property then make it a warning and we can easily rename one or the other in 
our code to fix the warning. 

>> Why is this a problem for keypaths, but not for unbound methods?
>> 

Hi Brent, what is an unbound method? Do you have a simple example just so that 
I can better follow what you are saying? Thanks. 


>> How is this different from a hundred other places in Swift where we allow 
>> overloading and tolerate ambiguity in order to enjoy nicer syntax?
>> 
>> When, in practice, do you expect this to cause trouble?
> 
> +1
> 
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Charles Srstka via swift-evolution
> On Mar 19, 2017, at 3:45 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
>> > wrote:
>> 
>>> I disagree. How the reader is supposed to now there is a static property or 
>>> not ? Having readable code is more important than having easy to write code.
>> 
>> I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
>> you’re referring to a static property or a key path. It’s going to cause 
>> confusion. There needs to be some kind of syntactic way to differentiate the 
>> two.
> 
> How often do you have a property with the exact same name and type on both 
> the instance and type? When you *do* have one, how often would it be better 
> off with a name like `defaultFoo` instead of plain `foo`?
> 
> Why is this a problem for keypaths, but not for unbound methods?
> 
> How is this different from a hundred other places in Swift where we allow 
> overloading and tolerate ambiguity in order to enjoy nicer syntax?
> 
> When, in practice, do you expect this to cause trouble?

Even if there *isn’t* a property with the same name, it’s still confusing, 
because to a reader unfamiliar with the code, it’s not clear what you’re 
looking at.

Unbound methods are annoying too. At least with them, though, there are 
*usually* naming conventions that differentiate the two from each other (but 
not always. Quick, between FileManager, NSParagraphStyle, 
IOBluetoothHostController, NSTimeZone, and and NSUserNotificationCenter, which 
ones require you to put parens after the ‘default’ accessor, and which don’t?).

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Ricardo Parada via swift-evolution
I was thinking that maybe it could be an error or warning to have a static 
property with the same name as a normal property. But I'm simply thinking out 
loud a possible solution to this ambiguity problem without introducing a symbol 
for key paths. Just trying to see if we can keep it simple. 

I'm not arguing in favor of this though. Im just trying to bring up possible 
solutions so we that we can better compare the alternatives and understand the 
pros and cons of each. 

By the way I do like the colon notation that you and others have suggested. I 
hope we pick the best at the end. 

I'm excited about this proposal and want it to be the successful. One of the 
most exciting things happening in swift right now IMHO. 


> On Mar 19, 2017, at 3:51 PM, Jean-Daniel  wrote:
> 
> 
>> Le 19 mars 2017 à 16:41, Ricardo Parada via swift-evolution 
>>  a écrit :
>> 
>> I agree that they can get mixed up with static properties. However, I think 
>> I would not mind because it would only cause an ambiguity when having a 
>> static property with the same name as the property which would be an odd 
>> practice I think.  
> 
> I disagree. How the reader is supposed to now there is a static property or 
> not ? Having readable code is more important than having easy to write code.
> 
> Without context, the following statement is ambiguous, This ambiguity can 
> easily be avoid by choosing an other syntax. So why would we want to 
> introduce it in the first place ?
> 
> let name = Person:friends[0].name
> 
> 
> 
>> I was defining static properties with the same name as the property in order 
>> to smart key paths.  For example:
>> 
>> Class Person {
>>static firstName: KeyPath(“firstName”)
>>static lastName: KeyPath(“lastName”)
>> 
>>var firstName: String 
>>var lastName: String
>> 
>>…
>> }
>> 
>> 
>> So that I could create qualifiers, ie. Person.firstName.like(“R*”), and sort 
>> orderings, Person.firstName.asc().
>> 
>> I think with these smart key paths the need for these static properties that 
>> mirror the property on the instance would not be required.
>> 
>> 
>> 
>> 
>>> On Mar 17, 2017, at 2:27 PM, Vladimir.S via swift-evolution 
>>>  wrote:
>>> 
>>> On 17.03.2017 20:04, Michael LeHew via swift-evolution 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
 ...
>>> 
>>> Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
>>> 
>>> Person.friends[0].name - like access to static property. T.method can't 
>>> have subscript for it and then some field. So, I believe such key paths 
>>> deserve its own syntax.
>>> 
>>> luke[path] - very close to access the subscript of instance. In compare to 
>>> T.method, we can call result of T.method(i.e. let m = T.method; m()), just 
>>> like the T.method itself(foo.method()). But here we are calling some kind 
>>> of subscript instead of access property by "path".
>>> 
>>> There is no some 'special' marker for me that saying "hey, there is 
>>> references to properties used" from the first look.
>>> 
>>> Probably we can consider another separators, like
>>> 
>>> Person:friends[0].name
>>> luke:path
>>> 
>>> Person->friends[0].name
>>> luke->path
>>> 
>>> Person[friends[0].name] // single brackets for type
>>> luke[[path]] // double brackets for instance
>>> 
>>> Person@friends[0].name
>>> luke@path
>>> 
>>> or other with help of community.
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Matthew Johnson via swift-evolution


Sent from my iPhone

> On Mar 19, 2017, at 3:45 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
>>>  wrote:
>>> 
>>> I disagree. How the reader is supposed to now there is a static property or 
>>> not ? Having readable code is more important than having easy to write code.
>> 
>> I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
>> you’re referring to a static property or a key path. It’s going to cause 
>> confusion. There needs to be some kind of syntactic way to differentiate the 
>> two.
> 
> How often do you have a property with the exact same name and type on both 
> the instance and type? When you *do* have one, how often would it be better 
> off with a name like `defaultFoo` instead of plain `foo`?
> 
> Why is this a problem for keypaths, but not for unbound methods?
> 
> How is this different from a hundred other places in Swift where we allow 
> overloading and tolerate ambiguity in order to enjoy nicer syntax?
> 
> When, in practice, do you expect this to cause trouble?

+1

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Brent Royal-Gordon via swift-evolution
> On Mar 19, 2017, at 12:57 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> I disagree. How the reader is supposed to now there is a static property or 
>> not ? Having readable code is more important than having easy to write code.
> 
> I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
> you’re referring to a static property or a key path. It’s going to cause 
> confusion. There needs to be some kind of syntactic way to differentiate the 
> two.

How often do you have a property with the exact same name and type on both the 
instance and type? When you *do* have one, how often would it be better off 
with a name like `defaultFoo` instead of plain `foo`?

Why is this a problem for keypaths, but not for unbound methods?

How is this different from a hundred other places in Swift where we allow 
overloading and tolerate ambiguity in order to enjoy nicer syntax?

When, in practice, do you expect this to cause trouble?

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Charles Srstka via swift-evolution
> On Mar 19, 2017, at 2:51 PM, Jean-Daniel via swift-evolution 
>  wrote:
> 
>> Le 19 mars 2017 à 16:41, Ricardo Parada via swift-evolution 
>> > a écrit :
>> 
>> I agree that they can get mixed up with static properties. However, I think 
>> I would not mind because it would only cause an ambiguity when having a 
>> static property with the same name as the property which would be an odd 
>> practice I think.  
> 
> I disagree. How the reader is supposed to now there is a static property or 
> not ? Having readable code is more important than having easy to write code.

I’ve got to agree with this. With the proposed syntax, it’s unclear whether 
you’re referring to a static property or a key path. It’s going to cause 
confusion. There needs to be some kind of syntactic way to differentiate the 
two.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Jean-Daniel via swift-evolution

> Le 19 mars 2017 à 16:41, Ricardo Parada via swift-evolution 
>  a écrit :
> 
> I agree that they can get mixed up with static properties. However, I think I 
> would not mind because it would only cause an ambiguity when having a static 
> property with the same name as the property which would be an odd practice I 
> think.  

I disagree. How the reader is supposed to now there is a static property or not 
? Having readable code is more important than having easy to write code.

Without context, the following statement is ambiguous, This ambiguity can 
easily be avoid by choosing an other syntax. So why would we want to introduce 
it in the first place ?

let name = Person:friends[0].name



> I was defining static properties with the same name as the property in order 
> to smart key paths.  For example:
> 
> Class Person {
> static firstName: KeyPath(“firstName”)
> static lastName: KeyPath(“lastName”)
> 
> var firstName: String 
> var lastName: String
> 
> …
> }
> 
> 
> So that I could create qualifiers, ie. Person.firstName.like(“R*”), and sort 
> orderings, Person.firstName.asc().
> 
> I think with these smart key paths the need for these static properties that 
> mirror the property on the instance would not be required.
> 
> 
> 
> 
>> On Mar 17, 2017, at 2:27 PM, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>> On 17.03.2017 20:04, Michael LeHew via swift-evolution 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
>>> ...
>> 
>> Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
>> 
>> Person.friends[0].name - like access to static property. T.method can't have 
>> subscript for it and then some field. So, I believe such key paths deserve 
>> its own syntax.
>> 
>> luke[path] - very close to access the subscript of instance. In compare to 
>> T.method, we can call result of T.method(i.e. let m = T.method; m()), just 
>> like the T.method itself(foo.method()). But here we are calling some kind of 
>> subscript instead of access property by "path".
>> 
>> There is no some 'special' marker for me that saying "hey, there is 
>> references to properties used" from the first look.
>> 
>> Probably we can consider another separators, like
>> 
>> Person:friends[0].name
>> luke:path
>> 
>> Person->friends[0].name
>> luke->path
>> 
>> Person[friends[0].name] // single brackets for type
>> luke[[path]] // double brackets for instance
>> 
>> Person@friends[0].name
>> luke@path
>> 
>> or other with help of community.
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Zach Waldowski via swift-evolution
I might point out that this form of bikeshedding was already explicitly
called out in the text of the proposal. ("Alternatives Considered")
Your personal preferences as to what sigils are "lightweight" or "easy"
are not absolute ones without some form of evidence or objective
rationale provided.


Until that can be done, it would be more productive to discuss what we
can do to avoid ambiguity without magic sigils; or, in the face of Joe
Groff's post, why that ambiguity is a problem at all.


Best,

  Zachary Waldowski

  z...@waldowski.me





On Sun, Mar 19, 2017, at 01:00 AM, Muse M via swift-evolution wrote:

> I would suggest a keypath using ~ which is concise and clearer to
> identify.
> 

> let myPath = Person~friends[0].name

> 

> 

> 

> 

> 

> On Sunday, March 19, 2017, Jonathan Hull via swift-evolution  evolut...@swift.org> wrote:
>> This looks fantastic!

>> 

>> The one worry I would have, as others have brought up, is confusion
>> when there are static properties with the same name.  Maybe we could
>> have a special static property called ‘keyPath’ or ‘path’ that would
>> be reserved, and anything that followed would be a key path.
>> 

>> So instead of:

>> 

>> let myPath = Person.friends[0].name

>> 

>> you would have:

>> 

>> let myPath = Person.keyPath.friends[0].name

>> 

>> 

>> Or if we want to choose a sentinel, I would nominate ‘$’:

>> 

>> let myPath = $Person.friends[0].name

>> 

>> Thanks,

>> Jon

>> 

>> 

>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution >> evolut...@swift.org> 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-
>>>  * Authors: David Smith[1], Michael LeHew[2], Joe Groff[3]
>>>  * Review Manager: TBD
>>>  * Status: *Awaiting Review*
>>>  * Associated PRs:
>>>* #644[4]
>>> 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.
>>> More Expressive KeyPaths



>>> We would also like to support being able to use *Key Paths* to
>>> access into collections, which is not currently possible.
>>> Proposed solution



>>> We propose introducing a new expression akin to Type.method, but for
>>> properties and subscripts. These property reference expressions
>>> produce KeyPath objects, rather than Strings. KeyPaths are a family
>>> of generic classes *(structs and protocols here would be ideal, but
>>> requires generalized existentials)* which encapsulate a property
>>> reference or chain of property references, including the type,
>>> mutability, property name(s), and ability to set/get values.
>>> Here's a sample of it in use:



>>> Swift struct Person {  var name: String  var friends: [Person]  var
>>> bestFriend: Person? }

>>> var han = Person(name: "Han Solo", friends: []) var luke =
>>> Person(name: "Luke Skywalker", friends: [han])

>>> let firstFriendsNameKeyPath = Person.friends[].name

>>> let firstFriend = luke[path] // han

>>> // or equivalently, with type inferred from context let
>>> firstFriendName = luke[.friends[].name]

>>> // rename Luke's first friend luke[firstFriendsNameKeyPath] = "A
>>> Disreputable Smuggler"

>>> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the
>>> last jedi
>>> Detailed design



>>> Core KeyPath Types



>>> KeyPaths are a hierarchy of progressively more specific classes,
>>> based on whether we have prior knowledge of the path through the
>>> object graph we wish to traverse.
>>> Unknown Path / Unknown Root Type



>>> AnyKeyPath is fully type-erased, referring to 'any route' through an
>>> object/value graph for 'any root'. Because of type-erasure many
>>> operations can fail at runtime and are thus nillable.
>>> Swift class AnyKeyPath: CustomDebugStringConvertible, Hashable {  //
>>> MARK - Composition  // Returns nil if path.rootType !=
>>> self.valueType  func 

Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Ricardo Parada via swift-evolution
I agree that they can get mixed up with static properties. However, I think I 
would not mind because it would only cause an ambiguity when having a static 
property with the same name as the property which would be an odd practice I 
think.  

I was defining static properties with the same name as the property in order to 
smart key paths.  For example:

Class Person {
 static firstName: KeyPath(“firstName”)
 static lastName: KeyPath(“lastName”)

 var firstName: String 
 var lastName: String

 …
}


So that I could create qualifiers, ie. Person.firstName.like(“R*”), and sort 
orderings, Person.firstName.asc().

I think with these smart key paths the need for these static properties that 
mirror the property on the instance would not be required.




> On Mar 17, 2017, at 2:27 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 17.03.2017 20:04, Michael LeHew via swift-evolution 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
>> ...
> 
> Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
> 
> Person.friends[0].name - like access to static property. T.method can't have 
> subscript for it and then some field. So, I believe such key paths deserve 
> its own syntax.
> 
> luke[path] - very close to access the subscript of instance. In compare to 
> T.method, we can call result of T.method(i.e. let m = T.method; m()), just 
> like the T.method itself(foo.method()). But here we are calling some kind of 
> subscript instead of access property by "path".
> 
> There is no some 'special' marker for me that saying "hey, there is 
> references to properties used" from the first look.
> 
> Probably we can consider another separators, like
> 
> Person:friends[0].name
> luke:path
> 
> Person->friends[0].name
> luke->path
> 
> Person[friends[0].name] // single brackets for type
> luke[[path]] // double brackets for instance
> 
> Person@friends[0].name
> luke@path
> 
> or other with help of community.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Ricardo Parada via swift-evolution
It looks awesome.  

I don’t understand the details yet but I always felt it would be super cool if 
swift allowed you to express key paths elegantly which seems what this is.  

I would love to be able to create what used to be called EOQualifier in 
WebObjects/Enterprise Objects Framework (i.e. NSPredicate in CoreData I think) 
using a better syntax.  Same for EOSortOrdering, equivalent to 
NSSortDescriptor.  For example:

let predicate = 
Person.lastName.like(“Para*").and(Person.birthDate.greaterThan(aDate))

Fetch objects from the database into a managed object context like this:

let people = context.fetch(Person.self, predicate: predicate)   // 
people is inferred as Array

Or perhaps filter elements from an array like this:

let matches = people.filtered(predicate)// 
matches is inferred as Array

Or create sort orderings like this:

let orderings = 
Person.age.desc().then(Person.lastName.asc().then(Person.lastName.asc()))   // 
orderings is Array

And sort like this:

let sortedPeople = people.sorted(orderings) // sortedPeople is 
Array

And predicates for to-many relationships, for example, if we had a Family class 
and a Pet class and a pets to-many relationship Family <—>> Pet, then building 
a predicate like this would be cool:

// Families with at least one pet
let predicate = Family.pets.isNotEmpty()

// Families with no pets
let predicate = Family.pets.isEmpty()

// Families with a cat or dog
let predicate = Family.pets.hasAtLeastOneObjectSatisfying(Pet.type.equals(.dog))

// Families with a puppy
let predicate = 
Family.pets.hasAtLeastOneObjectSatisfying(Pet.type.equals(.dog).and(Pet.ageInMonths.lessThan(12))

In SQL these translate to an EXISTS qualifier. For example, the last predicate 
would translate to something like this in SQL:

SELECT t0.family_id, …
FROM family t0
WHERE 
EXISTS (
select p.pet_id
from pet p
where p.family_id = t0.family_id
and p.pet_type = ‘dog’
and p.age_in_months < 12
)


Would these Star KeyPaths enable this sort of expressiveness?

Or creating ad hoc queries like this:

// records is Array>
let records = Query()
.select (Claim.provider, Claim.sumExpectedAmount)  // 
Claim.sumExpectedAmount is a derived non-class property defined as 
"SUM(expectedAmount)"
.from (Claim.entityName)// Claim.entityName is a static property for 
string “Claim”
.where (Claim.userGroup.equals(aUserGroup))
.groupBy (Claim.provider)
.having (Claim.sumExpectedAmount.greaterThan(1000.0))
.orderBy (Claim.sumExpectedAmount.asc())
.fetch (editingContext)

// Or to fetch into a custom class

// objects is Array
let objects = Query()
.select (Claim.provider, Claim.sumExpectedAmount)  // 
Claim.sumExpectedAmount is a derived non-class property defined as 
"SUM(expectedAmount)"
.from (Claim.entityName)// Claim.entityName is a static property for 
string “Claim”
.where (Claim.userGroup.equals(aUserGroup))
.groupBy (Claim.provider)
.having (Claim.sumExpectedAmount.greaterThan(1000.0))
.orderBy (Claim.sumExpectedAmount.asc())
.fetch (context) {
Foo(context: ec, data: row)
}

Then print the results like this:

for obj in objects {
Print(“Health provider: \(obj.provider?.fullName), Total Expected: 
\(obj.sumExpectedAmount)”)
}

Where Foo would be a custom class to hold the results and provide some type 
checking on the getters for the data fetched:

class Foo {
var data : [String: Any]

init(context: EditingContext, data row: [String: Any]) {
   data = row
}


var provider : Provider? {
get {
   return data[“provider”] as? Provider
}
}

var provider : Double? {
get {
   return data[“sumExpectedAmount”] as? Double
}
}
}


By the way I do this kind of stuff with WebObjects and Project Wonder.  It’s 
just that the key paths are static variables defined in the class in ALL CAPS, 
i.e. Person.FIRST_NAME.asc() to get an EOSortOrdering for ascending firstName.  
They also look not as elegant for key paths, i.e. 
Claim.PROVIDER.dot(Provider.LAST_NAME).like(“Para*”) for an EOQualifier.  This 
is all provided by a class named ERXKey.

And for ad hoc queries I use ERXQuery which I recently created a pull request 
to add to project Wonder.  It’s in my repository rparada/wonder on GitHub in 
the erxquery branch.




> On Mar 17, 2017, at 1:04 PM, Michael LeHew via swift-evolution 
>  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-
> Authors: David Smith , Michael LeHew 
> , Joe Groff 
> Review Manager: TBD
> Status: 

Re: [swift-evolution] Smart KeyPaths

2017-03-19 Thread Rick Mann via swift-evolution
Would it be possible to create operators?

let total = manager[@sum.reports.salary]


> On Mar 18, 2017, at 22:00 , Muse M via swift-evolution 
>  wrote:
> 
> I would suggest a keypath using ~ which is concise and clearer to identify.
> 
>   let myPath = Person~friends[0].name
> 
> 
> 
> 
> 
> On Sunday, March 19, 2017, Jonathan Hull via swift-evolution 
>  wrote:
> This looks fantastic!
> 
> The one worry I would have, as others have brought up, is confusion when 
> there are static properties with the same name.  Maybe we could have a 
> special static property called ‘keyPath’ or ‘path’ that would be reserved, 
> and anything that followed would be a key path.
> 
> So instead of:
> 
>   let myPath = Person.friends[0].name
> 
> you would have:
> 
>   let myPath = Person.keyPath.friends[0].name
> 
> 
> Or if we want to choose a sentinel, I would nominate ‘$’:
> 
>   let myPath = $Person.friends[0].name
> 
> Thanks,
> Jon
> 
> 
>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>>  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-
>>  • Authors: David Smith, Michael LeHew, Joe Groff
>>  • Review Manager: TBD
>>  • Status: Awaiting Review
>>  • Associated PRs:
>>  • #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.
>> 
>> More Expressive KeyPaths
>> 
>> We would also like to support being able to use Key Paths to access into 
>> collections, which is not currently possible.
>> 
>> Proposed solution
>> We propose introducing a new expression akin to Type.method, but for 
>> properties and subscripts. These property reference expressions produce 
>> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
>> classes (structs and protocols here would be ideal, but requires generalized 
>> existentials) which encapsulate a property reference or chain of property 
>> references, including the type, mutability, property name(s), and ability to 
>> set/get values.
>> 
>> Here's a sample of it in use:
>> 
>> Swift
>> struct Person {
>> 
>> 
>> var name: String
>> 
>> 
>> var friends: [Person]
>> 
>> 
>> var bestFriend: Person?
>> }
>> 
>> 
>> 
>> var han = Person(name: "Han Solo", friends: [])
>> var luke = Person(name: "Luke Skywalker", friends: [han])
>> 
>> 
>> 
>> let firstFriendsNameKeyPath = Person.friends[0].
>> name
>> 
>> 
>> let firstFriend = luke[path] // han
>> 
>> 
>> 
>> // or equivalently, with type inferred from context
>> let firstFriendName = luke[.friends[0].name]
>> 
>> 
>> 
>> // rename Luke's first friend
>> 
>> luke
>> [firstFriendsNameKeyPath] = "A Disreputable Smuggler"
>> 
>> 
>> 
>> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
>> Detailed design
>> Core KeyPath Types
>> 
>> KeyPaths are a hierarchy of progressively more specific classes, based on 
>> whether we have prior knowledge of the path through the object graph we wish 
>> to traverse. 
>> 
>> Unknown Path / Unknown Root Type
>> 
>> AnyKeyPath is fully type-erased, referring to 'any route' through an 
>> object/value graph for 'any root'. Because of type-erasure many operations 
>> can fail at runtime and are thus nillable. 
>> 
>> Swift
>> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
>> 
>> 
>> // MARK - Composition
>> 
>> 
>> // Returns nil if path.rootType != self.valueType
>> 
>> 
>> func appending(path: AnyKeyPath) -> AnyKeyPath?
>> 
>> 
>> 
>> // MARK - Runtime Information
>> 
>> 
>> class var rootType: Any.Type
>> 
>> 
>> class var valueType: Any.Type
>> 
>> 
>> 
>> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
>> 
>> 
>> var hashValue: Int
>> }
>> 

Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Muse M via swift-evolution
I would suggest a keypath using ~ which is concise and clearer to identify.

let myPath = Person~friends[0].name





On Sunday, March 19, 2017, Jonathan Hull via swift-evolution <
swift-evolution@swift.org> wrote:

> This looks fantastic!
>
> The one worry I would have, as others have brought up, is confusion when
> there are static properties with the same name.  Maybe we could have a
> special static property called ‘keyPath’ or ‘path’ that would be reserved,
> and anything that followed would be a key path.
>
> So instead of:
>
> let myPath = Person.friends[0].name
>
> you would have:
>
> let myPath = Person.keyPath.friends[0].name
>
>
> Or if we want to choose a sentinel, I would nominate ‘$’:
>
> let myPath = $Person.friends[0].name
>
> Thanks,
> Jon
>
>
> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution <
> swift-evolution@swift.org
> > 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-
>- Authors: David Smith , Michael LeHew
>, Joe Groff 
>- Review Manager: TBD
>- Status: *Awaiting Review*
>- Associated PRs:
>   - #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.
> MotivationWe 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.
> More Expressive KeyPaths
>
> We would also like to support being able to use *Key Paths* to access
> into collections, which is not currently possible.
> Proposed solution
>
> We propose introducing a new expression akin to Type.method, but for
> properties and subscripts. These property reference expressions produce
> KeyPath objects, rather than Strings. KeyPaths are a family of generic
> classes *(structs and protocols here would be ideal, but requires
> generalized existentials)* which encapsulate a property reference or
> chain of property references, including the type, mutability, property
> name(s), and ability to set/get values.
>
> Here's a sample of it in use:
> Swift
>
> struct Person {
> var name: String
> var friends: [Person]
> var bestFriend: Person?}
> var han = Person(name: "Han Solo", friends: [])var luke = Person(name: "Luke 
> Skywalker", friends: [han])
> let firstFriendsNameKeyPath = Person.friends[0].name
> let firstFriend = luke[path] // han
> // or equivalently, with type inferred from contextlet firstFriendName = 
> luke[.friends[0].name]
> // rename Luke's first friend
> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
>
> Detailed designCore KeyPath Types
>
> KeyPaths are a hierarchy of progressively more specific classes, based on
> whether we have prior knowledge of the path through the object graph we
> wish to traverse.
> Unknown Path / Unknown Root Type
>
> AnyKeyPath is fully type-erased, referring to 'any route' through an
> object/value graph for 'any root'. Because of type-erasure many operations
> can fail at runtime and are thus nillable.
> Swift
>
> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
> // MARK - Composition
> // Returns nil if path.rootType != self.valueType
> func appending(path: AnyKeyPath) -> AnyKeyPath?
>
> // MARK - Runtime Information
> class var rootType: Any.Type
> class var valueType: Any.Type
>
> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
> var hashValue: Int}
>
> Unknown Path / Known Root Type
>
> If we know a little more type information (what kind of thing the key path
> is relative to), then we can use PartialKeyPath , which refers to
> an 'any route' from a known root:
> Swift
>
> class PartialKeyPath: AnyKeyPath {
> // MARK - Composition
> // Returns nil if Value != self.valueType
> func appending(path: 

Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Jonathan Hull via swift-evolution
This looks fantastic!

The one worry I would have, as others have brought up, is confusion when there 
are static properties with the same name.  Maybe we could have a special static 
property called ‘keyPath’ or ‘path’ that would be reserved, and anything that 
followed would be a key path.

So instead of:

let myPath = Person.friends[0].name

you would have:

let myPath = Person.keyPath.friends[0].name


Or if we want to choose a sentinel, I would nominate ‘$’:

let myPath = $Person.friends[0].name

Thanks,
Jon


> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution 
>  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-
> Authors: David Smith , Michael LeHew 
> , Joe Groff 
> Review Manager: TBD
> Status: Awaiting Review
> Associated PRs:
> #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.
> 
> More Expressive KeyPaths
> 
> We would also like to support being able to use Key Paths to access into 
> collections, which is not currently possible.
> 
> Proposed solution
> We propose introducing a new expression akin to Type.method, but for 
> properties and subscripts. These property reference expressions produce 
> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
> classes (structs and protocols here would be ideal, but requires generalized 
> existentials) which encapsulate a property reference or chain of property 
> references, including the type, mutability, property name(s), and ability to 
> set/get values.
> 
> Here's a sample of it in use:
> 
> Swift
> struct Person {
> var name: String
> var friends: [Person]
> var bestFriend: Person?
> }
> 
> var han = Person(name: "Han Solo", friends: [])
> var luke = Person(name: "Luke Skywalker", friends: [han])
> 
> let firstFriendsNameKeyPath = Person.friends[0].name
> 
> let firstFriend = luke[path] // han
> 
> // or equivalently, with type inferred from context
> let firstFriendName = luke[.friends[0].name]
> 
> // rename Luke's first friend
> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
> 
> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
> Detailed design
> Core KeyPath Types
> 
> KeyPaths are a hierarchy of progressively more specific classes, based on 
> whether we have prior knowledge of the path through the object graph we wish 
> to traverse. 
> 
> Unknown Path / Unknown Root Type
> 
> AnyKeyPath is fully type-erased, referring to 'any route' through an 
> object/value graph for 'any root'. Because of type-erasure many operations 
> can fail at runtime and are thus nillable. 
> 
> Swift
> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
> // MARK - Composition
> // Returns nil if path.rootType != self.valueType
> func appending(path: AnyKeyPath) -> AnyKeyPath?
> 
> // MARK - Runtime Information
> class var rootType: Any.Type
> class var valueType: Any.Type
> 
> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
> var hashValue: Int
> }
> Unknown Path / Known Root Type
> 
> If we know a little more type information (what kind of thing the key path is 
> relative to), then we can use PartialKeyPath , which refers to an 'any 
> route' from a known root:
> 
> Swift
> class PartialKeyPath: AnyKeyPath {
> // MARK - Composition
> // Returns nil if Value != self.valueType
> func appending(path: AnyKeyPath) -> PartialKeyPath?
> func appending(path: KeyPath) 
> -> KeyPath?
> func appending(path: ReferenceKeyPath AppendedValue>) -> ReferenceKeyPath?

Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Christopher Kornher via swift-evolution
I love the proposal and it is great to see this feature being considered. This 
provides a great foundation for future functionality. I too find the syntax 
confusing. The syntax is elegant and does not introduce any extra keywords, but 
accessing key paths is an advanced “meta” feature and does not have to be this 
straightforward. I would prefer less potential ambiguity at the expense of a 
little extra verbosity.

I suggest that the all keypaths be grouped under a `keypaths` pseudo-root path. 
This eliminates potential ambiguity with other language constructs and is 
easier for humans ( and as an added benefit, the compiler) to parse, reducing 
potential errors and clearer error diagnostics for name collisions and 
misspellings. Compiler reasoning and error messages are difficult enough deal 
with today. The use of a unique root for all keypaths will also greatly 
simplify searching for uses and code maintenance.

Many of the advanced language features that have been proposed for Swift add 
elegance and power to the language, but they have a cost in comprehensibility 
especially to beginners. The use of `keypaths` greatly improves the 
discoverability of this feature.

Another potential benefit of introducing a keyword-like construct now could 
simplifies the task of adding more metadata with other pseudo-root paths like 
`classKeypaths` and others as the language evolves.

Here is your example, rewritten with `keypaths` highlighted as a keyword. It 
does not add any additional nesting or operators, but clearly identifies the 
construct as something different and provides a simple term to search for in 
documentation.


struct Person {
var name: String
var friends: [Person]
var bestFriend: Person?
}

var han = Person(name: "Han Solo", friends: [])
var luke = Person(name: "Luke Skywalker", friends: [han])

let firstFriendsNameKeyPath = Person.keypaths.friends[0].name

let firstFriend = luke[keypaths.path] // han

// or equivalently, with type inferred from context
let firstFriendName = luke[keypaths.friends[0].name]

// rename Luke's first friend
luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"

let bestFriendsName = luke[keypaths.bestFriend]?.name  // nil, if he is the 
last jedi



> On Mar 17, 2017, at 12:27 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 17.03.2017 20:04, Michael LeHew via swift-evolution 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
>> ...
> 
> Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
> 
> Person.friends[0].name - like access to static property. T.method can't have 
> subscript for it and then some field. So, I believe such key paths deserve 
> its own syntax.
> 
> luke[path] - very close to access the subscript of instance. In compare to 
> T.method, we can call result of T.method(i.e. let m = T.method; m()), just 
> like the T.method itself(foo.method()). But here we are calling some kind of 
> subscript instead of access property by "path".
> 
> There is no some 'special' marker for me that saying "hey, there is 
> references to properties used" from the first look.
> 
> Probably we can consider another separators, like
> 
> Person:friends[0].name
> luke:path
> 
> Person->friends[0].name
> luke->path
> 
> Person[friends[0].name] // single brackets for type
> luke[[path]] // double brackets for instance
> 
> Person@friends[0].name
> luke@path
> 
> or other with help of community.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Colin Barrett via swift-evolution
It's so nice that this is finally seeing the light of day :) Great work
everyone!

Re: subscripts, it's definitely a great solution for "the Swift we have
now", but I'm not sure in "the Swift we'll have in a few years." If, for
instance, someday we're able to return inouts (or really just lvalues in
general), we'd be able to do a lot of this with regular functions and some
combinators.

Count me as a +1 for the Lisp-style syntax. If ` isn't to people's liking,
I wonder about @. I think both "luke @  .friends[0].name" and "
.friends[0].name @ luke" read quiet nicely, and gives the idea of a key
path as a kind of addressing scheme.

-Colin

P.S. Has anyone thought about writing an HTTP + JSON DSL with these?

On Fri, Mar 17, 2017 at 1:04 PM Michael LeHew via swift-evolution <
swift-evolution@swift.org> 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-
>- Authors: David Smith , Michael LeHew
>, Joe Groff 
>- Review Manager: TBD
>- Status: *Awaiting Review*
>- Associated PRs:
>   - #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.
> MotivationWe 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.
> More Expressive KeyPaths
>
> We would also like to support being able to use *Key Paths* to access
> into collections, which is not currently possible.
> Proposed solution
>
> We propose introducing a new expression akin to Type.method, but for
> properties and subscripts. These property reference expressions produce
> KeyPath objects, rather than Strings. KeyPaths are a family of generic
> classes *(structs and protocols here would be ideal, but requires
> generalized existentials)* which encapsulate a property reference or
> chain of property references, including the type, mutability, property
> name(s), and ability to set/get values.
>
> Here's a sample of it in use:
> Swift
>
> struct Person {
> var name: String
> var friends: [Person]
> var bestFriend: Person?}
> var han = Person(name: "Han Solo", friends: [])var luke = Person(name: "Luke 
> Skywalker", friends: [han])
> let firstFriendsNameKeyPath = Person.friends[0].name
> let firstFriend = luke[path] // han
> // or equivalently, with type inferred from contextlet firstFriendName = 
> luke[.friends[0].name]
> // rename Luke's first friend
> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
>
> Detailed designCore KeyPath Types
>
> KeyPaths are a hierarchy of progressively more specific classes, based on
> whether we have prior knowledge of the path through the object graph we
> wish to traverse.
> Unknown Path / Unknown Root Type
>
> AnyKeyPath is fully type-erased, referring to 'any route' through an
> object/value graph for 'any root'. Because of type-erasure many operations
> can fail at runtime and are thus nillable.
> Swift
>
> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
> // MARK - Composition
> // Returns nil if path.rootType != self.valueType
> func appending(path: AnyKeyPath) -> AnyKeyPath?
>
> // MARK - Runtime Information
> class var rootType: Any.Type
> class var valueType: Any.Type
>
> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
> var hashValue: Int}
>
> Unknown Path / Known Root Type
>
> If we know a little more type information (what kind of thing the key path
> is relative to), then we can use PartialKeyPath , which refers to
> an 'any route' from a known root:
> Swift
>
> class PartialKeyPath: AnyKeyPath {
> // MARK - Composition
> // Returns nil if Value != self.valueType
> func appending(path: AnyKeyPath) -> PartialKeyPath?
> func appending(path: KeyPath) 
> -> 

Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Matt Diephouse via swift-evolution

> On Mar 17, 2017, at 6:38 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 17, 2017, at 12:34 PM, David Hart via swift-evolution 
>> > 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 
>>> > wrote:
>>> 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

This might be my new favorite Swift feature. <3 It seems obvious in retrospect, 
which is surely a sign of its genius.

I would LOVE to be able to get the individual components in a path. Even if it 
were just the names, that would let me do some things that I’ve been itching to 
do in Swift. If the types were exposed in a type-erased container, that would 
be even better.

Something like this would be plenty of information to accomplish my goals:

class AnyKeyPath {
…

struct Key {
let name: String
let rootType: Any.Type
let valueType: Any.Type
}

private(set) var keys: [Key]
}

But even stringifying a key path would probably let me do most of what I 
wanted. I’d just need to (somewhat awkwardly) split on `.`s and handle 
subscripts. You mentioned that we’d have “limited” ability to stringify a key 
path. Can you elaborate on what that means or what the limitations would be?

Matt

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

2017-03-18 Thread Martijn Walraven via swift-evolution

> Smart KeyPaths: Better Key-Value Coding for Swift
> Proposal: SE-
> Authors: David Smith , Michael LeHew 
> , Joe Groff 
> Review Manager: TBD
> Status: Awaiting Review
> Associated PRs:
> #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
> 


Really happy to see this proposal! What isn’t clear to me is if/how this design 
could also be used for dynamic paths through collections. A concrete use case 
of this would be getting/setting values in a JSON response consisting of nested 
dictionaries and arrays.

I’ve recently started using a design similar to that described by Ole Begemann 
in this blog post: https://oleb.net/blog/2017/01/dictionary-key-paths/ 


That allows me to use strings as key paths to navigate a nested structure:
data[keyPath: “person.bestFriend.name"] = “Han Solo”

It uses labeled subscripts to get back values of a known type, which is useful 
if you want to modify an array for example:
data[arrayAt: “person.friends"]?.append(["name": “Luke Skywalker”])

Generic subscripts might make this more elegant, although it seems you’d still 
need a way to provide enough context to let the type be inferred, and I’m not 
sure where that information would come from with these dynamic structures.

Curious to hear if this proposal would help with use cases like this!

Martijn___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


  1   2   >