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] [Pitch] String revision proposal #1

2017-03-29 Thread Xiaodi Wu via swift-evolution
This looks great. The restored conformances to *Collection will be huge.

Is this to be the first of several or the only major part of the manifesto
to be delivered in Swift 4?

Nits on naming: are we calling it Substring or SubString (à la
SubSequence)? and shouldn't it be UnicodeParsedResult rather than
UnicodeParseResult?


On Wed, Mar 29, 2017 at 19:32 Ben Cohen via swift-evolution <
swift-evolution@swift.org> wrote:

Hi Swift Evolution,

Below is a pitch for the first part of the String revision. This covers a
number of changes that would allow the basic internals to be overhauled.

Online version here:
https://github.com/airspeedswift/swift-evolution/blob/3a822c799011ace682712532cfabfe32e9203fbb/proposals/0161-StringRevision1.md


String Revision: Collection Conformance, C Interop, Transcoding

   - Proposal: SE-0161
   - Authors: Ben Cohen , Dave Abrahams
   
   - Review Manager: TBD
   - Status: *Awaiting review*

Introduction

This proposal is to implement a subset of the changes from the Swift 4
String Manifesto
.

Specifically:

   - Make String conform to BidirectionalCollection
   - Make String conform to RangeReplaceableCollection
   - Create a Substring type for String.SubSequence
   - Create a Unicode protocol to allow for generic operations over both
   types.
   - Consolidate on a concise set of C interop methods.
   - Revise the transcoding infrastructure.

Other existing aspects of String remain unchanged for the purposes of this
proposal.
Motivation

This proposal follows up on a number of recommendations found in the
manifesto:

Collection conformance was dropped from String in Swift 2. After
reevaluation, the feeling is that the minor semantic discrepancies (mainly
with RangeReplaceableCollection) are outweighed by the significant benefits
of restoring these conformances. For more detail on the reasoning, see here


While it is not a collection, the Swift 3 string does have slicing
operations. String is currently serving as its own subsequence, allowing
substrings to share storage with their “owner”. This can lead to memory
leaks when small substrings of larger strings are stored long-term (see here

for
more detail on this problem). Introducing a separate type of Substring to
serve as String.Subsequence is recommended to resolve this issue, in a
similar fashion to ArraySlice.

As noted in the manifesto, support for interoperation with nul-terminated C
strings in Swift 3 is scattered and incoherent, with 6 ways to transform a
C string into a String and four ways to do the inverse. These APIs should
be replaced with a simpler set of methods on String.
Proposed solution

A new type, Substring, will be introduced. Similar to ArraySlice it will be
documented as only for short- to medium-term storage:

*Important*
Long-term storage of Substring instances is discouraged. A substring holds
a reference to the entire storage of a larger string, not just to the
portion it presents, even after the original string’s lifetime ends.
Long-term storage of a substring may therefore prolong the lifetime of
elements that are no longer otherwise accessible, which can appear to be
memory leakage.

Aside from minor differences, such as having a SubSequence of Self and a
larger size to describe the range of the subsequence, Substring will be
near-identical from a user perspective.

In order to be able to write extensions accross both String and Substring,
a new Unicode protocol to which the two types will conform will be
introduced. For the purposes of this proposal, Unicode will be defined as a
protocol to be used whenver you would previously extend String. It should
be possible to substitute extension Unicode { ... } in Swift 4
wherever extension
String { ... } was written in Swift 3, with one exception: any passing of
self into an API that takes a concrete String will need to be rewritten as
String(self). If Self is a String then this should effectively optimize to
a no-op, whereas if Self is a Substring then this will force a copy,
helping to avoid the “memory leak” problems described above.

The exact nature of the protocol – such as which methods should be protocol
requirements vs which can be implemented as protocol extensions, are
considered implementation details and so not covered in this proposal.

Unicode will conform to BidirectionalCollection.
RangeReplaceableCollection conformance
will be added directly onto the String and Substring types, as it is
possible future Unicode-conforming types might not be range-replaceable
(e.g. an immutable type that wraps a const char *).

The C string interop methods will be updated to those described here

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


[swift-evolution] [Pitch] String revision proposal #1

2017-03-29 Thread Ben Cohen via swift-evolution
Hi Swift Evolution,

Below is a pitch for the first part of the String revision. This covers a 
number of changes that would allow the basic internals to be overhauled.

Online version here: 
https://github.com/airspeedswift/swift-evolution/blob/3a822c799011ace682712532cfabfe32e9203fbb/proposals/0161-StringRevision1.md
 



String Revision: Collection Conformance, C Interop, Transcoding

Proposal: SE-0161 

Authors: Ben Cohen , Dave Abrahams 

Review Manager: TBD
Status: Awaiting review
Introduction

This proposal is to implement a subset of the changes from the Swift 4 String 
Manifesto .

Specifically:

Make String conform to BidirectionalCollection
Make String conform to RangeReplaceableCollection
Create a Substring type for String.SubSequence
Create a Unicode protocol to allow for generic operations over both types.
Consolidate on a concise set of C interop methods.
Revise the transcoding infrastructure.
Other existing aspects of String remain unchanged for the purposes of this 
proposal.

Motivation

This proposal follows up on a number of recommendations found in the manifesto:

Collection conformance was dropped from String in Swift 2. After reevaluation, 
the feeling is that the minor semantic discrepancies (mainly with 
RangeReplaceableCollection) are outweighed by the significant benefits of 
restoring these conformances. For more detail on the reasoning, see here 

While it is not a collection, the Swift 3 string does have slicing operations. 
String is currently serving as its own subsequence, allowing substrings to 
share storage with their “owner”. This can lead to memory leaks when small 
substrings of larger strings are stored long-term (see here 
 
for more detail on this problem). Introducing a separate type of Substring to 
serve as String.Subsequence is recommended to resolve this issue, in a similar 
fashion to ArraySlice.

As noted in the manifesto, support for interoperation with nul-terminated C 
strings in Swift 3 is scattered and incoherent, with 6 ways to transform a C 
string into a String and four ways to do the inverse. These APIs should be 
replaced with a simpler set of methods on String.

Proposed solution

A new type, Substring, will be introduced. Similar to ArraySlice it will be 
documented as only for short- to medium-term storage:

Important

Long-term storage of Substring instances is discouraged. A substring holds a 
reference to the entire storage of a larger string, not just to the portion it 
presents, even after the original string’s lifetime ends. Long-term storage of 
a substring may therefore prolong the lifetime of elements that are no longer 
otherwise accessible, which can appear to be memory leakage.
Aside from minor differences, such as having a SubSequence of Self and a larger 
size to describe the range of the subsequence, Substring will be near-identical 
from a user perspective.

In order to be able to write extensions accross both String and Substring, a 
new Unicode protocol to which the two types will conform will be introduced. 
For the purposes of this proposal, Unicode will be defined as a protocol to be 
used whenver you would previously extend String. It should be possible to 
substitute extension Unicode { ... } in Swift 4 wherever extension String { ... 
} was written in Swift 3, with one exception: any passing of self into an API 
that takes a concrete String will need to be rewritten as String(self). If Self 
is a String then this should effectively optimize to a no-op, whereas if Self 
is a Substring then this will force a copy, helping to avoid the “memory leak” 
problems described above.

The exact nature of the protocol – such as which methods should be protocol 
requirements vs which can be implemented as protocol extensions, are considered 
implementation details and so not covered in this proposal.

Unicode will conform to BidirectionalCollection. RangeReplaceableCollection 
conformance will be added directly onto the String and Substring types, as it 
is possible future Unicode-conforming types might not be range-replaceable 
(e.g. an immutable type that wraps a const char *).

The C string interop methods will be updated to those described here 
:
 a single withCString operation and two init(cString:) constructors, one for 
UTF8 and one for arbitrary encodings. The primary change is to remove 
“non-repairing” variants of construction from nul-terminated C strings. In both 
of the construction 

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] Disallowing unreachable code

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

> On Mar 29, 2017, at 4:21 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Mar 29, 2017, at 4:14 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Mar 29, 2017, at 8:11 AM, John McCall via swift-evolution 
>>>  wrote:
>>> 
>>> I was suggesting that it would be a useful addition to the language, not 
>>> that it
>>> necessarily needed new compiler support.
>> 
>> Personally, what I'd like to see is for the existing <#whatever#> 
>> placeholder syntax to be treated as an unimplemented() call. That probably 
>> *would* require compiler support, although fortunately we already parse this 
>> syntax into an EditorPlaceholderExpr.
> 
> Actually, looking more closely, we already have this behavior in playgrounds 
> (and REPLs); it's only an error when you compile. Like, we literally do this:
> 
>   // Found it. Flag it as error (or warning, if in playground mode) for 
> the
>   // rest of the compiler pipeline and lex it as an identifier.
>   if (LangOpts.Playground) {
> diagnose(TokStart, diag::lex_editor_placeholder_in_playground);
>   } else {
> diagnose(TokStart, diag::lex_editor_placeholder);
>   }
> 
> Could we change the compile-time error into a warning? Would that require an 
> evolution proposal?

Ah, you beat me to it. I would support reducing this to a warning.

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


Re: [swift-evolution] Disallowing unreachable code

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

> On Mar 29, 2017, at 8:11 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On Mar 29, 2017, at 9:15 AM, Alex Blewitt  wrote:
>>> On 29 Mar 2017, at 14:10, Jonathan Hull  wrote:
>>> 
>>> I think the idea is that it also adds a warning so you can find it later.
>> 
>> @available(*, deprecated, message: "Don't forget to implement this")
>> func unimplemented(_ file:String = #file,_ line:Int = #line) -> T {
>>   fatalError("Not implemented \(file):\(line)")
>> }
>> 
>> let f: String = unimplemented()
> 
> I was suggesting that it would be a useful addition to the language, not that 
> it
> necessarily needed new compiler support.
> 
> Does someone want to write a proposal for it?

Placeholder expressions in fact have this exact behavior in "playgrounds mode" 
already. We could easily make it so that placeholders warn rather than error in 
normal source code as well.

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


Re: [swift-evolution] Disallowing many expressions with unused result (@error_unused_result?)

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

> On Mar 24, 2017, at 3:57 PM, Peter Dillinger via swift-evolution 
>  wrote:
> 
> I recently criticized Swift 3 for allowing many expressions with no side 
> effects as statements, in this blog post: 
> https://blogs.synopsys.com/software-integrity/2017/03/24/swift-programming-language-design-part-2/
>  (search for "that expression").  I've seen some related discussion such as 
> "Make non-void functions @warn_unused_result by default", but not quite this.
> 
> For emphasis, let me include a real example (from open-source software, 
> simplified) of defective JavaScript code that happens to be legal Swift as 
> well:
> 
> var html = "" +
>  "" +
>  trs
>  "" +
>  "";
> 
> DEFECT SPOILER:   (There is a 
> missing '+')
> 
> Part of my argument is that people commonly ignore compiler warnings.  We see 
> lots of defective code that would be (or is) caught by compiler warnings but 
> people don't pay attention.
> 
> I have not formulated this into a detailed proposal, but I suspect that 
> because of Swift's pervasive overloading, implicit constructor calls, etc., 
> it would involve introducing a new @error_unused_result annotation and using 
> that in many places in the standard library.  I also suggest that user 
> overloads of traditionally non-side-effecting operators, as well as 
> non-mutating struct methods, be @error_unused_result by default, or perhaps 
> by mandate.  Our experience also suggests this @error_unused_result feature 
> could also be useful for ordinary methods of classes, as we find a number of 
> defects where a method call is expecting a side effect but there is none, 
> because the method is only useful for its return value.

In the Swift 3 timeframe, we adopted pretty much exactly these rules, albeit 
making value-producing operations *warn* by default instead of error. There's 
already a @discardableResult attribute that you can apply to declarations whose 
result is intended to be discardable. The philosophy of warnings vs errors is 
being discussed in your thread on unreachable code, so I don't think it needs 
to be reiterated here.

-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 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] Disallowing unreachable code

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 29, 2017, at 4:14 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 29, 2017, at 8:11 AM, John McCall via swift-evolution 
>> > wrote:
>> 
>> I was suggesting that it would be a useful addition to the language, not 
>> that it
>> necessarily needed new compiler support.
> 
> Personally, what I'd like to see is for the existing <#whatever#> placeholder 
> syntax to be treated as an unimplemented() call. That probably *would* 
> require compiler support, although fortunately we already parse this syntax 
> into an EditorPlaceholderExpr.

Actually, looking more closely, we already have this behavior in playgrounds 
(and REPLs); it's only an error when you compile. Like, we literally do this:

  // Found it. Flag it as error (or warning, if in playground mode) for the
  // rest of the compiler pipeline and lex it as an identifier.
  if (LangOpts.Playground) {
diagnose(TokStart, diag::lex_editor_placeholder_in_playground);
  } else {
diagnose(TokStart, diag::lex_editor_placeholder);
  }

Could we change the compile-time error into a warning? Would that require an 
evolution proposal?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 29, 2017, at 8:11 AM, John McCall via swift-evolution 
>  wrote:
> 
> I was suggesting that it would be a useful addition to the language, not that 
> it
> necessarily needed new compiler support.

Personally, what I'd like to see is for the existing <#whatever#> placeholder 
syntax to be treated as an unimplemented() call. That probably *would* require 
compiler support, although fortunately we already parse this syntax into an 
EditorPlaceholderExpr.

-- 
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] [Review] SE-0160: Limiting @objc inference

2017-03-29 Thread Hooman Mehr via swift-evolution

> On Mar 29, 2017, at 3:00 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
> * @implicitobjc added to a class implicitly makes members of that class *and 
> all of its subclasses* @objc if they can be exposed to Objective-C
> * @implicitobjc added to a class extension makes members of that class 
> extension @objc if they can be exposed to Objective-C
> 
> This is a more elegant way to handle the XCTestCase issue—we can mark 
> XCTestCase as @implicitobjc through some Clang-side attribute or API note—and 
> makes it easy for class hierarchies that rely heavily on the Objective-C 
> runtime to continue to get @objc inference.

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


Re: [swift-evolution] [Review] SE-0160: Limiting @objc inference

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

> On Mar 23, 2017, at 2:06 AM, Slava Pestov via swift-evolution 
>  wrote:
> 
> Here’s an idea for working around the problem of the lack of static knowledge 
> during migration. Probably it’s kind of tacky and won’t get much traction in 
> it’s current form, but it might start some useful discussion at least.
> 
> Right now, @objc when applied to a _class_ is completely useless; if a class 
> ultimately inherits from NSObject, it is always implicitly @objc, and 
> applying @objc to a class not rooted in NSObject is always an error. (I think 
> at some point in the past we allowed @objc classes that _don’t_ inherit from 
> NSObject, but I don’t know if that even made it into any released version of 
> Swift, so it’s totally vestigial at this point.) We can keep this behavior in 
> Swift 3 mode, but in Swift 4 mode, change things so that @objc applied to a 
> class enables @objc inference for the members of the class, and the absence 
> of @objc enables the new, more limited inference behavior outlined in this 
> proposal.
> 
> Then the migration story can just be “slap @objc on every NSObject-derived 
> class and you’re good”. Existing mixed source bases, KVC, and so on would 
> just work. We could also say that in Swift 4 mode, @objc on an 
> NSObject-derived class produces a warning asking the developer to consider 
> making individual members @objc as necessary instead. This would allow a 
> Swift 4 migration to proceed in two phases — first fix any fallout from 
> SE-0110 or new string stuff or whatever, and get a working app that builds 
> and runs in Swift 4 mode, albeit with some warnings. Then they can deal with 
> marking individual class members as @objc later. We could still have the 
> option of making it an error to apply @objc to an entire class in a future 
> release of Swift, if we decide it is beneficial to do so.

I don’t think we should repurpose @objc to mean “infer @objc if possible”, but 
we could add a new attribute—you’d mentioned @objcMembers somewhere before, 
I’ll refer to it as @implicitobjc” here—that one could added to classes or 
extensions. The semantics could be:

* @implicitobjc added to a class implicitly makes members of that class *and 
all of its subclasses* @objc if they can be exposed to Objective-C
* @implicitobjc added to a class extension makes members of that class 
extension @objc if they can be exposed to Objective-C

This is a more elegant way to handle the XCTestCase issue—we can mark 
XCTestCase as @implicitobjc through some Clang-side attribute or API note—and 
makes it easy for class hierarchies that rely heavily on the Objective-C 
runtime to continue to get @objc inference.

- Doug

> 
> Based on feedback, the all-or-nothing nature of the Swift 2->3 migration was 
> rather painful — mixing and matching 3 and 4 modules will definitely help us 
> do better the next time around, and allowing a complex change such as this 
> one to be done piecemeal could be a further step in the right direction.
> 
> Slava
> 
>> On Mar 21, 2017, at 11:03 PM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> Hello Swift community, 
>> 
>> The review of "SE-0160: Limiting @objc inference" begins now and runs 
>> through March 28. The proposal is available here:
>> 
>>  
>> https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md
>> 
>> Reviews are an important part of the Swift evolution process. All reviews 
>> should be sent to the swift-evolution mailing list at:
>> 
>>  https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager. 
>> 
>> 
>> What goes into a review?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and, eventually, determine the direction of 
>> Swift. When writing your review, here are some questions you might want to 
>> answer in your review:
>> 
>> * What is your evaluation of the proposal?
>> * Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> * Does this proposal fit well with the feel and direction of Swift?
>> * If you have you used other languages or libraries with a similar feature, 
>> how do you feel that this proposal compares to those?
>> * How much effort did you put into your review? A glance, a quick reading, 
>> or an in-depth study? 
>> 
>> More information about the Swift evolution process is available at:
>>  https://github.com/apple/swift-evolution/blob/master/process.md 
>> 
>> Thanks!
>> 
>> -Chris Lattner
>> Review Manager
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> 

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] [Pitch] Allow closures/default params to satisfy protocol requirements

2017-03-29 Thread Jonathan Hull via swift-evolution
I would be in favor of some sugar allowing optional methods eventually.  I am 
kind of waiting to see how the reflection API shakes out.

I know there was some sort of argument on the list before about it being bad 
design to have optional methods, but I still really like it as a pattern.  In 
swift, I tend to use optional callback closures instead of delegate methods to 
achieve the same pattern of enabling or disabling some feature based on whether 
it is there or not.  For example, last week I wrote some code that lets me 
quickly build a table to edit data structures. When editing an array, there is 
an optional ‘moveCallback’ closure.  If it is there, then the rows of the table 
can be reordered in the UI, and if it isn’t the UI doesn’t show the reordering 
handles. Same with ‘deleteCallback' and whether there is UI to delete a row 
from the array.

I think that basing behavior based on what is possible (or not possible) due to 
the availability of methods is very intuitive. (But then I have been 
programming ObjC for almost 20 years, so that may be influencing my thinking. 
It probably seems strange to those coming from less dynamic languages.)

Thanks,
Jon

> On Mar 28, 2017, at 12:37 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> Theoretically speaking optional could potentially become some language sugar 
> right?
> 
> protocol P {
> // Variable with label
> var foo(a:) : ((Int) -> Void)? { get }
>  
> // more sugared version
> var foo: ((a: Int) -> Void)? { get }
> }
> 
> extension P {
> // (1)
> var foo: ((a: Int) -> Void)? { return nil }
> }
> 
> // Everything from above with even more sugar
> protocol P {
> // default implementation (1) is inferred
> optional func foo(a: Int)
> }
> 
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> 
> ___
> 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] Disallowing unreachable code

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

> On Mar 24, 2017, at 3:54 PM, Peter Dillinger via swift-evolution 
>  wrote:
> 
> I don't see anything directly relevant to this in the archives, and I haven't 
> prepared a detailed proposal.  But I'm raising the general idea because I 
> recently criticized Swift 3 for allowing unreachable code in a blog post: 
> https://blogs.synopsys.com/software-integrity/2017/03/24/swift-programming-language-design-part-2/
>  (search for "unreachable code").  And I want you to have every opportunity 
> to rectify this, even though I'm in the business of finding defects the 
> compiler doesn't.  :)
> 
> Part of my argument is that people commonly ignore compiler warnings.  We see 
> lots of defective code that would be (or is) caught by compiler warnings but 
> people don't pay attention.

That's a fair concern, but unlike C compilers, where warnings vary widely among 
implementations and often aren't even on by default, Swift's warnings are 
considered as part of the language design and can't be turned off, so there's 
less opportunity or excuse to ignore them.

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


Re: [swift-evolution] [swift-build-dev] [Draft] Package Manager Custom Targets Layout

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

> On Mar 29, 2017, at 10:56, Ankit Aggarwal  wrote:
> 
> We discussed variadic overloads during the manifest redesign proposal but 
> ultimately rejected it. We could add an overload for a singular source file 
> (instead of variadic) but I think its simpler to just have one option, and it 
> is also easier when you want to extend your source list form one to two.

K, seems reasonable.

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


Re: [swift-evolution] [swift-build-dev] [Draft] Package Manager Custom Targets Layout

2017-03-29 Thread Ankit Aggarwal via swift-evolution
We discussed variadic overloads during the manifest redesign proposal but 
ultimately rejected 

 it. We could add an overload for a singular source file (instead of variadic) 
but I think its simpler to just have one option, and it is also easier when you 
want to extend your source list form one to two.

I think parsing is not a concern because tools are expected to ask for JSON 
representation and not directly parse the swift file.


> On 29-Mar-2017, at 11:18 PM, David Sweeris  wrote:
> 
> 
> On Mar 29, 2017, at 10:19, Ankit Aggarwal via swift-build-dev 
> > wrote:
> 
>> The proposal 
>> 
>>  is updated with this change.
> 
> What do we think about adding convenience inits that take a single parameter 
> in place of the []s, for when we're only passing one value?
> 
> The down side is that it makes it more complicated for 3rd party tools to 
> parse. Dunno if that's a concern.
> 
> - Dave Sweeris

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


Re: [swift-evolution] [swift-build-dev] [Draft] Package Manager Custom Targets Layout

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

On Mar 29, 2017, at 10:19, Ankit Aggarwal via swift-build-dev 
 wrote:

> The proposal is updated with this change.

What do we think about adding convenience inits that take a single parameter in 
place of the []s, for when we're only passing one value?

The down side is that it makes it more complicated for 3rd party tools to 
parse. Dunno if that's a concern.

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


Re: [swift-evolution] [swift-build-dev] [Draft] Package Manager Custom Targets Layout

2017-03-29 Thread Ankit Aggarwal via swift-evolution
Oops, I had pressed reply instead reply all. The proposal

is
updated with this change.

On Mon, Mar 27, 2017 at 12:32 PM, Ankit Aggarwal 
wrote:

> Hi Brent,
>
> I agree, this sounds like a reasonable thing to do. We can probably emit a
> warning when its set to an empty array.
>
> Thanks!
>
> On Mon, Mar 27, 2017 at 10:57 AM, Brent Royal-Gordon via swift-build-dev <
> swift-build-...@swift.org> wrote:
>
>> On Mar 24, 2017, at 1:26 PM, Ankit Aggarwal via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> sources: This property defines the source files to be included in the
>> target, relative to the target path. The default value of this property
>> will be an empty array, which means all valid source files found in the
>> target's path will be included.
>>
>>
>> Stupid little niggle: could this be an optional array with a default
>> value of `nil`? It seems more natural to treat the absence of a `sources`
>> list as meaning "auto-detect" than to treat an empty `sources` list that
>> way.
>>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>>
>> ___
>> swift-build-dev mailing list
>> swift-build-...@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-build-dev
>>
>>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread John McCall via swift-evolution
> On Mar 29, 2017, at 12:55 AM, Peter Dillinger  
> wrote:
>>> On Mar 28, 2017, at 9:40 PM, Peter Dillinger  
>>> wrote:
 Agreed, we have the right design here.  The go community has shown the 
 result of taking
 a hard line on this, and it really hurts refactoring and other 
 experimental “pound out some
 code” prototyping use cases.  We use warnings for things that “should be 
 cleaned up before
 code is committed”, but which is not itself a fatal issue.
>>> 
>>> Missing 'try' is a fatal issue?
>> 
>> That could be argued I suppose, I was referring to unreachable code, unused 
>> variables,
>> variables that are never mutated, etc.
> 
> And what about non-exhaustive switch?
> 
> Both of these existing rules seem to violate the principle claimed, because 
> they are hazards to incomplete or experimental changes that might lead people 
> to use quick fixes (try!; default) that are not associated with a warning, 
> whereas a warning instead of the error would (as you claim) signal to the 
> user there are pending fixes before commit.
> 
> In theory, your position seems defensible, but I'm not seeing consistency in 
> application.

Non-exhaustive switch is like a missing return statement: the code isn't just 
"suspicious", it's potentially unsound if the warning is correct.  That's not 
true of unreachable code or ignored return values.  We could, of course, invent 
semantics for it, like implicitly asserting or implicitly falling through; but 
the former is inconsistent with our safety goals, and the second is likely to 
just lead to worse downstream diagnostics.

You're correct that enforcing "try" as a hard error is not consistent with 
being lax about experimental code, but the entire point of "try" is to reliably 
mark places that can throw; making it only a warning would completely undermine 
that.  If we had a language mode focused on experimental code, then yes, it 
would be appropriate to disable the "try" diagnostic; but adding a language 
mode like that would be really destructive long-term, outside of specific 
situations like coding in the debugger.

I would say that the "incomplete" side of the coin is more important to us than 
the "experimental" side.  We don't want laxer rules for experimental code 
because in practice there's usually no bright line between prototypes and 
production.  But if our hand isn't being forced, and we don't have strong 
language-design reasons to enforce the rule, a warning is fine.

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread John McCall via swift-evolution
> On Mar 29, 2017, at 9:15 AM, Alex Blewitt  wrote:
>> On 29 Mar 2017, at 14:10, Jonathan Hull > > wrote:
>> 
>> I think the idea is that it also adds a warning so you can find it later.
> 
> @available(*, deprecated, message: "Don't forget to implement this")
> func unimplemented(_ file:String = #file,_ line:Int = #line) -> T {
>   fatalError("Not implemented \(file):\(line)")
> }
> 
> let f: String = unimplemented()

I was suggesting that it would be a useful addition to the language, not that it
necessarily needed new compiler support.

Does someone want to write a proposal for it?

John.

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Alex Blewitt via swift-evolution

> On 29 Mar 2017, at 14:10, Jonathan Hull  wrote:
> 
> I think the idea is that it also adds a warning so you can find it later.

@available(*, deprecated, message: "Don't forget to implement this")
func unimplemented(_ file:String = #file,_ line:Int = #line) -> T {
  fatalError("Not implemented \(file):\(line)")
}

let f: String = unimplemented()

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Jonathan Hull via swift-evolution
I think the idea is that it also adds a warning so you can find it later.


> On Mar 29, 2017, at 6:06 AM, Alex Blewitt  wrote:
> 
> On 29 Mar 2017, at 11:38, Jonathan Hull via swift-evolution 
> > wrote:
>> 
>> 
>>> On Mar 27, 2017, at 11:27 AM, John McCall via swift-evolution 
>>> > wrote:
>>> 
>>> In fact, we should probably double-down on this design and add an 
>>> "unimplemented" expression that always triggers warnings and just traps if 
>>> you try to evaluate it. That expression would be a logical thing to use in 
>>> e.g. code snippets automatically inserted by an IDE.
>> 
>> Yes, please.
> 
> 
> You can do this already:
> 
> func unimplemented(_ file:String = #file,_ line:Int = #line) -> T {
>   fatalError("Not implemented \(file):\(line)")
> }
> 
> let f: String = unimplemented()
> 
> 

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Alex Blewitt via swift-evolution
On 29 Mar 2017, at 11:38, Jonathan Hull via swift-evolution 
 wrote:
> 
> 
>> On Mar 27, 2017, at 11:27 AM, John McCall via swift-evolution 
>> > wrote:
>> 
>> In fact, we should probably double-down on this design and add an 
>> "unimplemented" expression that always triggers warnings and just traps if 
>> you try to evaluate it. That expression would be a logical thing to use in 
>> e.g. code snippets automatically inserted by an IDE.
> 
> Yes, please.


You can do this already:

func unimplemented(_ file:String = #file,_ line:Int = #line) -> T {
  fatalError("Not implemented \(file):\(line)")
}

let f: String = unimplemented()


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


Re: [swift-evolution] Disallowing unreachable code

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

> On Mar 27, 2017, at 11:27 AM, John McCall via swift-evolution 
>  wrote:
> 
> In fact, we should probably double-down on this design and add an 
> "unimplemented" expression that always triggers warnings and just traps if 
> you try to evaluate it. That expression would be a logical thing to use in 
> e.g. code snippets automatically inserted by an IDE.

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


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Haravikk via swift-evolution

> On 24 Mar 2017, at 22:54, Peter Dillinger via swift-evolution 
>  wrote:
> 
> I don't see anything directly relevant to this in the archives, and I haven't 
> prepared a detailed proposal.  But I'm raising the general idea because I 
> recently criticized Swift 3 for allowing unreachable code in a blog post: 
> https://blogs.synopsys.com/software-integrity/2017/03/24/swift-programming-language-design-part-2/
>  (search for "unreachable code").  And I want you to have every opportunity 
> to rectify this, even though I'm in the business of finding defects the 
> compiler doesn't.  :)
> 
> Part of my argument is that people commonly ignore compiler warnings.  We see 
> lots of defective code that would be (or is) caught by compiler warnings but 
> people don't pay attention.

Which people? Personally warnings bug me no end; I'm not happy until they're 
all dealt with, so a warning is more than sufficient in my case.

While obviously writing unreachable code on purpose isn't the best way to do 
something, sometimes throwing some code into an if (false) or dropping in an 
early return to see if it fixes or triggers a problem is a perfectly reasonable 
way to do something in a quick and dirty way.

IMO a warning is more than sufficient for this, so that the programmer is 
reminded to go back and fix it.

I don't know if it's possible to elevate specific warnings to errors (I used to 
do this working with Java in Eclipse but have never wanted to in Xcode), if not 
then that may be worth considering as an alternative? But as a default I think 
a warning is sufficient, at least for me, as I'd rather be able to make code 
unreachable than have an error when it is.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Disallowing unreachable code

2017-03-29 Thread Brent Royal-Gordon via swift-evolution
> On Mar 28, 2017, at 9:55 PM, Peter Dillinger via swift-evolution 
>  wrote:
> 
>>> Missing 'try' is a fatal issue?
>> 
>> That could be argued I suppose, I was referring to unreachable code, unused 
>> variables,
>> variables that are never mutated, etc.
> 
> And what about non-exhaustive switch?
> 
> Both of these existing rules seem to violate the principle claimed, because 
> they are hazards to incomplete or experimental changes that might lead people 
> to use quick fixes (try!; default) that are not associated with a warning, 
> whereas a warning instead of the error would (as you claim) signal to the 
> user there are pending fixes before commit.

Here's a different principle: When Swift generates a warning, the mistake has 
no runtime effect on the behavior of the code, but things like non-exhaustive 
`switch` or a missing `try` represent code where you haven't told the compiler 
how to handle some of the circumstances it might encounter.

If you stick a `return` in the middle of some code, the compiler knows exactly 
how to interpret that: Return there and don't run the code after it. If you 
write a non-exhaustive `switch`, what is the compiler supposed to do? Fall out 
of `switch` statement? Trap? It's unclear. Similarly, if there's no 
`try`—particularly outside of a `do`/`catch` block or `throws` function—what 
behavior should the compiler assume you want?

Trapping is clearly the proper choice, because Swift's philosophy is to trap 
whenever the program finds itself in a state that the programmer did not 
anticipate. And yet you don't want the *lack* of something to cause a trap; you 
should at least be able to see the operation so you have a chance to recognize 
the potential to trap. (Implicitly unwrapped optionals are the exception that 
proves the rule--many programmers ban them because they cause invisible 
trapping. You don't want people banning `switch` or `throw` statements because 
of their invisible danger.) Any other option, though, runs the risk of letting 
a program run off the rails and do the wrong thing.

So we emit an error in these cases because the programmer has written ambiguous 
code, and the compiler has no good option for resolving the ambiguity. On the 
other hand, if you use `var` instead of `let`, or write code after a `return`, 
the instructions your code is giving the compiler are unambiguous; they're just 
not phrased as well as they could be. So we emit a program that does what your 
code says and politely point out that you could write it better.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Pitch] Allow closures/default params to satisfy protocol requirements

2017-03-29 Thread Adrian Zubarev via swift-evolution
I will consider your advice, it’s actually a replay good one. :) I guess it was 
the iOS development influence from Objective-C that let me write such not 
swifty delegates.



-- 
Adrian Zubarev
Sent with Airmail

Am 29. März 2017 um 04:07:38, Slava Pestov (spes...@apple.com) schrieb:


On Mar 28, 2017, at 12:10 AM, Adrian Zubarev  
wrote:

It’s probably the influence from iOS development where I have delegate 
protocols like this one:

@objc public protocol _ContainerViewControllerDelegate: class {
  
@objc optional func containerViewController(_ containerViewController: 
ContainerViewController,
willPerform operation: 
ContainerViewController.Operation,
from oldViewController: 
UIViewController,
to newViewController: 
UIViewController,
animated: Bool)
  
@objc optional func containerViewController(_ containerViewController: 
ContainerViewController,
didPerform operation: 
ContainerViewController.Operation,
from oldViewController: 
UIViewController,
to newViewController: 
UIViewController,
animated: Bool)
  
@objc optional func containerViewController(_ containerViewController: 
ContainerViewController,
willSet oldViewControllers: 
[UIViewController],
to newViewControllers: 
[UIViewController],
animated: Bool)
  
@objc optional func containerViewController(_ containerViewController: 
ContainerViewController,
didSet newViewControllers: 
[UIViewController],
from oldViewControllers: 
[UIViewController],
animated: Bool)
}

This looks like a bad API to begin with. If I was designing something like this 
I would instead have a single containerViewController() method or something 
that takes a value which encodes the various states.

You could have something like this:

enum ViewControllerState {
  case willPerform(…)
  case didPerform(…)
  case willSet(…)
  case didSet(…)
}

Slava
Implementing noops for each function in an extension seems kind of a wrong 
decision for a few reasons:

They don’t make sense, because either the receiver implements a function or 
not. So optional functions provide a more natural solution to that problem.

We don’t have to pass unnecessarily any arguments to the top functions.

(Personal preference) I tend to avoid @objc in general. 

I think there was some technical reason why we don’t have optional functions in 
pure Swift yet, something that also affects dynamic if I’m not mistaken.

Think of the protocol from above as of an existential of a set of functions. 
The problem is that, I don’t want to introduce a standalone protocol for every 
function, so the client can decide which protocol it will conform to to avoid 
these noops. Furthermore, it’s way easier to check for an optional function in 
your control flow instead of dealing with default values delegate functions 
with a more complex return type might have.




-- 
Adrian Zubarev
Sent with Airmail

Am 28. März 2017 um 07:31:50, Slava Pestov (spes...@apple.com) schrieb:


On Mar 27, 2017, at 1:48 PM, Adrian Zubarev via swift-evolution 
 wrote:

Assuming we’ll get that functionality, both var and let should satisfy the 
protocol requirements right?

In theory, there’s no reason not to allow that.

If it is valid, could we potentially get optional functions in pure Swift as 
well?


I mean, you can already do this:

protocol P {
  var optionalRequirement: ((Int) -> ())? { get }
}

extension P {
  // “default implementation"
  var optionalRequirement: ((Int) -> ())? { return nil }
}

struct A : P {}

struct B : P {
  let optionalRequirement: ((Int) -> ())? = { (x: Int) in print(x) }
}

But it’s kind of tacky.

If you think about it, “optional requirement” is an oxymoron. What’s your 
use-case?

Slava

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


Re: [swift-evolution] Disallowing unreachable code

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

On Mar 28, 2017, at 21:55, Peter Dillinger via swift-evolution 
 wrote:

 On Mar 28, 2017, at 9:40 PM, Peter Dillinger 
  wrote:
 Agreed, we have the right design here.  The go community has shown the 
 result of taking
 a hard line on this, and it really hurts refactoring and other 
 experimental “pound out some
 code” prototyping use cases.  We use warnings for things that “should be 
 cleaned up before
 code is committed”, but which is not itself a fatal issue.
>>> 
>>> Missing 'try' is a fatal issue?
>> 
>> That could be argued I suppose, I was referring to unreachable code, unused 
>> variables,
>> variables that are never mutated, etc.
> 
> And what about non-exhaustive switch?

Switches are required to be exhaustive in Swift, but code is not required to be 
called.

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