Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 17, 2017, at 2:42 PM, Itai Ferber  wrote:
> 
> On 16 Mar 2017, at 14:29, Matthew Johnson wrote:
> 
> 
> This is a fantastic proposal! I am very much looking forward to robust 
> Swift-native encoding and decoding in Foundation. The compiler synthesized 
> conformances is especially great! I want to thank everyone who worked on it. 
> It is clear that a lot of work went into the proposal.
> 
> The proposal covers a lot of ground so I’m breaking my comments up by topic 
> in the order the occur in the proposal.
> 
> Thanks for the feedback, Matthew! Responses inline.
> 
> 

And thank you for the responses!

> 
> Encode / Decode only types:
> 
> Brent raised the question of decode only types. Encode only types are also 
> not uncommon when an API accepts an argument payload that gets serialized 
> into the body of a request. The compiler synthesis feature in the proposal 
> makes providing both encoding and decoding easy in common cases but this 
> won’t always work as needed.
> 
> The obvious alternative is to have Decodable and Encodable protocols which 
> Codable refines. This would allow us to omit a conformance we don’t need when 
> it can’t be synthesized.
> 
> If conformances are still synthesized individually (i.e. for just Decodable 
> or just Encodable), it would be way too easy to accidentally conform to one 
> or the other and not realize that you’re not conforming to Codable, since the 
> synthesis is invisible. You’d just be missing half of the protocol.
> 
This is the kind of mistake people don’t tend to make often and Swift’s typing 
will alert someone pretty quickly if they make this mistake.  A fixit could 
even be offered if the type is in the same module as it is used incorrectly.  I 
really don’t think it’s that big a deal to expect people to understand the 
differences.  They already need to understand encoders and decoders to make use 
of these protocols and this is just the other side of that distinction.
> If the way out of this is to only synthesize conformance to Codable, then 
> it’s much harder to justify the inclusion of Encodable or Decodable since 
> those would require a manual implementation and would much more rarely be 
> used.
> 
I wouldn’t limit synthesis in that way.

This isn’t that big a deal given that synthesis will do the work for us most of 
the time but I think it’s unfortunate to see these coupled.  There will be 
times when we have to choose between fatalError and maintaining code we don’t 
need.  That’s a bad choice to have to make.  I don’t like designs that impose 
it on me.

> 
> Your reply to Brent mentions using `fatalError` to avoid implementing the 
> direction that isn't needed. I think it would be better if the conformance 
> can reflect what is actually supported by the type. Requiring us to write 
> `fatalError` as a stub for functionality we don’t need is a design problem 
> IMO. I don’t think the extra protocols are really that big a burden. They 
> don’t add any new functionality and are very easy to understand, especially 
> considering the symmetry they would have with the other types you are 
> introducing.
> 
> Coding Keys:
> 
> As others have mentioned, the design of this protocol does not require a 
> value of a conforming type to actually be a valid key (it can return nil for 
> both `intValue` and `stringValue`). This seems problematic to me.
> 
> In the reply to Brent again you mention throwing and `preconditionFailure` as 
> a way to handle incompatible keys. This also seems problematic to me and 
> feels like a design problem. If we really need to support more than one 
> underlying key type and some encoders will reject some key types this 
> information should be captured in the type system. An encoder would only vend 
> a keyed container for keys it actually supports. Ideally the conformance of a 
> type’s CodingKeys could be leveraged to produce a compiler error if an 
> attempt was made to encode this type into an encoder that can’t support its 
> keys. In general, the idea is to produce static errors as close to the origin 
> of the programming mistake as possible.
> 
> I would very much prefer that we don’t defer to runtime assertions or thrown 
> errors, etc for conditions that could be caught statically at compile time 
> given the right design. Other comments have indicated that static guarantees 
> are important to the design (encoders *must* guarantee support of primitives 
> specified by the protocols, etc). Why is a static guarantee of compatible 
> coding keys considered less important?
> 
> I agree that it would be nice to support this in a static way, but while not 
> impossible to represent in the type system, it absolutely explodes the API 
> into a ton of different types and protocols which are not dissimilar. We’ve 
> considered this in the past (see approach #4 in the Alternatives Considered 
> 

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 17, 2017, at 3:23 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Mar 16, 2017, at 12:33 PM, Itai Ferber > > wrote:
>> Optional values are accepted and vended directly through the API. The 
>> encode(_:forKey:) methods take optional values directly, and 
>> decodeIfPresent(_:forKey:) vend optional values.
>> 
>> Optional is special in this way — it’s a primitive part of the system. It’s 
>> actually not possible to write an encode(to:) method for Optional, since the 
>> representation of null values is up to the encoder and the format it’s 
>> working in; JSONEncoder, for instance, decides on the representation of nil 
>> (JSON null).
>> 
> Yes—I noticed that later but then forgot to revise the beginning. Sorry about 
> that.
>> It wouldn’t be possible to ask nil to encode itself in a reasonable way.
>> 
> I really think it could be done, at least for most coders. I talked about 
> this in another email, but in summary:
> 
> NSNull would become a primitive type; depending on the format, it would be 
> encoded either as a null value or the absence of a value.
> Optional.some(x) would be encoded the same as x.
> Optional.none would be encoded in the following fashion:
> If the Wrapped associated type was itself an optional type, it would be 
> encoded as a keyed container containing a single entry. That entry's key 
> would be some likely-unique value like "_swiftOptionalDepth"; its value would 
> be the number of levels of optionality before reaching a non-optional type.
> If the Wrapped associated type was non-optional, it would be encoded as an 
> NSNull.
> 
> That sounds complicated, but the runtime already has machinery to coerce 
> Optionals to Objective-C id: Optional.some gets bridged as the Wrapped value, 
> while Optional.none gets bridged as either NSNull or _SwiftNull, which 
> contains a depth. We would simply need to make _SwiftNull conform to Codable, 
> and give it a decoding implementation which was clever enough to realize when 
> it was being asked to decode a different type.
>> What about a more complex enum, like the standard library's 
>> `UnicodeDecodingResult`:
>> 
>> enum UnicodeDecodingResult {
>> case emptyInput
>> case error
>> case scalarValue(UnicodeScalar)
>> }
>> 
>> Or, say, an `Error`-conforming type from one of my projects:
>> 
>> public enum SQLError: Error {
>> case connectionFailed(underlying: Error)
>> case executionFailed(underlying: Error, statement: SQLStatement)
>> case noRecordsFound(statement: SQLStatement)
>> case extraRecordsFound(statement: SQLStatement)
>> case columnInvalid(underlying: Error, key: ColumnSpecifier, statement: 
>> SQLStatement)
>> case valueInvalid(underlying: Error, key: AnySQLColumnKey, statement: 
>> SQLStatement)
>> }
>> 
>> (You can assume that all the types in the associated values are `Codable`.)
>> 
>> Sure — these cases specifically do not derive Codable conformance because 
>> the specific representation to choose is up to you. Two possible ways to 
>> write this, though there are many others (I’m simplifying these cases here a 
>> bit, but you can extrapolate this):
>> 
> Okay, so tl;dr is "There's nothing special to help with this; just encode 
> some indication of the case in one key, and the associated values in separate 
> keys". I suppose that works.
>> Have you given any consideration to supporting types which only need to 
>> decode? That seems likely to be common when interacting with web services.
>> 
>> We have. Ultimately, we decided that the introduction of several protocols 
>> to cover encodability, decodability, and both was too much of a cognitive 
>> overhead, considering the number of other types we’re also introducing. You 
>> can always implement encode(to:) as fatalError().
>> 
> I understand that impulse.
>> Structured types (i.e. types which encode as a collection of properties) 
>> encode and decode their properties in a keyed manner. Keys may be 
>> String-convertible or Int-convertible (or both),
>> 
>> What does "may" mean here? That, at runtime, the encoder will test for the 
>> preferred key type and fall back to the other one? That seems a little bit 
>> problematic.
>> 
>> Yes, this is the case. A lot is left up to the Encoder because it can choose 
>> to do something for its format that your implementation of encode(to:) may 
>> not have considered.
>> If you try to encode something with an Int key in a string-keyed dictionary, 
>> the encoder may choose to stringify the integer if appropriate for the 
>> format. If not, it can reject your key, ignore the call altogether, 
>> preconditionFailure(), etc. It is also perfectly legitimate to write an 
>> Encoder which supports a flat encoding format — in that case, keys are 
>> likely ignored altogether, in which case there is no error to be had. We’d 
>> like to not arbitrarily constrain an implementation unless necessary.
>> 
> Wait, what? If it's ignoring the keys altogether, how does it know what to 
>

Re: [swift-evolution] Swift's reflection

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

> On Mar 17, 2017, at 3:42 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> I hope that Mirror will ultimately be superseded by key paths:
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033998.html
>  
> 
> 
> Key paths address the mutability limitations of mirror, and give you the 
> ability to work with arbitrary values in a dictionary-like way that Mirror 
> does without an intermediary type. While the initial key path proposal lacks 
> the dynamic discovery of key paths by name/index/etc., that would be a 
> natural future direction to go in. Being able to build or query key paths 
> dynamically would also solve other problems with Mirror, such as not being 
> able to discover the structure of a value without an instance of the value.

This all sounds so incredible!  I’m really looking forward to dynamic discovery 
and manipulation of key paths, especially without needing an instance of the 
type to do it.  It can’t come soon enough - I already have a project where it 
could come in very handy!

> 
> -Joe
> 
>> On Mar 16, 2017, at 2:38 PM, Slava Pestov via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Adding write reflection to the existing Mirrors implementation should not be 
>> too difficult and we would accept a well-written PR that adds this 
>> capability.
>> 
>> Slava
>> 
>>> On Mar 15, 2017, at 8:10 AM, Dimitri Racordon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hello fellow evolutionists,
>>> 
>>> I’d like to ask if someone knows about the current state of affairs of the 
>>> evolution of the reflection API in Swift.
>>> I read it was (or at least used to be) in the scope of Swift 4 to improve 
>>> on the current capabilities, but failed to see any proposal in that 
>>> direction since then. I found this evolution post 
>>> (https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003401.html
>>>  
>>> )
>>>  from quite a while ago, and would like to know if anything progressed 
>>> since then.
>>> 
>>> As a domain specific languages designer, reflection is an essential feature 
>>> for me. Unfortunately I think Swift is quite behind regarding that point. 
>>> Most specifically, the inability to set properties discovered from a mirror 
>>> (without resorting to the black magic of unsafe pointers) has a huge impact 
>>> on the simplicity of embedded DSLs.
>>> 
>>> Thanks,
>>> Dimitri Racordon
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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


Sent from my iPhone

> On Mar 17, 2017, at 3:36 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 17, 2017, at 12:49 PM, Itai Ferber  wrote:
>> 
>> On 17 Mar 2017, at 12:18, Michael Gottesman wrote:
>> 
>> 
>> On Mar 16, 2017, at 10:23 AM, Joe Groff via swift-evolution 
>>  wrote:
>> 
>> On Mar 16, 2017, at 10:21 AM, Itai Ferber  wrote:
>> 
>> On 15 Mar 2017, at 19:12, Joe Groff wrote:
>> 
>> 
>> On Mar 15, 2017, at 6:46 PM, Itai Ferber  wrote:
>> 
>> Thanks Joe, and thanks for passing this along!
>> 
>> To those who are curious, we use abstract base classes for a cascading list 
>> of reasons:
>> 
>> • We need to be able to represent keyed encoding and decoding containers as 
>> abstract types which are generic on a key type
>> • There are two ways to support abstraction in this way: protocol & type 
>> constraints, and generic types
>> • Since Swift protocols are not generic, we unfortunately cannot write 
>> protocol KeyedEncodingContainer { ... }, which is the 
>> "ideal" version of what we're trying to represent
>> • Let's try this with a protocol first (simplified here):
>> 
>> protocol Container {
>> associatedtype Key : CodingKey
>> }
>> 
>> func container(_ type: Key.Type) -> Cont 
>> where Cont.Key == Key {
>> // return something
>> }
>> 
>> This looks promising so far — let's try to make it concrete:
>> 
>> struct ConcreteContainer : Container {
>> typealias Key = K
>> }
>> 
>> func container(_ type: Key.Type) -> Cont 
>> where Cont.Key == Key {
>> return ConcreteContainer() // error: Cannot convert return expression 
>> of type 'ConcreteContainer' to return type 'Cont'
>> }
>> 
>> Joe or anyone from the Swift team can describe this better, but this is my 
>> poor-man's explanation of why this happens. Swift's type constraints are 
>> "directional" in a sense. You can constrain a type going into a function, 
>> but not out of a function. There is no type I could return from inside of 
>> container() which would satisfy this constraint, because the constraint can 
>> only be satisfied by turning Cont into a concrete type from the outside.
>> 
>> Okay, well let's try this:
>> 
>> func container... {
>> return ConcreteContainer() as! Cont
>> }
>> 
>> This compiles fine! Hmm, let's try to use it:
>> 
>> container(Int.self) // error: Generic parameter 'Cont' could not be inferred
>> 
>> The type constraint can only be fulfilled from the outside, not the inside. 
>> The function call itself has no context for the concrete type that this 
>> would return, so this is a no-go.
>> 
>> • If we can't do it with type constraints in this way, is it possible with 
>> generic types? Yep! Generic types satisfy this without a problem. However, 
>> since we don't have generic protocols, we have to use a generic abstract 
>> base class to represent the same concept — an abstract container generic on 
>> the type of key which dynamically dispatches to the "real" subclassed type
>> 
>> Hopes that gives some simplified insight into the nature of this decision.
>> 
>> I see. Protocols with associated types serve the same purpose as generic 
>> interfaces in other languages, but we don't have the first-class support for 
>> protocol types with associated type constraints (a value of type `Container 
>> where Key == K`). That's something we'd like to eventually support. In other 
>> places in the standard library, we wrtie the type-erased container by hand, 
>> which is why we have `AnySequence`, `AnyCollection`, and `AnyHashable`. You 
>> could probably do something similar here; that would be a bit awkward for 
>> implementers, but might be easier to migrate forward to where we eventually 
>> want to be with the language.
>> 
>> -Joe
>> 
>> Yep, that’s a good way to describe it.
>> We could potentially do that as well, but adding another type like 
>> AnyHashable or AnyCollection felt like a much more sweeping change, 
>> considering that those require some special compiler magic themselves (and 
>> we’d like to do as little of that as we can).
>> 
>> AnyCollection doesn't have any special compiler magic. AnyHashable's only 
>> magic is that it has implicit conversions, but that would become normal 
>> behavior once it can be replaced by a plain Hashable existential type.
>> 
>> Hey Itai. I am not sure if I missed this. But did you follow up with why you 
>> didn't want to use AnyCollection/AnyHashable? The thread got really long 
>> pretty fast.
>> 
>> I responded to this in a different part of the thread very recently. Can you 
>> elaborate on how a type like AnyCollection/AnyHashable would help here? More 
>> important than the type erasure is the type being generic on the key type, 
>> and this must be specified. How would this be possible
>> 
>> 
> 
> You can implement an AnyContainer type that conforms to the Container 
> protocol, using an abstract base class that erases the type, and a private 
> subclass that forwards the interface to a contained value. 
> https://www.bignerdranch.com/blog/breakin

Re: [swift-evolution] Smart KeyPaths

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

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

This proposal is really incredible!  It is an invaluable addition to the 
language - far better than simple first-class properties.  I really can’t wait 
to see it implemented!  The design looks very solid.  I’m especially happy to 
see that a path to eventually get away from using classes has already been 
identified and planned for.

Thank you so much for bringing this forward in Swift 4.  It is a wonderful (and 
rather unexpected) surprise!

Seeing this makes me *really* wish we had a way to get at a collection of 
`PartialKeyPath` for all the (visible) properties of a type.  I guess the 
visible part of that makes it tricky.  We can always work around it in the 
meantime.

> 
> Many thanks,
> -Michael
> 
> Smart KeyPaths: Better Key-Value Coding for Swift
> Proposal: SE-
> Authors: David Smith , Michael LeHew 
> , Joe Groff 
> Review Manager: TBD
> Status: Awaiting Review
> Associated PRs:
> #644 
> Introduction
> We propose a family of concrete Key Path types that represent uninvoked 
> references to properties that can be composed to form paths through many 
> values and directly get/set their underlying values.
> 
> Motivation
> We Can Do Better than String
> 
> On Darwin platforms Swift's existing #keyPath() syntax provides a convenient 
> way to safely refer to properties. Unfortunately, once validated, the 
> expression becomes a String which has a number of important limitations:
> 
> Loss of type information (requiring awkward Any APIs)
> Unnecessarily slow to parse
> Only applicable to NSObjects
> Limited to Darwin platforms
> Use/Mention Distinctions
> 
> While methods can be referred to without invoking them (let x = foo.bar 
> instead of  let x = foo.bar()), this is not currently possible for properties 
> and subscripts.
> 
> Making indirect references to a properties' concrete types also lets us 
> expose metadata about the property, and in the future additional behaviors.
> 
> More Expressive KeyPaths
> 
> We would also like to support being able to use Key Paths to access into 
> collections, which is not currently possible.
> 
> Proposed solution
> We propose introducing a new expression akin to Type.method, but for 
> properties and subscripts. These property reference expressions produce 
> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
> classes (structs and protocols here would be ideal, but requires generalized 
> existentials) which encapsulate a property reference or chain of property 
> references, including the type, mutability, property name(s), and ability to 
> set/get values.
> 
> Here's a sample of it in use:
> 
> Swift
> struct Person {
> var name: String
> var friends: [Person]
> var bestFriend: Person?
> }
> 
> var han = Person(name: "Han Solo", friends: [])
> var luke = Person(name: "Luke Skywalker", friends: [han])
> 
> let firstFriendsNameKeyPath = Person.friends[0].name
> 
> let firstFriend = luke[path] // han
> 
> // or equivalently, with type inferred from context
> let firstFriendName = luke[.friends[0].name]
> 
> // rename Luke's first friend
> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
> 
> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
> Detailed design
> Core KeyPath Types
> 
> KeyPaths are a hierarchy of progressively more specific classes, based on 
> whether we have prior knowledge of the path through the object graph we wish 
> to traverse. 
> 
> Unknown Path / Unknown Root Type
> 
> AnyKeyPath is fully type-erased, referring to 'any route' through an 
> object/value graph for 'any root'. Because of type-erasure many operations 
> can fail at runtime and are thus nillable. 
> 
> Swift
> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
> // MARK - Composition
> // Returns nil if path.rootType != self.valueType
> func appending(path: AnyKeyPath) -> AnyKeyPath?
> 
> // MARK - Runtime Information
> class var rootType: Any.Type
> class var valueType: Any.Type
> 
> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
> var hashValue: Int
> }
> Unknown Path / Known Root Type
> 
> If we know a little more type information (what kind of thing the key path is 
> relative to), then we can use PartialKeyPath , which refers to an 'any 
> route' from a known root:
> 
> Swift
> class PartialKeyPath: AnyKeyPath {
> // MARK - Composition
> // Returns nil if Value != self.valueType
> func appending(path: AnyKeyPath) -> PartialKeyPath?
> func appending(path: KeyPath) 
> -> KeyPath?
> func appending(path: ReferenceKeyPath AppendedValue>) -> ReferenceKeyPath?
> }

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 17, 2017, at 5:13 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 17, 2017, at 2:38 PM, Matthew Johnson > > wrote:
>> 
>>> At a broad level, that's a good idea. But why not provide something more 
>>> precise than a bag of `Any`s here? You're in pure Swift; you have that 
>>> flexibility.
>>> 
>>> protocol Codable {
>>> associatedtype CodingContext = ()
>>> 
>>> init(from decoder: Coder, with context: 
>>> CodingContext) throws
>>> func encoder(from encoder: Coder, with context: 
>>> CodingContext) throws
>>> }
>>> protocol Encoder {
>>> associatedtype CodingContext = ()
>>> 
>>> func container(keyedBy type: Key.Type) -> 
>>> KeyedEncodingContainer
>>> …
>>> }
>>> class KeyedEncodingContainer {
>>> func encode(_ value: Value,? forKey key: Key, 
>>> with context: Value.CodingContext) throws { … }
>>> 
>>> // Shorthand when contexts are the same:
>>> func encode(_ value: Value,? forKey key: Key) 
>>> throws
>>> where Value.CodingContext == CodingContext
>>> { … }
>>> 
>>> …
>>> }
>> 
>> This is sort of similar to the design I suggested for contexts.  The 
>> difference is that you’re requiring all Codable to be context aware and by 
>> introducing an associated type you break the ability to use Codable as an 
>> existential.
> 
> I don't think banning existentials is actually a loss. Since `encode(_:)` 
> doesn't record type information, and instead `decode(_:)` requires the exact 
> concrete type to be passed in, `Codable` existentials cannot be usefully 
> encoded or decoded. For instance, a heterogeneous `[Codable]` would encode in 
> several different, probably mutually incompatible formats, without any type 
> information that could distinguish between them. Since the only semantics of 
> `Codable` are encoding and decoding, and decoding is always done by an 
> `init`, `Codable` existentials are useless and we lose nothing by not 
> supporting them.

That’s fair.  But how would you change the design of the NSKeyedArchiver / 
NSKeyedUnarchiver extensions which use the existentials? 

> 
>> Many Codable conforming types won’t need to know anything about a context.  
>> I would still want to be able to encode them along with my custom 
>> context-aware types.  A good example is types from Foundation that will 
>> conform to Codable.  They will definitely not know anything about my context 
>> but I still want to be able to encode a URL alongside my custom 
>> context-aware types.
> 
> Sure; you can do that by calling `encode(_:forKey:with:)` and passing a 
> freshly-made `()` context. We might even add a second convenience overload of 
> `encode(_:forKey:)`:
> 
>   class KeyedEncodingContainer {
>   func encode(_ value: Value,? forKey key: Key, 
> with context: Value.CodingContext) throws { … }
>   
>   // Shorthand when contexts are the same:
>   func encode(_ value: Value,? forKey key: Key) 
> throws
>   where Value.CodingContext == CodingContext
>   {
>   try encode(value, forKey: key, with: currentContext)
>   }
>   
>   // Shorthand when the type uses a Void context:
>   func encode(_ value: Value,? forKey key: Key) 
> throws
>   where Value.CodingContext == Void
>   {
>   try encode(value, forKey: key, with: ())
>   }
>   
>   …
>   }
> 
> The main disadvantage I can think of in this design is that even `Codable` 
> users who don't need a context have to have a `with context: Void` in their 
> code. This might be confusing to new developers, but I think it's worth it.
> 
> (I don't think I mentioned this anywhere, but containers like `Array` should 
> take on the `CodingContext` of their `Element`s and pass the context they 
> receive through without examining it. That would probably be pretty common 
> with generic container types.)

You’re right - I just wasn’t thinking about this clearly.  I missed that you 
were requiring Codable types to manually thread the context through.  This is 
kind of unfortunate when *all* types involved in the encoding either have a 
Void context or use the same context type.  On the other hand, it is a somewhat 
rarely needed feature and this approach offers a lot of flexibility.  I think I 
like it.

> 
>> Did you take a look at the design I suggested?  What do you think of it?
> 
> I think that, if a type wants to support context-free coding, it should use 
> an optional `CodingContext`. :^)
> 
> In all seriousness, I see the design as very slightly weak, in that it makes 
> it easy to forget to pass a context through, but quite acceptable.

Easy for who?  I was not re

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

> On Mar 17, 2017, at 5:17 PM, Michael LeHew  wrote:
> 
> 
>>> On Mar 17, 2017, at 3:08 PM, Matthew Johnson  wrote:
>>> 
>>> 
>>> On Mar 17, 2017, at 12:04 PM, Michael LeHew via swift-evolution 
>>>  wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>> 
>> This proposal is really incredible!  It is an invaluable addition to the 
>> language - far better than simple first-class properties.  I really can’t 
>> wait to see it implemented!  The design looks very solid.  I’m especially 
>> happy to see that a path to eventually get away from using classes has 
>> already been identified and planned for.
>> 
>> Thank you so much for bringing this forward in Swift 4.  It is a wonderful 
>> (and rather unexpected) surprise!
>> 
>> Seeing this makes me *really* wish we had a way to get at a collection of 
>> `PartialKeyPath` for all the (visible) properties of a type.  I guess 
>> the visible part of that makes it tricky.  We can always work around it in 
>> the meantime.
> 
> We had discussed that a future application where KeyPath's would make a lot 
> of sense is with the Mirror API.  Of course in the interest of the finiteness 
> of time, we aren't pursuing that right now. 
> 
> One thing that gets interesting with the scope-restricted visibility of 
> KeyPaths, is what happens if an fileprivate KeyPath gets leaked out of the 
> file?  That's a scary/maybe useful thing?  But a complication that emerges 
> pretty quick and thus another reason not to pursue that just now.  

Yep, totally understand.  :)  The interaction with access control will 
definitely have some subtleties to consider.

Is the plan to allow a type to manually vend a KeyPath wider than the 
visibility of properties in the path?  It looks that way and that's probably 
the right call.

> 
>> 
>>> 
>>> Many thanks,
>>> -Michael
>>> 
>>> Smart KeyPaths: Better Key-Value Coding for Swift
>>> Proposal: SE-
>>> Authors: David Smith, Michael LeHew, Joe Groff
>>> Review Manager: TBD
>>> Status: Awaiting Review
>>> Associated PRs:
>>> #644
>>> Introduction
>>> We propose a family of concrete Key Path types that represent uninvoked 
>>> references to properties that can be composed to form paths through many 
>>> values and directly get/set their underlying values.
>>> 
>>> Motivation
>>> We Can Do Better than String
>>> 
>>> On Darwin platforms Swift's existing #keyPath() syntax provides a 
>>> convenient way to safely refer to properties. Unfortunately, once 
>>> validated, the expression becomes a String which has a number of important 
>>> limitations:
>>> 
>>> Loss of type information (requiring awkward Any APIs)
>>> Unnecessarily slow to parse
>>> Only applicable to NSObjects
>>> Limited to Darwin platforms
>>> Use/Mention Distinctions
>>> 
>>> While methods can be referred to without invoking them (let x = foo.bar 
>>> instead of  let x = foo.bar()), this is not currently possible for 
>>> properties and subscripts.
>>> 
>>> Making indirect references to a properties' concrete types also lets us 
>>> expose metadata about the property, and in the future additional behaviors.
>>> 
>>> More Expressive KeyPaths
>>> 
>>> We would also like to support being able to use Key Paths to access into 
>>> collections, which is not currently possible.
>>> 
>>> Proposed solution
>>> We propose introducing a new expression akin to Type.method, but for 
>>> properties and subscripts. These property reference expressions produce 
>>> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
>>> classes (structs and protocols here would be ideal, but requires 
>>> generalized existentials) which encapsulate a property reference or chain 
>>> of property references, including the type, mutability, property name(s), 
>>> and ability to set/get values.
>>> 
>>> Here's a sample of it in use:
>>> 
>>> Swift
>>> struct Person {
>>> var name: String
>>> var friends: [Person]
>>> var bestFriend: Person?
>>> }
>>> 
>>> var han = Person(name: "Han Solo", friends: [])
>>> var luke = Person(name: "Luke Skywalker", friends: [han])
>>> 
>>> let firstFriendsNameKeyPath = Person.friends[0].name
>>> 
>>> let firstFriend = luke[path] // han
>>> 
>>> // or equivalently, with type inferred from context
>>> let firstFriendName = luke[.friends[0].name]
>>> 
>>> // rename Luke's first friend
>>> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
>>> 
>>> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last 
>>> jedi
>>> Detailed design
>>> Core KeyPath Types
>>> 
>>> KeyPaths are a hierarchy of progressively more specific classes, based on 
>>> whether we have prior knowledge of the path through the object graph we 
>>> wish to traverse. 
>>> 
>>> Unknown Path / Unknown Root Type
>>> 
>>> AnyKeyPath is fully type-erased, referring to 'any route' through an 
>>> object/value graph for 'any root'. Because of type-

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

> On Mar 17, 2017, at 5:24 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 17, 2017, at 3:17 PM, Michael LeHew via swift-evolution 
>>  wrote:
>> 
>> One thing that gets interesting with the scope-restricted visibility of 
>> KeyPaths, is what happens if an fileprivate KeyPath gets leaked out of the 
>> file?  That's a scary/maybe useful thing?
> 
> 
> I think that, as long as code within the `fileprivate` scope is responsible 
> for passing the KeyPath out, that's an *extremely* useful thing. It 
> essentially lets a privileged scope delegate its access to a less-privileged 
> scope so it can do complex, potentially read-write work on its behalf. 
> Imagine keeping an instance variable private, but allowing a serialization 
> framework to access it through a key path; that'd be pretty handy.

Agree.  As long as it is manually vended it is semantically pretty similar to 
passing a closure that reads or writes.  That's the way I would think about it.

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


Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

> On Mar 17, 2017, at 5:45 PM, Joe Groff  wrote:
> 
> 
>>> On Mar 17, 2017, at 3:08 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> On Mar 17, 2017, at 12:04 PM, Michael LeHew via swift-evolution 
>>>  wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>> 
>> This proposal is really incredible!  It is an invaluable addition to the 
>> language - far better than simple first-class properties.  I really can’t 
>> wait to see it implemented!  The design looks very solid.  I’m especially 
>> happy to see that a path to eventually get away from using classes has 
>> already been identified and planned for.
>> 
>> Thank you so much for bringing this forward in Swift 4.  It is a wonderful 
>> (and rather unexpected) surprise!
>> 
>> Seeing this makes me *really* wish we had a way to get at a collection of 
>> `PartialKeyPath` for all the (visible) properties of a type.  I guess 
>> the visible part of that makes it tricky.  We can always work around it in 
>> the meantime.
> 
> Yeah, that's a natural future extension. We're intentionally trying to keep 
> the initial core functionality small to keep discussion focused (and also 
> make good use of limited design and implementation time).

That makes sense, especially considering the nuances around access control.  
I'm ecstatic to see even just the basic functionality making it into Swift 4!

> 
> -Joe
> 
>> 
>>> 
>>> Many thanks,
>>> -Michael
>>> 
>>> Smart KeyPaths: Better Key-Value Coding for Swift
>>> Proposal: SE-
>>> Authors: David Smith, Michael LeHew, Joe Groff
>>> Review Manager: TBD
>>> Status: Awaiting Review
>>> Associated PRs:
>>> #644
>>> Introduction
>>> We propose a family of concrete Key Path types that represent uninvoked 
>>> references to properties that can be composed to form paths through many 
>>> values and directly get/set their underlying values.
>>> 
>>> Motivation
>>> We Can Do Better than String
>>> 
>>> On Darwin platforms Swift's existing #keyPath() syntax provides a 
>>> convenient way to safely refer to properties. Unfortunately, once 
>>> validated, the expression becomes a String which has a number of important 
>>> limitations:
>>> 
>>> Loss of type information (requiring awkward Any APIs)
>>> Unnecessarily slow to parse
>>> Only applicable to NSObjects
>>> Limited to Darwin platforms
>>> Use/Mention Distinctions
>>> 
>>> While methods can be referred to without invoking them (let x = foo.bar 
>>> instead of  let x = foo.bar()), this is not currently possible for 
>>> properties and subscripts.
>>> 
>>> Making indirect references to a properties' concrete types also lets us 
>>> expose metadata about the property, and in the future additional behaviors.
>>> 
>>> More Expressive KeyPaths
>>> 
>>> We would also like to support being able to use Key Paths to access into 
>>> collections, which is not currently possible.
>>> 
>>> Proposed solution
>>> We propose introducing a new expression akin to Type.method, but for 
>>> properties and subscripts. These property reference expressions produce 
>>> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
>>> classes (structs and protocols here would be ideal, but requires 
>>> generalized existentials) which encapsulate a property reference or chain 
>>> of property references, including the type, mutability, property name(s), 
>>> and ability to set/get values.
>>> 
>>> Here's a sample of it in use:
>>> 
>>> Swift
>>> struct Person {
>>> var name: String
>>> var friends: [Person]
>>> var bestFriend: Person?
>>> }
>>> 
>>> var han = Person(name: "Han Solo", friends: [])
>>> var luke = Person(name: "Luke Skywalker", friends: [han])
>>> 
>>> let firstFriendsNameKeyPath = Person.friends[0].name
>>> 
>>> let firstFriend = luke[path] // han
>>> 
>>> // or equivalently, with type inferred from context
>>> let firstFriendName = luke[.friends[0].name]
>>> 
>>> // rename Luke's first friend
>>> luke[firstFriends

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

> On Mar 17, 2017, at 5:38 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 17, 2017, at 12:34 PM, David Hart via swift-evolution 
>>  wrote:
>> 
>> Sent off-list by mistake:
>> 
>> Nice proposal. I have a few comments inline:
>> 
>>> On 17 Mar 2017, at 18:04, Michael LeHew via swift-evolution 
>>>  wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>>> 
>>> Many thanks,
>>> -Michael
>>> 
>>> Smart KeyPaths: Better Key-Value Coding for Swift
>>> Proposal: SE-
>>> Authors: David Smith, Michael LeHew, Joe Groff
>>> Review Manager: TBD
>>> Status: Awaiting Review
>>> Associated PRs:
>>> #644
>>> Introduction
>>> We propose a family of concrete Key Path types that represent uninvoked 
>>> references to properties that can be composed to form paths through many 
>>> values and directly get/set their underlying values.
>>> 
>>> Motivation
>>> We Can Do Better than String
>>> 
>>> On Darwin platforms Swift's existing #keyPath() syntax provides a 
>>> convenient way to safely refer to properties. Unfortunately, once 
>>> validated, the expression becomes a String which has a number of important 
>>> limitations:
>>> 
>>> Loss of type information (requiring awkward Any APIs)
>>> Unnecessarily slow to parse
>>> Only applicable to NSObjects
>>> Limited to Darwin platforms
>>> Use/Mention Distinctions
>>> 
>>> While methods can be referred to without invoking them (let x = foo.bar 
>>> instead of  let x = foo.bar()), this is not currently possible for 
>>> properties and subscripts.
>>> 
>>> Making indirect references to a properties' concrete types also lets us 
>>> expose metadata about the property, and in the future additional behaviors.
>>> 
>> What metadata is attached? How is it accessed? What future features are you 
>> thinking about?
> 
> To begin with, you'd have limited ability to stringify a key path. Eventually 
> we'd like to support other reflectiony things, including:
> 
> - Asking for the primary key paths a type supports
> - Asking for a key by name or index
> - Breaking a key path down by components
> 
> I also see key path objects as a good way of eventually addressing some of 
> the design problems we ran up against with property behaviors 
> (https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
>  from last year), including the problem of what exactly a property behavior 
> declaration *is* (a type? a protocol? a function-like thing? something 
> completely new?), and the problem of handling "out-of-band" operations on a 
> property beyond getting and setting, such as clearing a cached lazy value, 
> registering for notifications on an observable property, and so on. I think 
> it would be natural to express property behaviors as a user-defined key path 
> type; the key path type can provide the get/set logic for the property as 
> well as any other interesting operations the property supports. This answers 
> the questions of both what behaviors look like (they're just types that 
> conform to KeyPath) and how they extend properties with new actions (they're 
> just methods of the key path value) fairly nicely.

Very interesting!  This sounds like it would enable a very nice design in a 
project I'm working on right now.  I'm looking forward to seeing this take 
shape in the future.

It sounds like it wouldn't solve one use case I was hoping property behaviors 
might solve though.  Sometimes we have a property that we would like to make a 
constant but cont because we can't set it until phase 2.  I would really like 
to have some notion of a "phase 2 initialized constant" which would provide a 
much stronger guarantee than IUO does.  There would be a very small window 
where a trap is possible between phase 1 and when it is set in phase 2.  It 
would probably make more sense to actually think of this as phase 1.5 where all 
of these properties must be initialized to a non-nil value, but self can be 
used in the initializing expressions.

It sounds like property behaviors might not be the right way to solve that.  If 
that is the case, is it possible a solution to this might be considered during 
Swift 4?

>>> More Expressive KeyPaths
>>> 
>>> We would also like to support being able to use Key Paths to access into 
>>> collections, which is not currently possible.
>>> 
>>> Proposed solution
>>> We propose introducing a new expression akin to Type.method, but for 
>>> properties and subscripts. These property reference expressions produce 
>>> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
>>> classes (structs and protocols here would be ideal, but requires 
>>> generalized existentials)
>>> 
>> How different would the design be with generalized existentials? Are they 
>> plans to migrate to that design once we do get generalized existentials?
>>> which encapsulate a property reference or chain 

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPhone

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

Didn't it require trapping if set more than once?  And it didn't offer a way to 
require initialization during phase 2 did it?

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

Re: [swift-evolution] Smart KeyPaths

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

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

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 17, 2017, at 6:15 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 17, 2017, at 3:35 PM, Matthew Johnson > > wrote:
>> 
>>> In all seriousness, I see the design as very slightly weak, in that it 
>>> makes it easy to forget to pass a context through, but quite acceptable. 
>> 
>> Easy for who?  I was not requiring Codable types to thread it through at 
>> all.  The context was fully managed by the Encoder / Decoder type.  The only 
>> place Codable types work with the context is as an argument they receive.  
>> They never pass it when encoding or decoding anything.  The Encoder / 
>> Decoder would need to store the context internally and when call is made to 
>> encode / decode a ContextAwareCodable it would pass the result of a dynamic 
>> cast to ContextAwareCodable.Context as the context.
> 
> Oh, I see. Sorry, I missed that when I was looking at your design.
> 
> In practice, in my design, you would only need to manually pass a context to 
> `encode(_:forKey:with:)` if the context was of a different type than `self`’s.

Oh, I see.  I missed that part of your design.  I really like it with the 
shorthands.  I’m fully on board with this being the right way to handle 
contexts now.  I think Context should be in the basic Codable protocol.  That 
leaves the question of what to do with NSKeyedArchiver and NSKeyedUnarchiver.  
I’m not sure what the answer is for those but it would be unfortunate to see 
the design compromised solely because of a requirement to interoperate with 
them.

> This would probably happen at module or subsystem boundaries. Imagine, for 
> instance, that your FooKit module (for interacting with the foo.io 
>  web service) needs to encode a GeoKit.Location instance, but 
> both FooKit and GeoKit need information from a context to encode themselves 
> properly, and they use different context types. When FooKit encoded a 
> GeoKit.Location, it could construct and pass a GeoKit context.
> 
> I believe that in your design, unless the FooKit context was a subtype of the 
> GeoKit context, you wouldn't be able to get GeoKit.Location to do the right 
> thing.

Right.  It was assuming only one context would be needed for an entire encoding 
/ decoding process.  I don’t know of use cases where one module could 
meaningfully provide a context to another module unless they were very closely 
related (i.e. built as parts of the same system) but maybe they do exist.  Your 
design is able to accommodate this very well.

I made some compromises to try and diverge from the current proposal as little 
as possible while still solving the primary use cases I’m aware of.  Now that I 
understand your design I think it has enough advantages that we should go in 
that direction.  And we certainly should not go in the direction of something 
that requires Any.

> 
> If that weren't the case—if you were encoding a type with a matching context, 
> or with a `Void` context—you could use the two convenience methods, which 
> would handle the context argument for you. So threading contexts would only 
> be necessary in a relatively rare case.

Yep, that’s very elegant!

> 
> -- 
> 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-17 Thread Matthew Johnson via swift-evolution

> On Mar 17, 2017, at 5:38 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 17, 2017, at 12:34 PM, David Hart via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Sent off-list by mistake:
>> 
>> Nice proposal. I have a few comments inline:
>> 
>>> On 17 Mar 2017, at 18:04, Michael LeHew via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi friendly swift-evolution folks,
>>> 
>>> The Foundation and Swift team  would like for you to consider the following 
>>> proposal:
>>> 
>>> Many thanks,
>>> -Michael
>>> 
>>> Smart KeyPaths: Better Key-Value Coding for Swift
>>> Proposal: SE-
>>> Authors: David Smith , Michael LeHew 
>>> , Joe Groff 
>>> Review Manager: TBD
>>> Status: Awaiting Review
>>> Associated PRs:
>>> #644 
>>> Introduction
>>> We propose a family of concrete Key Path types that represent uninvoked 
>>> references to properties that can be composed to form paths through many 
>>> values and directly get/set their underlying values.
>>> 
>>> Motivation
>>> We Can Do Better than String
>>> 
>>> On Darwin platforms Swift's existing #keyPath() syntax provides a 
>>> convenient way to safely refer to properties. Unfortunately, once 
>>> validated, the expression becomes a String which has a number of important 
>>> limitations:
>>> 
>>> Loss of type information (requiring awkward Any APIs)
>>> Unnecessarily slow to parse
>>> Only applicable to NSObjects
>>> Limited to Darwin platforms
>>> Use/Mention Distinctions
>>> 
>>> While methods can be referred to without invoking them (let x = foo.bar 
>>> instead of  let x = foo.bar()), this is not currently possible for 
>>> properties and subscripts.
>>> 
>>> Making indirect references to a properties' concrete types also lets us 
>>> expose metadata about the property, and in the future additional behaviors.
>>> 
>> What metadata is attached? How is it accessed? What future features are you 
>> thinking about?
> 
> To begin with, you'd have limited ability to stringify a key path. Eventually 
> we'd like to support other reflectiony things, including:
> 
> - Asking for the primary key paths a type supports
> - Asking for a key by name or index
> - Breaking a key path down by components
> 
> I also see key path objects as a good way of eventually addressing some of 
> the design problems we ran up against with property behaviors 
> (https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
>  
> 
>  from last year), including the problem of what exactly a property behavior 
> declaration *is* (a type? a protocol? a function-like thing? something 
> completely new?), and the problem of handling "out-of-band" operations on a 
> property beyond getting and setting, such as clearing a cached lazy value, 
> registering for notifications on an observable property, and so on. I think 
> it would be natural to express property behaviors as a user-defined key path 
> type; the key path type can provide the get/set logic for the property as 
> well as any other interesting operations the property supports. This answers 
> the questions of both what behaviors look like (they're just types that 
> conform to KeyPath) and how they extend properties with new actions (they're 
> just methods of the key path value) fairly nicely.

Would these user-defined key path types be unbound like the ones described in 
the current proposal?  That would be really cool.  

I am thinking through how this would impact the design of a library I’m working 
on.  It is a use case where I would want a single unbound instance per property 
rather than an instance of the key path (and its storage) for each instance of 
the type.  Storage of the property value itself would not be affected by the 
behavior.

I would use reflection to discover the key paths of a type that my library 
recognizes and use them to interact with the property.  I would have the user 
initialize the custom key path for a property with a key path into a related 
type where both have the same value type.  The library would use the key paths 
to synchronize data between the related instances.  There is no need to change 
the per-instance storage or access (the library would not rely on intercepting 
specific accesses to the property to synchronize the data).  It would only be 
used as a powerful tool for working with arbitrary types.

>>> More Expressive KeyPaths
>>> 
>>> We would also like to support being able to use Key Paths to access into 
>>> collections, which is not currently possible.
>>> 
>>> Proposed solution
>>> We propose introducing a new expression akin to Type.method, but for 
>>> properties and subscripts. These property reference expressions produce 
>>> KeyPath objects, rather

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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


Sent from my iPhone

> On Mar 19, 2017, at 10:47 AM, Tony Parker  wrote:
> 
> Hi Matthew, Brent,
> 
> I see why you are asking for this Context parameter, but putting it into the 
> basic Codable protocol introduces too much conceptual overhead. There are too 
> many benefits to keeping adoption to just one protocol, including 
> discoverability, ease of use, reducing the need for overloads on protocols 
> elsewhere, and more. Supporting this one use case does not outweigh those 
> benefits, especially considering I expect that most library code would not 
> use it (as you say: it would be weird to pass this context between modules).
> 
> Can you figure out a way to get the context info passed through the 
> encoder/decoder instead? It would make more sense as something optionally 
> retrieved from the encoder/decoder that was set at the top level.

Hi Tony.  I can see the argument that the this is a feature that should be 
relatively rarely used and thus should have as simple a design as possible.

If you feel like the impact of threading a typed context on the API surface 
area is too heavy you could just add a `var context: Any? { get }` requirement 
to Encoder and Decoder.  The expectation is that encoders and decoders would 
accept a context in the top level call and make it available to all Codable 
types.  This would solve the problem with minimal API impact at the cost of the 
ability to statically verify that all types receive the context they need to 
encode / decode correctly.

I much prefer the static safety but having a solution is better than not having 
one.  :)

> 
> - Tony
> 
>>> On Mar 17, 2017, at 5:56 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>>> On Mar 17, 2017, at 6:15 PM, Brent Royal-Gordon  
>>>> wrote:
>>>> 
>>>>> On Mar 17, 2017, at 3:35 PM, Matthew Johnson  
>>>>> wrote:
>>>>> 
>>>>> In all seriousness, I see the design as very slightly weak, in that it 
>>>>> makes it easy to forget to pass a context through, but quite acceptable. 
>>>> 
>>>> Easy for who?  I was not requiring Codable types to thread it through at 
>>>> all.  The context was fully managed by the Encoder / Decoder type.  The 
>>>> only place Codable types work with the context is as an argument they 
>>>> receive.  They never pass it when encoding or decoding anything.  The 
>>>> Encoder / Decoder would need to store the context internally and when call 
>>>> is made to encode / decode a ContextAwareCodable it would pass the result 
>>>> of a dynamic cast to ContextAwareCodable.Context as the context.
>>> 
>>> Oh, I see. Sorry, I missed that when I was looking at your design.
>>> 
>>> In practice, in my design, you would only need to manually pass a context 
>>> to `encode(_:forKey:with:)` if the context was of a different type than 
>>> `self`’s. 
>> 
>> Oh, I see.  I missed that part of your design.  I really like it with the 
>> shorthands.  I’m fully on board with this being the right way to handle 
>> contexts now.  I think Context should be in the basic Codable protocol.  
>> That leaves the question of what to do with NSKeyedArchiver and 
>> NSKeyedUnarchiver.  I’m not sure what the answer is for those but it would 
>> be unfortunate to see the design compromised solely because of a requirement 
>> to interoperate with them.
>> 
>>> This would probably happen at module or subsystem boundaries. Imagine, for 
>>> instance, that your FooKit module (for interacting with the foo.io web 
>>> service) needs to encode a GeoKit.Location instance, but both FooKit and 
>>> GeoKit need information from a context to encode themselves properly, and 
>>> they use different context types. When FooKit encoded a GeoKit.Location, it 
>>> could construct and pass a GeoKit context.
>>> 
>>> I believe that in your design, unless the FooKit context was a subtype of 
>>> the GeoKit context, you wouldn't be able to get GeoKit.Location to do the 
>>> right thing.
>> 
>> Right.  It was assuming only one context would be needed for an entire 
>> encoding / decoding process.  I don’t know of use cases where one module 
>> could meaningfully provide a context to another module unless they were very 
>> closely related (i.e. built as parts of the same system) but maybe they do 
>> exist.  Your design is able to accommodate this very well.
>> 
>> I made some compromises to try and diverge from the current proposal as 
>> little as possible while still solving the pri

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPhone

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

+1

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


Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPhone

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

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

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


Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 19, 2017, at 3:38 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 19, 2017, at 12:21 PM, Tony Parker > > wrote:
>>> 
>>> On Mar 19, 2017, at 12:14 PM, Matthew Johnson >> > wrote:
>>> 
>>> On Mar 19, 2017, at 10:47 AM, Tony Parker >> > wrote:
>>> 
 Hi Matthew, Brent,
 
 I see why you are asking for this Context parameter, but putting it into 
 the basic Codable protocol introduces too much conceptual overhead. There 
 are too many benefits to keeping adoption to just one protocol, including 
 discoverability, ease of use, reducing the need for overloads on protocols 
 elsewhere, and more. Supporting this one use case does not outweigh those 
 benefits, especially considering I expect that most library code would not 
 use it (as you say: it would be weird to pass this context between 
 modules).
 
 Can you figure out a way to get the context info passed through the 
 encoder/decoder instead? It would make more sense as something optionally 
 retrieved from the encoder/decoder that was set at the top level.
>>> 
>>> Hi Tony.  I can see the argument that the this is a feature that should be 
>>> relatively rarely used and thus should have as simple a design as possible.
>>> 
>>> If you feel like the impact of threading a typed context on the API surface 
>>> area is too heavy you could just add a `var context: Any? { get }` 
>>> requirement to Encoder and Decoder.  The expectation is that encoders and 
>>> decoders would accept a context in the top level call and make it available 
>>> to all Codable types.  This would solve the problem with minimal API impact 
>>> at the cost of the ability to statically verify that all types receive the 
>>> context they need to encode / decode correctly.
>>> 
>>> I much prefer the static safety but having a solution is better than not 
>>> having one.  :)
>> 
>> The Any context property is reasonable, but it would be nice to find 
>> something in the middle. =)
>> 
>> One other possibility is that we define a user info dictionary instead, with 
>> a custom key type that can be extended (much like our string enumerations). 
>> In general I haven’t been a fan of the user info pattern in Swift because of 
>> the necessity to cast, but as you say it’s better than nothing. e.g. 
>> userInfo : [CodingUserInfoKey: Any].
> 
> I hate casting out of Any, and I strongly believe we should support multiple 
> contexts, so personally, I'd prefer something typed:

I can imagine multiple contexts being useful in rare cases; much more rarely 
than a single context but still worth supporting.

I generally agree with you about casting.  However, my dislike isn’t the cast 
itself, but instead it is the lack of a static guarantee.  I’m not sure we’ll 
find a solution that provides a static guarantee that a required context exists 
that is also acceptable to the Foundation team.

> 
>   protocol Encoder {
>   // Retrieve the context instance of the indicated type.
>   func context(ofType type: Context.Type) -> Context?
>   
>   // This context is visible for `encode(_:)` calls from this 
> encoder's containers all the way down, recursively.
>   func addContext(_ context: Context, ofType type: 
> Context.Type)

What happens if you call `addContext` more than once with values of the same 
type?  And why do you require the type to be passed explicitly when it is 
already implied by the type of the value?

>   }
>   // Likewise on Decoder
>   
>   // Encoder and decoder classes should accept contexts in their 
> top-level API:
>   open class JSONEncoder {
>   open func encode(_ value: Value, withContexts 
> contexts: [Any] = []) throws -> Data
>   }

What happens if more than one context of the same type is provided here?  Also, 
it’s worth pointing out that whatever reason you had for explicitly passing the 
type above you’re not requiring type information to be provided here.  Whatever 
design we have it should be self-consistent.

I’m going to speculate that the intent above is that the types of the context 
values are treated as a key into a dictionary, or something along those lines.  
I’ll also speculate that if more than one context of the same type exist are 
provided at a given stack level level the latest one overwrites the previous 
one (what else would happen - `addContext` is non-throwing).

Do you think it’s really important to allow users to dynamically provide 
context for children?  Do you have real world use cases where this is needed?  
I’m sure there could be case where this might be useful.  But I also think 
there is some benefit in knowing that the context used for an entire encoding / 
decoding is the one you provide at the top level.  I suspect the benefit of a 
static guarantee that your context is used for the enti

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 19, 2017, at 2:21 PM, Tony Parker  wrote:
> 
> 
>> On Mar 19, 2017, at 12:14 PM, Matthew Johnson > <mailto:matt...@anandabits.com>> wrote:
>> 
>> 
>> 
>> Sent from my iPhone
>> 
>> On Mar 19, 2017, at 10:47 AM, Tony Parker > <mailto:anthony.par...@apple.com>> wrote:
>> 
>>> Hi Matthew, Brent,
>>> 
>>> I see why you are asking for this Context parameter, but putting it into 
>>> the basic Codable protocol introduces too much conceptual overhead. There 
>>> are too many benefits to keeping adoption to just one protocol, including 
>>> discoverability, ease of use, reducing the need for overloads on protocols 
>>> elsewhere, and more. Supporting this one use case does not outweigh those 
>>> benefits, especially considering I expect that most library code would not 
>>> use it (as you say: it would be weird to pass this context between modules).
>>> 
>>> Can you figure out a way to get the context info passed through the 
>>> encoder/decoder instead? It would make more sense as something optionally 
>>> retrieved from the encoder/decoder that was set at the top level.
>> 
>> Hi Tony.  I can see the argument that the this is a feature that should be 
>> relatively rarely used and thus should have as simple a design as possible.
>> 
>> If you feel like the impact of threading a typed context on the API surface 
>> area is too heavy you could just add a `var context: Any? { get }` 
>> requirement to Encoder and Decoder.  The expectation is that encoders and 
>> decoders would accept a context in the top level call and make it available 
>> to all Codable types.  This would solve the problem with minimal API impact 
>> at the cost of the ability to statically verify that all types receive the 
>> context they need to encode / decode correctly.
>> 
>> I much prefer the static safety but having a solution is better than not 
>> having one.  :)
> 
> The Any context property is reasonable, but it would be nice to find 
> something in the middle. =)
> 
> One other possibility is that we define a user info dictionary instead, with 
> a custom key type that can be extended (much like our string enumerations). 
> In general I haven’t been a fan of the user info pattern in Swift because of 
> the necessity to cast, but as you say it’s better than nothing. e.g. userInfo 
> : [CodingUserInfoKey: Any].

This makes sense some sense.  This would allow us to support the multiple 
context use case.  I think the need for that is far more rare than the need for 
a single context but it still makes sense to support it.

The down side I can see is that it could encourage users to adopt a “context 
dictionary” approach with a bunch of keys rather than defining their own 
context type using a single key.  This is generally a bad idea and should be 
discouraged.

I think we should make the more common single-content use case more convenient 
and subtly nudge users in the right direction by making it easier to use.  We 
could do this by defining a `DefaultContext` key, including a `defaultContext` 
property on `Encoder` and `Decoder` in an extension which returns 
`self.context[DefaultContext]` and encouraging encoders and decoders to provide 
an override that takes a single `context: Any` argument which gets placed in 
the context dictionary using that key.

I still very much prefer the stronger guarantees offered by Brent’s first 
design but I could live with this.

One last thought - might it be possible to restructure the design a way that 
would allow us to build type-safe context-awareness on top of existing encoders 
/ decoders?  I’m going to give a little bit of thought to this but don’t expect 
to come up with a good answer.

At least one hurdle to this in the current proposal is that the Foundation 
encoders and decoders hide the types that actually do the encoding and 
decoding.  There are probably very good reasons for this of course, but they 
also make it more difficult to layer functionality like context-awareness on 
top of them.  We would have to resort to a hack of some kind to even attempt it.

> 
> - Tony
> 
>> 
>>> 
>>> - Tony
>>> 
>>>> On Mar 17, 2017, at 5:56 PM, Matthew Johnson via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> 
>>>>> On Mar 17, 2017, at 6:15 PM, Brent Royal-Gordon >>>> <mailto:br...@architechies.com>> wrote:
>>>>> 
>>>>>> On Mar 17, 2017, at 3:35 PM, Matthew Johnson >>>>> <mailto:matt...@anandabits.com>> wrote:
>>>>>> 
>>>>>>&

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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


Sent from my iPad

> On Mar 19, 2017, at 9:14 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 19, 2017, at 5:51 PM, Matthew Johnson  wrote:
>> 
>> I generally agree with you about casting.  However, my dislike isn’t the 
>> cast itself, but instead it is the lack of a static guarantee.  I’m not sure 
>> we’ll find a solution that provides a static guarantee that a required 
>> context exists that is also acceptable to the Foundation team.
> 
> I don't think we can get a static guarantee that the context is present, but 
> I still would like a static guarantee that the context is of the expected 
> type. That's what I'm trying to provide here.

This doesn't do any better job of that than a cast in user code.  I can see two 
meaningful differences.  First, your solution does not allow a user to see a 
context if they can't name the type (you can't get it as Any and use 
reflection, etc).  I don't see this restriction as being beneficial.  Second, 
your solution introduces several subtle problems mentioned in my last email 
which you didn't respond to (overlapping context types, etc).  

> 
>>> 
>>> protocol Encoder {
>>> // Retrieve the context instance of the indicated type.
>>> func context(ofType type: Context.Type) -> Context?
>>> 
>>> // This context is visible for `encode(_:)` calls from this 
>>> encoder's containers all the way down, recursively.
>>> func addContext(_ context: Context, ofType type: 
>>> Context.Type)
>> 
>> What happens if you call `addContext` more than once with values of the same 
>> type?
> 
> It overrides the previous context, but only for the containers created by 
> this `encode(to:)` method and any containers nested within them.
> 
> (Although that could cause trouble for an encoder which only encodes objects 
> with multiple instances once. Hmm.)
> 
>> And why do you require the type to be passed explicitly when it is already 
>> implied by the type of the value?
> 
> As you surmised later, I was thinking in terms of `type` being used as a 
> dictionary key; in that case, if you stored a `Foo` into the context, you 
> would not later be able to look it up using one of `Foo`'s supertypes. But if 
> we really do expect multiple contexts to be rare, perhaps we don't need a 
> dictionary at all—we can just keep an array, loop over it with `as?`, and 
> return the first (or last?) match. If that's what we do, then we probably 
> don't need to pass the type explicitly.

The array approach is better because at least there is an order to the contexts 
and we can assign precise semantics in the presence of overlapping context 
types by saying type get the first (most recent) context that can be cast to 
the type you ask for.  

That said, I think what you're really trying to model here is a context stack, 
isn't it?  Why don't we just do that?

> 
>>> }
>>> // Likewise on Decoder
>>> 
>>> // Encoder and decoder classes should accept contexts in their 
>>> top-level API:
>>> open class JSONEncoder {
>>> open func encode(_ value: Value, withContexts 
>>> contexts: [Any] = []) throws -> Data
>>> }
>> 
>> What happens if more than one context of the same type is provided here?
> 
> Fail a precondition, probably.

I would never support this design.  Good news though: the context stack 
approach avoids the problem.  We allow multiple contexts of the same type to be 
on the stack and the topmost context that can be cast to the requested type is 
used.

> 
>> Also, it’s worth pointing out that whatever reason you had for explicitly 
>> passing the type above you’re not requiring type information to be provided 
>> here.  Whatever design we have it should be self-consistent.
> 
> Yeah. I did this here because there was no way to specify a dictionary 
> literal of `(T.Type, T)`, where `T` could be different for different elements.
> 
>> Do you think it’s really important to allow users to dynamically provide 
>> context for children?  Do you have real world use cases where this is 
>> needed?  I’m sure there could be case where this might be useful.  But I 
>> also think there is some benefit in knowing that the context used for an 
>> entire encoding / decoding is the one you provide at the top level.  I 
>> suspect the benefit of a static guarantee that your context is used for the 
>> entire encoding / decoding has a lot more value than the ability to 
>> dynamically change the context for a subtree.
> 
> The problem with providing all the contexts at the top level is that then the 
> top level has to *know* what all the contexts needed are. Again, if you're 
> encoding a type from FooKit, and it uses a type from GeoKit, then you—the 
> user of FooKit—need to know that FooKit uses GeoKit and how to make contexts 
> for both of them. There's no way to encapsulate GeoKit's role in encoding.

The use cases I know of for contexts are really around helping a type choose an 
encoding strategy.  I 

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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


Sent from my iPad

> On Mar 19, 2017, at 10:19 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 19, 2017, at 9:14 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Mar 19, 2017, at 5:51 PM, Matthew Johnson  wrote:
>>> 
>>> I generally agree with you about casting.  However, my dislike isn’t the 
>>> cast itself, but instead it is the lack of a static guarantee.  I’m not 
>>> sure we’ll find a solution that provides a static guarantee that a required 
>>> context exists that is also acceptable to the Foundation team.
>> 
>> I don't think we can get a static guarantee that the context is present, but 
>> I still would like a static guarantee that the context is of the expected 
>> type. That's what I'm trying to provide here.
> 
> This doesn't do any better job of that than a cast in user code.  I can see 
> two meaningful differences.  First, your solution does not allow a user to 
> see a context if they can't name the type (you can't get it as Any and use 
> reflection, etc).  I don't see this restriction as being beneficial.  Second, 
> your solution introduces several subtle problems mentioned in my last email 
> which you didn't respond to (overlapping context types, etc).  
> 
>> 
>>>> 
>>>>protocol Encoder {
>>>>// Retrieve the context instance of the indicated type.
>>>>func context(ofType type: Context.Type) -> Context?
>>>>
>>>>// This context is visible for `encode(_:)` calls from this 
>>>> encoder's containers all the way down, recursively.
>>>>func addContext(_ context: Context, ofType type: 
>>>> Context.Type)
>>> 
>>> What happens if you call `addContext` more than once with values of the 
>>> same type?
>> 
>> It overrides the previous context, but only for the containers created by 
>> this `encode(to:)` method and any containers nested within them.
>> 
>> (Although that could cause trouble for an encoder which only encodes objects 
>> with multiple instances once. Hmm.)
>> 
>>> And why do you require the type to be passed explicitly when it is already 
>>> implied by the type of the value?
>> 
>> As you surmised later, I was thinking in terms of `type` being used as a 
>> dictionary key; in that case, if you stored a `Foo` into the context, you 
>> would not later be able to look it up using one of `Foo`'s supertypes. But 
>> if we really do expect multiple contexts to be rare, perhaps we don't need a 
>> dictionary at all—we can just keep an array, loop over it with `as?`, and 
>> return the first (or last?) match. If that's what we do, then we probably 
>> don't need to pass the type explicitly.
> 
> The array approach is better because at least there is an order to the 
> contexts and we can assign precise semantics in the presence of overlapping 
> context types by saying type get the first (most recent) context that can be 
> cast to the type you ask for.  
> 
> That said, I think what you're really trying to model here is a context 
> stack, isn't it?  Why don't we just do that?
> 
>> 
>>>>}
>>>>// Likewise on Decoder
>>>>
>>>>// Encoder and decoder classes should accept contexts in their 
>>>> top-level API:
>>>>open class JSONEncoder {
>>>>open func encode(_ value: Value, withContexts 
>>>> contexts: [Any] = []) throws -> Data
>>>>}
>>> 
>>> What happens if more than one context of the same type is provided here?
>> 
>> Fail a precondition, probably.
> 
> I would never support this design.  Good news though: the context stack 
> approach avoids the problem.  We allow multiple contexts of the same type to 
> be on the stack and the topmost context that can be cast to the requested 
> type is used.
> 
>> 
>>> Also, it’s worth pointing out that whatever reason you had for explicitly 
>>> passing the type above you’re not requiring type information to be provided 
>>> here.  Whatever design we have it should be self-consistent.
>> 
>> Yeah. I did this here because there was no way to specify a dictionary 
>> literal of `(T.Type, T)`, where `T` could be different for different 
>> elements.
>> 
>>> Do you think it’s really important to allow users to dynamically provide 
>>> context for children?  Do you have real

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

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

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


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


Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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


Sent from my iPad

> On Mar 20, 2017, at 1:43 AM, David Hart  wrote:
> 
> 
>> On 20 Mar 2017, at 02:09, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>>>> On Mar 19, 2017, at 2:21 PM, Tony Parker  wrote:
>>>> 
>>>> 
>>>> On Mar 19, 2017, at 12:14 PM, Matthew Johnson  
>>>> wrote:
>>>> 
>>>> 
>>>> 
>>>> Sent from my iPhone
>>>> 
>>>>> On Mar 19, 2017, at 10:47 AM, Tony Parker  
>>>>> wrote:
>>>>> 
>>>>> Hi Matthew, Brent,
>>>>> 
>>>>> I see why you are asking for this Context parameter, but putting it into 
>>>>> the basic Codable protocol introduces too much conceptual overhead. There 
>>>>> are too many benefits to keeping adoption to just one protocol, including 
>>>>> discoverability, ease of use, reducing the need for overloads on 
>>>>> protocols elsewhere, and more. Supporting this one use case does not 
>>>>> outweigh those benefits, especially considering I expect that most 
>>>>> library code would not use it (as you say: it would be weird to pass this 
>>>>> context between modules).
>>>>> 
>>>>> Can you figure out a way to get the context info passed through the 
>>>>> encoder/decoder instead? It would make more sense as something optionally 
>>>>> retrieved from the encoder/decoder that was set at the top level.
>>>> 
>>>> Hi Tony.  I can see the argument that the this is a feature that should be 
>>>> relatively rarely used and thus should have as simple a design as possible.
>>>> 
>>>> If you feel like the impact of threading a typed context on the API 
>>>> surface area is too heavy you could just add a `var context: Any? { get }` 
>>>> requirement to Encoder and Decoder.  The expectation is that encoders and 
>>>> decoders would accept a context in the top level call and make it 
>>>> available to all Codable types.  This would solve the problem with minimal 
>>>> API impact at the cost of the ability to statically verify that all types 
>>>> receive the context they need to encode / decode correctly.
>>>> 
>>>> I much prefer the static safety but having a solution is better than not 
>>>> having one.  :)
>>> 
>>> The Any context property is reasonable, but it would be nice to find 
>>> something in the middle. =)
>>> 
>>> One other possibility is that we define a user info dictionary instead, 
>>> with a custom key type that can be extended (much like our string 
>>> enumerations). In general I haven’t been a fan of the user info pattern in 
>>> Swift because of the necessity to cast, but as you say it’s better than 
>>> nothing. e.g. userInfo : [CodingUserInfoKey: Any].
>> 
>> This makes sense some sense.  This would allow us to support the multiple 
>> context use case.  I think the need for that is far more rare than the need 
>> for a single context but it still makes sense to support it.
> 
> I'm not a fan of the info dictionary as it penalizes the simple cases of a 
> unique context type.

I agree with this.  That is why I suggested we need to add convenience for the 
single context of a custom type if we go that route.  I like the context stack 
idea I posted later last night better though.  It gets away from the context 
dictionary altogether.

> 
>> The down side I can see is that it could encourage users to adopt a “context 
>> dictionary” approach with a bunch of keys rather than defining their own 
>> context type using a single key.  This is generally a bad idea and should be 
>> discouraged.
>> 
>> I think we should make the more common single-content use case more 
>> convenient and subtly nudge users in the right direction by making it easier 
>> to use.  We could do this by defining a `DefaultContext` key, including a 
>> `defaultContext` property on `Encoder` and `Decoder` in an extension which 
>> returns `self.context[DefaultContext]` and encouraging encoders and decoders 
>> to provide an override that takes a single `context: Any` argument which 
>> gets placed in the context dictionary using that key.
>> 
>> I still very much prefer the stronger guarantees offered by Brent’s first 
>> design but I could live with this.
>> 
>> One last thought - might it be possible to restructure the design a way that 
>> would allow us to build type-safe contex

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

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

No.  What I mean by shadowed is this:

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

Shadowed was perhaps a bad word to use.  :)

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


Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

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

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

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

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

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

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 20, 2017, at 5:34 AM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 19, 2017, at 8:19 PM, Matthew Johnson > > wrote:
>> 
>> First, your solution does not allow a user to see a context if they can't 
>> name the type (you can't get it as Any and use reflection, etc).
> 
> What I meant is that, if you retrieve the context, you know it is of the type 
> you expect. You don't need to *also* cast it.

Right.  What I’m saying is that if all we’re doing is moving the cast in to the 
encoder / decoder I don’t see value in doing that over the obvious thing of 
exposing the context as Any? and letting the caller cast it.  If the encoder / 
decoder uses the requested type in an algorithm to find the matching context 
then we obviously do need to pass the type as a parameter.  :)

> 
>> I don't see this restriction as being beneficial.  Second, your solution 
>> introduces several subtle problems mentioned in my last email which you 
>> didn't respond to (overlapping context types, etc).  
> 
> I mentioned that, if we give up storing values in a dictionary, we can come 
> up with some sort of sensible-ish behavior for overlapping context types.

Oh, sorry.  I missed that the breadth-first algorithm for finding a matching 
context was the answer to this.

> 
>   protocol Encoder {
>   // Retrieve the context instance of the indicated type.
>   func context(ofType type: Context.Type) -> Context?
>   
>   // This context is visible for `encode(_:)` calls from this 
> encoder's containers all the way down, recursively.
>   func addContext(_ context: Context, ofType type: 
> Context.Type)
 
 What happens if you call `addContext` more than once with values of the 
 same type?
>>> 
>>> It overrides the previous context, but only for the containers created by 
>>> this `encode(to:)` method and any containers nested within them.
>>> 
>>> (Although that could cause trouble for an encoder which only encodes 
>>> objects with multiple instances once. Hmm.)
>>> 
 And why do you require the type to be passed explicitly when it is already 
 implied by the type of the value?
>>> 
>>> As you surmised later, I was thinking in terms of `type` being used as a 
>>> dictionary key; in that case, if you stored a `Foo` into the context, you 
>>> would not later be able to look it up using one of `Foo`'s supertypes. But 
>>> if we really do expect multiple contexts to be rare, perhaps we don't need 
>>> a dictionary at all—we can just keep an array, loop over it with `as?`, and 
>>> return the first (or last?) match. If that's what we do, then we probably 
>>> don't need to pass the type explicitly.
>> 
>> The array approach is better because at least there is an order to the 
>> contexts and we can assign precise semantics in the presence of overlapping 
>> context types by saying type get the first (most recent) context that can be 
>> cast to the type you ask for.  
>> 
>> That said, I think what you're really trying to model here is a context 
>> stack, isn't it?  Why don't we just do that?
> 
> You mention this a couple times, but I don't think it's really possible. 
> Here's why.
> 
> Suppose you write these types:
> 
>   struct SomeObjectContext {
>   var oldFormat: Bool
>   }
>   
>   struct Root: Codeable {
>   var str: SomeStruct
>   var obj: SomeObject
>   
>   func encode(to encoder: Encoder) throws {
>   encoder.push(SomeObjectContext(oldFormat: true))
>   
>   let container = encoder.container(keyedBy: 
> CodingKeys.self)
>   try container.encode(str, forKey: .str)
>   try container.encode(obj, forKey: .obj)
>   }
>   ...
>   }
>   
>   struct SomeStruct: Codeable {
>   var obj: SomeObject
>   
>   func encode(to encoder: Encoder) throws {
>   encoder.push(SomeObjectContext(oldFormat: false))
>   
>   let container = encoder.container(keyedBy: 
> CodingKeys.self)
>   try container.encode(obj, forKey: .obj)
>   }
>   }
>   
>   class SomeObject: Codeable {
>   …
>   
>   func encode(to encoder: Encoder) throws {
>   let context = encoder.context(ofType: 
> SomeObjectContext.self)
>   
>   print(context.oldFormat)
>   …
>   }
>   }
> 
> And you construct an object graph like this:
> 
>   let object = SomeObject()
>   
>   let root = Root(
>   str: SomeStruct(obj: object),
>   obj: object
>   )
> 
> And finally, you encode it with a coder which respects object identity, so 
> that even if a

Re: [swift-evolution] Smart KeyPaths

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

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

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

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

Re: [swift-evolution] Fwd: Re: Smart KeyPaths

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

> On Mar 20, 2017, at 12:37 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 20.03.2017 17:56, Charles Srstka via swift-evolution wrote:
>>> On Mar 20, 2017, at 9:23 AM, Christopher Kornher via swift-evolution
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Mar 20, 2017, at 5:12 AM, David Hart via swift-evolution
 mailto:swift-evolution@swift.org>> wrote:
 
 
 
> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution
> mailto:swift-evolution@swift.org>> wrote:
> 
> +1.  This is my favorite solution so far.
> 
> With ‘Person.keypath.name' it is obvious that we are creating a key
> path.  There is no ambiguity for the reader.  With autocomplete it will
> be very little extra typing anyway…
 
 But that adds a lot of verbosity. They disregarded #keyPath because it
 was too verbose.
>>> 
>>> The syntax in the original proposal is terse and elegant, and will
>>> probably be fine when a developer who is experienced with Swift and a
>>> particular codebase is first writing the code. Using “key path” or
>>> “keypaths” of perhaps a shorter term or even a single leading character
>>> (`#` ?) will make this feature more discoverable, tool-friendly and its
>>> usages more maintainable.
>>> 
>>> An extra term or character does add verbosity. How much is subjective,
>>> but I would not call it “a lot”. It does not add any nesting or code
>>> complexity. KVO code is usually a small fraction of most Objective-C
>>> projects (in my experience, at least) and it is probably safe to assume
>>> that the usage of this feature in Swift will be similar.
>>> 
>>> Verbosity vs clarity is often a tradeoff and I think that on balance, for
>>> a feature like this a little extra verbosity is worth it. Swift does not
>>> have the most terse syntax possible. `++` was removed, for example.
>>> 
>>> Just because an assignment is already implicitly typed in Swift does not
>>> mean that the ambiguity has to keep increasing without end for
>>> implementation of all new features, especially for ones that are not used
>>> very frequently.
>> 
>> +1 to all of this.
>> 
>> Particularly the point that KVO code typically is a small portion of the
>> overall code; this not only makes the added verbosity not that
>> egregious—certainly less so than “try” or “override”—but it also
>> underscores the fact that as a relatively uncommon feature, it’s not what a
>> reader of the code is going to be expecting to see. This latter point is
>> why I feel that without some kind of additional syntax—even if it’s just
>> one character—key paths will frequently get mistaken for property accesses
>> if they are implemented this way.
> 
> +1 from me. The problem is not that we shouldn't have instance props with the 
> same name as class/static props. The problem is when you are *reading* some 
> code(not always in IDE) it is hard to say what MyType.someprop[atIndex].name 
> means. Is it static/class property or is it KeyPath? You just don't know - 
> you have to check this in MyType declaration for any static property you 
> don't know for sure it is static .
> 
> The same is for instance:
> 
> struct S {
>   var index = 0
>   func foo() {}
>   subscript (at: Int) -> Int {return at*100}
> }
> //
> let s = S()
> let value = s[index]
> // is it key path or subscript with `index` as parameter?
> 
> The difference with unbound methods(I hope I correctly understand that 
> unbound method is `T.method` as mentioned by the proposal) is that unbound 
> method IMO don't have *such* level of confusing. It can't have subscripts, it 
> can't contains more than one part(the method name itself).

Yes, this is a difference that matters in some respects.

> 
> Also, using the above code,
> let method = S.foo
> 
> this line *has* a marker, that here we have an unbound method : there is *no* 
> `()` after the foo. Do we have any such 'marker' in proposed key paths? No.
> 
> So I do believe this special feature(I mean it will be used rarely and reader 
> most likely will not expect it in the code) requires a special syntax 
> highlighting.
> 
> FWIW, currently I do like 3 proposed syntax to highlight what is happening 
> here and also is not verbose like #keyPath():
> 
> 1. Type:path and instance:path
> 
> 2. Type@path and instance@path - as it reads nice "type at path" and 
> "instance at path"
> 
> 3. And also I think as soon as we have `#` as marker for 'compiler magic', 
> IMO it will be logically use it for the feature:
> Type#path and instance#path.

Hmm, I could live with this approach (#) as long as the dot shorthand still 
worked in type contexts expecting a key path with a concrete Root.

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

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

> On Mar 21, 2017, at 7:27 AM, Jean-Daniel  wrote:
> 
> 
>>> Le 20 mars 2017 à 15:52, Matthew Johnson via swift-evolution 
>>>  a écrit :
>>> 
>>> 
>>> On Mar 20, 2017, at 9:23 AM, Christopher Kornher via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
>>>> On Mar 20, 2017, at 5:12 AM, David Hart via swift-evolution 
>>>>  wrote:
>>>> 
>>>> 
>>>> 
>>>>> On 20 Mar 2017, at 10:39, Jonathan Hull via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> +1.  This is my favorite solution so far. 
>>>>> 
>>>>> With ‘Person.keypath.name' it is obvious that we are creating a key path. 
>>>>>  There is no ambiguity for the reader.  With autocomplete it will be very 
>>>>> little extra typing anyway…
>>>> 
>>>> But that adds a lot of verbosity. They disregarded #keyPath because it was 
>>>> too verbose.
>>> 
>>> The syntax in the original proposal is terse and elegant, and will probably 
>>> be fine when a developer who is experienced with Swift and a particular 
>>> codebase is first writing the code. Using “key path” or “keypaths” of 
>>> perhaps a shorter term or even a single leading character (`#` ?) will make 
>>> this feature more discoverable, tool-friendly and its usages more 
>>> maintainable.
>> 
>> It also makes it inconsistent with how unbound methods behave.  I have yet 
>> to hear a convincing argument about why key paths should be treated 
>> different syntactically.
> 
> Because they are two different beasts. Are you arguing that we should allow 
> unbound method as subscript parameter to be consistent with key path ?

Obviously not.  A keypath represents data so a subscript is the logical way to 
access the data.  An unbound method represents a function so you call it.  But 
both represent unbound ways to access members of instances of a type, store 
that access in a variable, pass it as an argument, etc.  

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

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

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 20, 2017, at 9:33 PM, Greg Parker via swift-evolution 
>  wrote:
> 
> 
>> On Mar 20, 2017, at 4:54 PM, Douglas Gregor > > wrote:
>> 
>> Hello Swift community,
>> 
>> The review of SE-0159 "Fix Private Access Levels" begins now and runs 
>> through March 27, 2017. The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md
>>  
>> 
> -1. I yield the remainder of my time to Drew Crawford who satisfactorily 
> explained my concerns.

I am also -1.  

I think there are two issues to be considered.  One is scoped access itself and 
the other is the names of the access levels.  

I think a reasonable case can be made that changing the meaning of private and 
introducing fileprivate was a mistake.  We probably should have left private 
alone and chosen a new name for scoped access.  There was abundant bikeshedding 
over this at the time, but now we have the benefit of experience.  I believe we 
should have simply called scoped access control `scoped`.  It’s clear that some 
people would still oppose scoped access but I also don’t think we’d be 
revisiting this topic if we hadn’t changed the meaning of `private`.  The 
passionate dislike of the feature seems to me mostly related to stealing the 
`private` keyword.  

I support correcting the naming mistake eventually.  I’m neutral as to whether 
Swift 4 is the right time to do that.  We just introduced a lot of churn in 
Swift 3.  There is still inconsistency in Swift’s access control system as well 
as unmet needs (especially around submodules).  It may be better to leave 
things alone for a release and make the change as part of a larger set of 
changes when access control and submodules are part of a release “theme”.

I am extremely unconvinced that having a scoped access level is actively 
harmful.  It introduces another choice in the language but no individual 
programmers or teams are forced to use the additional flexibility if they don’t 
want to.  It would be very easy for linters to prohibit scoped access if there 
are teams that don’t want to use it.  It is one extra degree of control for new 
programmers to learn but properly taught it helps programmers learn to think 
about encapsulation.  This is a good thing.

On the other hand, I believe removing scoped access is active harmful.  It 
reduces our ability to properly encapsulate mutable state.  For example, I like 
to use scoped access to create small state machine types which are used as part 
of the implementation of another type.  These are usually structs with a 
private enum.  The struct exposes methods which encapsulate state transitions.  
Without scoped access there is no way to encapsulate the state of the state 
machine and force all changes to go through one of the methods on the struct.  
This is just one example of how this feature can be very useful, there are many 
others.  Small helper types like this are very idiomatic in Swift.  It would be 
a big step backward to lose the ability to have proper encapsulation of small 
helper types.

One common argument agains scoped access is that “you’re only protecting 
yourself from yourself”.  I find this to be a bit of a straw man.  It isn’t 
about “protection”.  It is about compiler verified encapsulation.  This 
prevents inadvertent changes that violate the intent of the design.  For 
example, it is not out of the question that without scoped access a new member 
of a large team writes directly to the internal storage of the state machine in 
the above example.  It is also possible that they do so in a way that 
represents an invalid state transition.  The compiler would not catch this 
mistake.  Hopefully it would be caught in a code review but I can imagine it 
getting missed for many different reasons.  On the other hand, with scoped 
access the new team member would be unlikely to prefer changing access control 
to using the intended methods.  If they did change access control this would be 
very likely to be caught in code review.

Access control also provides compiler verified documentation of our code.  This 
facilitates reasoning about our code.  It also communicates design intent from 
the original author to future maintainers.  Removing a tool that many people 
find useful in facilitating reasoning about code is actively harmful.  Teams 
that don’t find this tool useful should use a linter and ban its use on their 
team.  This approach would let those of us who do find this tool useful 
continue to use it.

My observation thus far has been that people seem to be preferring private over 
fileprivate in many cases.  I don’t think this preference is solely about 
typing four less characters.  I think many people really do value the tighter 
encapsulation it provides.

I do think changes to access control are necessary but I also 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 21, 2017, at 10:57 AM, Drew Crawford via swift-evolution 
>  wrote:
> 
> 
> 
>> > I’m not arguing that it is less or more than a majority. I’m just saying 
>> > that we’ve seen a lot of talk against the original change.
> 
> This proposal asks us to balance the convenience of one group 
> (extension-writers) against the existence of another (scoped-access users).  
> To do that, we need a clear idea of the composition of both groups.
> 
> “A lot of talk” is not the evidentiary standard to remove a feature.  It was 
> not good enough when we introduced the feature, that required argument and 
> clear use-cases.
> 
>> > By default, I did not mean the syntactic default of the language but the 
>> > access modifier users will use “by default” when trying to restrict 
>> > visibility. In most languages, that keyword is “private” so its valid to 
>> > say that newcomers to the language will “default” to using that one.
> 
> Apologies, but I do not understand the argument:
> 
> A user wants to restrict visibility (e.g. they are dissatisfied with 
> “internal”)
> The user *chooses* private because of familiarity from another language
> The user is then surprised that their choice of private indeed restricted the 
> visibility, thus achieving their goal?
> What language does the user come from in which “private” is file-visible?  It 
> isn’t Java, C++, or PHP.  C#’s “partial” is the closest I can think of, and 
> it isn’t at all close.
> 
> A user who wants a middle-ground visibility would “default” to “protected”, 
> “friend”, “partial”, or similar.  After that does not compile, they will use 
> google to find a middle-road visibility keyword, for which the only candidate 
> is “fileprivate”.  But they will not choose “private”, it’s just not a 
> reasonable expectation of what the keyword means to a new Swift developer.
> 
> The popularity of private “as a default” is simply because many users prefer 
> to hide their implementation details as a matter of routine code hygiene.  
> Redefining private in order to thwart their code hygiene goal seems extreme.
> 
> I agree with several here (as I did in SE-0025) that our access modifiers are 
> not well-named.  However, that’s not the proposal in front of us.
> 
>> > My own statistics in my projects show the contrary. At best, this shows 
>> > how divisive this feature is.
> 
> This *may* show that, if contrary statistics were presented, but that hasn’t 
> occurred.
> 
>> In old code, statistics could be biased by the migrator having replaced all 
>> previous instances of private by fileprivate.
> 
> If the migrator migrated code to private, and it *worked* (e.g. did not 
> introduce visibility errors) this is not bias, this is a correct use of the 
> feature.
> 
>> > I'm just arguing that the additional scope-based access modifier does not 
>> > provide enough differentiation to be worth that complexity.
> 
> The only argument I have seen so far around “complexity” boils down to: “some 
> people do not use it”.  But some people *do* use it, and anyway if we are 
> going to remove all the features “not enough people” use then we are in for a 
> ride.
> 
> Swift 3 shipped, so what we are discussing now is yanking a keyword without 
> replacement.  There is code written that uses private to enforce its 
> threading or security invariants.  There is code written that uses private in 
> order to shadow another declaration.   There is code that will not compile 
> after migration. We need more than a vague fear of complexity generally to 
> throw a brick through all those windows.  That brick will introduce quite a 
> bit of complexity itself.
> 
+1.  On one side we have a vague notion of “complexity” which doesn’t appear to 
amount to much more than a statement of opinion that the granularity isn’t 
useful.  On the other side we have people who find legitimate value in the 
feature for important and clearly articulated purposes.  This seems to me to be 
a solid demonstration that the feature is useful.  

Compiler verification of invariant-preserving encapsulation is important.  It 
is not trivial.  It is not something to be written off lightly because “you’re 
only protecting yourself from yourself”.  People make very similar arguments 
against static typing outside of the Swift community but most of us here see 
value in static types.  Frankly, I’m surprised that so many don’t see more 
value in compiler verified encapsulation.  Is it as important as a robust 
static type system?  No.  But that doesn’t make it unimportant.

>> Concerning the one-class-per-file argument, I would suggest this 
>> counter-argument: when working in large projects, I believe it's a good 
>> thing if the language encourages (forces is too strong a word for my taste) 
>> a one class per file structure, it's good practice.
> 
> The form of the argument is invalid.  Suppose I argued: "it’s a good thing 
> for the language to encourage one definition per class (no extensions), it’s 
> g

Re: [swift-evolution] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 21, 2017, at 11:00 AM, Colin Barrett via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Mar 16, 2017 at 3:33 PM Itai Ferber via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> Here's what I mean: Suppose I have a BlogPost model, and I can both fetch and 
> post BlogPosts to a cross-platform web service, and store them locally. But 
> when I fetch and post remotely, I ned to conform to the web service's 
> formats; when I store an instance locally, I have a freer hand in designing 
> my storage, and perhaps need to store some extra metadata. How do you imagine 
> handling that sort of situation? Is the answer simply that I should use two 
> different types?
> 
> This is a valid concern, and one that should likely be addressed.
> 
> Perhaps the solution is to offer a userInfo : [UserInfoKey : Any] 
> (UserInfoKey being a String-RawRepresentable struct or similar) on Encoder 
> and Decoder set at the top-level to allow passing this type of contextual 
> information from the top level down.
> 
>  
> I assumed that in those situations, one would create a wrapper struct,
> 
> struct WebBlogModel {
> let wrapped: BlogModel
> }
> 
> probably for the encoding impl that requires more custom work. The 
> implementation of Codable for this struct would then serialize (deserialize) 
> from (to) its wrapped value's properties directly.
> 
> Types already provide a means for performing context sensitive implementation 
> selection, I don't think it's necessary to provide another way to do that in 
> Swift. Of course I could very well be wrong :)

Wrappers like this give you a way to implement different encoding strategies 
but they don’t help you identify which strategy to use for a given encoding.  
You need a user-defined context to do that.  Brent has proposed a couple of 
different designs to facilitate this which are nicer than a user info 
dictionary.

> 
> -Colin
> ___
> 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] [Proposal] Foundation Swift Archival & Serialization

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

> On Mar 21, 2017, at 11:24 AM, Colin Barrett  
> wrote:
> 
> I'm not sure I follow. What do you mean "which strategy to use for a given 
> encoding"? IMO there should be at most one implementation of Coding / 
> Decoding for a particular type. So the way you'd say "I want to decode a JSON 
> response that implements my blog model" would be, reusing the definition from 
> above
> 
> let wblog = try JSONDecoder().decode(WebBlogModel.self, from: payload)
> let blog = wblog.wrapped
> 
> What am I missing?

When I have encountered a need for things like this I usually don’t need to 
encode a whole tree differently based on context.  I only need to encode one or 
two types differently based on context.  IMO it would be insane to require 
wrapper types all the way down the tree that’s getting encoded just so that one 
or two types can encode themselves using a format specified by a server.  I 
suppose you could make it work but it’s crazy and unnecessary complexity if you 
ask me.

Brent’s example was using different formats for local archiving and for cloud 
persistence.  This also seems reasonable.  Again wrappers would work but would 
also be a lot of boilerplate for no obvious win.

Encoder and Decoder as proposed already include a `codingKeyContext`.  We’re 
just asking for an additional user-defined context which gives information 
about the purpose of the encoding.

> 
> -Colin
> 
> 
> On Tue, Mar 21, 2017 at 12:16 PM Matthew Johnson  > wrote:
>> On Mar 21, 2017, at 11:00 AM, Colin Barrett via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>> On Thu, Mar 16, 2017 at 3:33 PM Itai Ferber via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Here's what I mean: Suppose I have a BlogPost model, and I can both fetch 
>> and post BlogPosts to a cross-platform web service, and store them locally. 
>> But when I fetch and post remotely, I ned to conform to the web service's 
>> formats; when I store an instance locally, I have a freer hand in designing 
>> my storage, and perhaps need to store some extra metadata. How do you 
>> imagine handling that sort of situation? Is the answer simply that I should 
>> use two different types?
>> 
>> This is a valid concern, and one that should likely be addressed.
>> 
>> Perhaps the solution is to offer a userInfo : [UserInfoKey : Any] 
>> (UserInfoKey being a String-RawRepresentable struct or similar) on Encoder 
>> and Decoder set at the top-level to allow passing this type of contextual 
>> information from the top level down.
>> 
>>  
>> I assumed that in those situations, one would create a wrapper struct,
>> 
>> struct WebBlogModel {
>> let wrapped: BlogModel
>> }
>> 
>> probably for the encoding impl that requires more custom work. The 
>> implementation of Codable for this struct would then serialize (deserialize) 
>> from (to) its wrapped value's properties directly.
>> 
>> Types already provide a means for performing context sensitive 
>> implementation selection, I don't think it's necessary to provide another 
>> way to do that in Swift. Of course I could very well be wrong :)
> 
> Wrappers like this give you a way to implement different encoding strategies 
> but they don’t help you identify which strategy to use for a given encoding.  
> You need a user-defined context to do that.  Brent has proposed a couple of 
> different designs to facilitate this which are nicer than a user info 
> dictionary.
> 
>> 
>> -Colin
> 
>> ___
>> 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] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 21, 2017, at 1:41 PM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
> 
> 
> Sent from my iPhone
> On 21 Mar 2017, at 16:57, Drew Crawford  > wrote:
> 
>> 
>> 
>>> > I’m not arguing that it is less or more than a majority. I’m just saying 
>>> > that we’ve seen a lot of talk against the original change.
>> 
>> This proposal asks us to balance the convenience of one group 
>> (extension-writers) against the existence of another (scoped-access users).  
>> To do that, we need a clear idea of the composition of both groups.
>> 
>> “A lot of talk” is not the evidentiary standard to remove a feature.  It was 
>> not good enough when we introduced the feature, that required argument and 
>> clear use-cases.
>> 
> "A lot of talk" is not the evidence supporting the proposal: it's just a 
> warning that something may be very controversial among the community. The 
> arguments for the revert are in the proposal and in the discussions in this 
> thread.
> 
>>> > By default, I did not mean the syntactic default of the language but the 
>>> > access modifier users will use “by default” when trying to restrict 
>>> > visibility. In most languages, that keyword is “private” so its valid to 
>>> > say that newcomers to the language will “default” to using that one.
>> 
>> Apologies, but I do not understand the argument:
>> 
>> A user wants to restrict visibility (e.g. they are dissatisfied with 
>> “internal”)
>> The user *chooses* private because of familiarity from another language
>> The user is then surprised that their choice of private indeed restricted 
>> the visibility, thus achieving their goal?
>> What language does the user come from in which “private” is file-visible?  
>> It isn’t Java, C++, or PHP.  C#’s “partial” is the closest I can think of, 
>> and it isn’t at all close.
> 
> It has pointed quite a few times by core team members that comparison to 
> languages is not a very strong arguments, especially when Swift does things 
> differently for a good reason. I can't stop from quoting Xiaodi from a month 
> back:
> 
> «The beauty of Swift 2's access modifiers was that they were based around 
> files and modules, explicitly rejecting types and scopes as units for 
> determining visibility.» -- Xiaodi
> 
>> A user who wants a middle-ground visibility would “default” to “protected”, 
>> “friend”, “partial”, or similar.  After that does not compile, they will use 
>> google to find a middle-road visibility keyword, for which the only 
>> candidate is “fileprivate”.  But they will not choose “private”, it’s just 
>> not a reasonable expectation of what the keyword means to a new Swift 
>> developer.
>> 
>> The popularity of private “as a default” is simply because many users prefer 
>> to hide their implementation details as a matter of routine code hygiene.  
>> Redefining private in order to thwart their code hygiene goal seems extreme.
> 
> The point is that keeping both private and fileprivate feels like an 
> un-necessary complication:
> 
> • either a programmer falls on your side of the fence and will use private as 
> often as possible and relegate to fileprivate when the design leaves no other 
> choice. At that point it feels like a language wart.
> • or a programmer will fall on my side of the fence and use fileprivate all 
> the time and the language feels like it has an unnecessary access modifier.
> 
> I'd argue that the cases when a programmer will use both meaningfully is very 
> rare. As a consequence, we should try to only keep one. Removing fileprivate 
> is a no-go with extensions so that leaves us with removing private.

Removing scoped access is a no-go if we consider tightly encapsulating 
invariant-preserving state to be an important feature.  The fact is that both 
features can be used meaningfully.  The fact that some people choose not to do 
this is not an argument against the features being available.  It is an 
opportunity to encourage people to thing more carefully about why they are 
encapsulating something.  

A programmer has to make a conscious decision to give a declaration visibility 
other than internal.  If they have trouble identifying whether file or scoped 
access is appropriate this indicates they don’t really understand their intent 
in encapsulating the declaration very clearly.  I don’t think it’s a bad thing 
to ask people to think about this a little bit more.  A simple guideline is to 
use file-level access unless you have a specific reason for preferring the 
tight encapsulation scoped access provides.  Both Drew and I have offered some 
examples of specific reasons for using scoped access that IMO are important 
enough that they deserve to be supported by the language.

> 
>> I agree with several here (as I did in SE-0025) that our access modifiers 
>> are not well-named.  However, that’s not the proposal in front of us.
>> 
>>> > My own statistics in my projects show the contrary. At best, this shows 
>>> > how div

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 21, 2017, at 4:26 PM, Jose Cheyo Jimenez  wrote:
> 
> 
>> On Mar 21, 2017, at 11:54 AM, Matthew Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Mar 21, 2017, at 1:41 PM, David Hart via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> 
>>> 
>>> 
>>> Sent from my iPhone
>>> On 21 Mar 2017, at 16:57, Drew Crawford >> <mailto:d...@sealedabstract.com>> wrote:
>>> 
>>>> 
>>>> 
>>>>> > I’m not arguing that it is less or more than a majority. I’m just 
>>>>> > saying that we’ve seen a lot of talk against the original change.
>>>> 
>>>> This proposal asks us to balance the convenience of one group 
>>>> (extension-writers) against the existence of another (scoped-access 
>>>> users).  To do that, we need a clear idea of the composition of both 
>>>> groups.
>>>> 
>>>> “A lot of talk” is not the evidentiary standard to remove a feature.  It 
>>>> was not good enough when we introduced the feature, that required argument 
>>>> and clear use-cases.
>>>> 
>>> "A lot of talk" is not the evidence supporting the proposal: it's just a 
>>> warning that something may be very controversial among the community. The 
>>> arguments for the revert are in the proposal and in the discussions in this 
>>> thread.
>>> 
>>>>> > By default, I did not mean the syntactic default of the language but 
>>>>> > the access modifier users will use “by default” when trying to restrict 
>>>>> > visibility. In most languages, that keyword is “private” so its valid 
>>>>> > to say that newcomers to the language will “default” to using that one.
>>>> 
>>>> Apologies, but I do not understand the argument:
>>>> 
>>>> A user wants to restrict visibility (e.g. they are dissatisfied with 
>>>> “internal”)
>>>> The user *chooses* private because of familiarity from another language
>>>> The user is then surprised that their choice of private indeed restricted 
>>>> the visibility, thus achieving their goal?
>>>> What language does the user come from in which “private” is file-visible?  
>>>> It isn’t Java, C++, or PHP.  C#’s “partial” is the closest I can think of, 
>>>> and it isn’t at all close.
>>> 
>>> It has pointed quite a few times by core team members that comparison to 
>>> languages is not a very strong arguments, especially when Swift does things 
>>> differently for a good reason. I can't stop from quoting Xiaodi from a 
>>> month back:
>>> 
>>> «The beauty of Swift 2's access modifiers was that they were based around 
>>> files and modules, explicitly rejecting types and scopes as units for 
>>> determining visibility.» -- Xiaodi
>>> 
>>>> A user who wants a middle-ground visibility would “default” to 
>>>> “protected”, “friend”, “partial”, or similar.  After that does not 
>>>> compile, they will use google to find a middle-road visibility keyword, 
>>>> for which the only candidate is “fileprivate”.  But they will not choose 
>>>> “private”, it’s just not a reasonable expectation of what the keyword 
>>>> means to a new Swift developer.
>>>> 
>>>> The popularity of private “as a default” is simply because many users 
>>>> prefer to hide their implementation details as a matter of routine code 
>>>> hygiene.  Redefining private in order to thwart their code hygiene goal 
>>>> seems extreme.
>>> 
>>> The point is that keeping both private and fileprivate feels like an 
>>> un-necessary complication:
>>> 
>>> • either a programmer falls on your side of the fence and will use private 
>>> as often as possible and relegate to fileprivate when the design leaves no 
>>> other choice. At that point it feels like a language wart.
>>> • or a programmer will fall on my side of the fence and use fileprivate all 
>>> the time and the language feels like it has an unnecessary access modifier.
>>> 
>>> I'd argue that the cases when a programmer will use both meaningfully is 
>>> very rare. As a consequence, we should try to only keep one. Removing 
>>> fileprivate is a no-go with extensions so that leaves us with removing 
>>> private

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPhone

> On Mar 21, 2017, at 4:48 PM, Jose Cheyo Jimenez  wrote:
> 
> 
>>> On Mar 21, 2017, at 2:33 PM, Matthew Johnson  wrote:
>>> 
>>> 
>>>> On Mar 21, 2017, at 4:26 PM, Jose Cheyo Jimenez  
>>>> wrote:
>>>> 
>>>> 
>>>>> On Mar 21, 2017, at 11:54 AM, Matthew Johnson via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> 
>>>>> On Mar 21, 2017, at 1:41 PM, David Hart via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> Sent from my iPhone
>>>>> On 21 Mar 2017, at 16:57, Drew Crawford  wrote:
>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> > I’m not arguing that it is less or more than a majority. I’m just 
>>>>>>> > saying that we’ve seen a lot of talk against the original change.
>>>>>> 
>>>>>> This proposal asks us to balance the convenience of one group 
>>>>>> (extension-writers) against the existence of another (scoped-access 
>>>>>> users).  To do that, we need a clear idea of the composition of both 
>>>>>> groups.
>>>>>> 
>>>>>> “A lot of talk” is not the evidentiary standard to remove a feature.  It 
>>>>>> was not good enough when we introduced the feature, that required 
>>>>>> argument and clear use-cases.
>>>>>> 
>>>>> "A lot of talk" is not the evidence supporting the proposal: it's just a 
>>>>> warning that something may be very controversial among the community. The 
>>>>> arguments for the revert are in the proposal and in the discussions in 
>>>>> this thread.
>>>>> 
>>>>>>> > By default, I did not mean the syntactic default of the language but 
>>>>>>> > the access modifier users will use “by default” when trying to 
>>>>>>> > restrict visibility. In most languages, that keyword is “private” so 
>>>>>>> > its valid to say that newcomers to the language will “default” to 
>>>>>>> > using that one.
>>>>>> 
>>>>>> Apologies, but I do not understand the argument:
>>>>>> 
>>>>>> A user wants to restrict visibility (e.g. they are dissatisfied with 
>>>>>> “internal”)
>>>>>> The user *chooses* private because of familiarity from another language
>>>>>> The user is then surprised that their choice of private indeed 
>>>>>> restricted the visibility, thus achieving their goal?
>>>>>> What language does the user come from in which “private” is 
>>>>>> file-visible?  It isn’t Java, C++, or PHP.  C#’s “partial” is the 
>>>>>> closest I can think of, and it isn’t at all close.
>>>>> 
>>>>> It has pointed quite a few times by core team members that comparison to 
>>>>> languages is not a very strong arguments, especially when Swift does 
>>>>> things differently for a good reason. I can't stop from quoting Xiaodi 
>>>>> from a month back:
>>>>> 
>>>>> «The beauty of Swift 2's access modifiers was that they were based around 
>>>>> files and modules, explicitly rejecting types and scopes as units for 
>>>>> determining visibility.» -- Xiaodi
>>>>> 
>>>>>> A user who wants a middle-ground visibility would “default” to 
>>>>>> “protected”, “friend”, “partial”, or similar.  After that does not 
>>>>>> compile, they will use google to find a middle-road visibility keyword, 
>>>>>> for which the only candidate is “fileprivate”.  But they will not choose 
>>>>>> “private”, it’s just not a reasonable expectation of what the keyword 
>>>>>> means to a new Swift developer.
>>>>>> 
>>>>>> The popularity of private “as a default” is simply because many users 
>>>>>> prefer to hide their implementation details as a matter of routine code 
>>>>>> hygiene.  Redefining private in order to thwart their code hygiene goal 
>>>>>> seems extreme.
>>>>> 
>>>>> The point is that keeping both private and fileprivate feels like an 
>>>>> un-necessary com

Re: [swift-evolution] Smart KeyPaths

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


Sent from my iPad

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

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

> 
> -- Ben
> 

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 21, 2017, at 7:40 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Tue, Mar 21, 2017 at 6:44 PM, Drew Crawford  
>> wrote:
 I am confused by this response. An argument in _support_ of new `private` 
 was that it is more in line with expectations of users coming from other 
 languages. In other some cases, such an argument might have its place. 
 However, as others have pointed out on this list, those other languages 
 don't have facilities like Swift's extensions, and therefore it was not a 
 very strong argument for new `private` to say that it better aligns with 
 user expectations coming from other languages.
>>> 
>>> The underlying issue here (which I have now identified, thanks!) is what 
>>> motivates the use of extensions.  That question predates proposals, but the 
>>> Swift book provides the following motivation, which I have numbered for 
>>> ease of reference:
>>> 
>>> 1. Extensions add new functionality to an existing class, structure, 
>>> enumeration, or protocol type. 
>>> 2. This includes the ability to extend types for which you do not have 
>>> access to the original source code (known as retroactive modeling). 
>>> 
>>> 3. Extensions are similar to categories in Objective-C.
>>> 
>> 
>> It seems to me this motivation contemplates use “at some distance”, that is 
>> we intend to create some semantically meaningful separation between the 
>> declaration and the extension(s).  If we did not we could use MARK or some 
>> other comment-based scheme to organize our class.
>> 
>> 2 is explicitly at great distance, so we know the distance motivation is 
>> well within scope.  1 refers to “an existing” type which implies a certain 
>> level of functionality in the unextended type, and not merely a partial 
>> implementation in the unextended type.  The record on 3 is more mixed (ObjC 
>> programmers do occasionally use categories “closely-held” to group a few 
>> methods together).  However ObjC also has the “distance” tradition: 
>> categories cannot introduce new storage even when this is technically 
>> trivial (within the same compilation unit for example), and this tradition 
>> was continued under Swift with the new ABI.
>> 
>> What I am suggesting is that the primary design purpose of an extension is 
>> to create semantic distance between a declaration and the functionality 
>> being added.
> 
> I'm not sure it is necessary for extensions to have a "primary design 
> purpose." They serve many purposes. One use I have for them is as follows:
> 
> ```
> struct A {
>   // Stuff here constitutes the "raison d'etre" for A.
> }
> 
> extension A : B {
>   // In the course of implementing `A`, I have discovered that
>   // `A` can fulfill the semantic guarantees of `B`, and in fact
>   // fulfills most of them already.
>   //
>   // So, I conform to B, as in so doing there are some practical
>   // advantages, such as gaining some default implementations.
>   //
>   // But, to conform, I may need to implement some methods
>   // not really essential for a functional `A`, but required nonetheless
>   // to conform to `B`.
>   //
>   // I implement them here in an extension; in so doing, I express
>   // the idea that I have, after implementing `A`, discovered its
>   // conformance to `B`, and I am here supplying the remaining
>   // implementations necessary for that conformance.
>   //
>   // That is, if `B` did not exist, neither would these functions here.
>   // But there may be some requirements of `B` that would be
>   // implemented in `A` whether or not `B` exists.
>   // Those are implemented above, in `struct A { ... }`.
> }
> ```
> 
> I find this to be an eloquent way to separate concerns. It is a common 
> pattern encouraged by code I admire written by others more skilled than me in 
> Swift.
> 
>> A mechanism to hide variables from extensions is something that *furthers* 
>> this design goal of extensions, rather than contradicts it.
> 
> This, I suppose, is an argument for you to take up with Charles.
>  
>> I understand that some people use extensions as sort of an imitation 
>> “partial class” but they simply aren’t (no storage) and we should introduce 
>> a new feature if we want to have them.
>> 
>>> A core team member (I'm blanking on who) has pointed out that, in the end, 
>>> the only necessary access modifiers are public and not public (spelled 
>>> "internal" in Swift).
>> 
>> 
>> It is not clear to me how this squares with the decision in SE-0025 that 
>> other access modifiers were necessary.  Can you clarify?
> 
> Why do you think SE-0025 decided that other access modifiers are necessary? 
> It merely decided that having four was deemed, on balance, superior to having 
> three. But the minimum number of access modifiers is, by definition, two. In 
> the case of Swift those essentially have to be at the module boundary. 
> Anything more finely diced than that and you are balancing expressivity and 
> complexit

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 21, 2017, at 9:17 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Tue, Mar 21, 2017 at 8:31 PM, Charles Srstka  > wrote:
> 
>> On Mar 21, 2017, at 8:15 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Mar 21, 2017 at 8:00 PM, Charles Srstka > > wrote:
>>> On Mar 21, 2017, at 7:49 PM, Xiaodi Wu >> > wrote:
>> 
>>> 
>>> On Tue, Mar 21, 2017 at 6:46 PM, Charles Srstka >> > wrote:
 On Mar 21, 2017, at 5:26 PM, Xiaodi Wu via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 So, if four/five access modifiers are too many, which one is carrying the 
 least weight? Which one could be removed to simplify the scheme while 
 maintaining the most expressiveness? Which one doesn't fulfill even its 
 own stated goals? Well, one of the key goals of `private` was to allow 
 members to be encapsulated within an extension, hidden even from the type 
 being extended (and vice versa for members defined in the type). It says 
 so in the first sentence of SE-0025. As seen above in my discussion with 
 Charles Srstka, even supporters of `private` disagree with that motivation 
 to begin with. The kicker is, _it also doesn't work_. Try, for instance:
 
 ```
 struct Foo {
   private var bar: Int { return 42 }
 }
 
 extension Foo {
   private var bar: Int { return 43 }
 }
 ```
 
 The code above should compile and does not. If I understood correctly the 
 explanation from a core team member on this list, it's unclear if it can 
 be made to work without changing how mangling works, which I believe 
 impacts ABI and is not trivial at all. Thus, (a) even proponents of new 
 `private` disagree on one of two key goals stated for new `private`; (b) 
 that goal was never accomplished, and making it work is not trivial; (c) 
 no one even complained about it, suggesting that it was a low-yield goal 
 in the first place.
>>> 
>>> Multiple people have already brought up cases in which they are using 
>>> ‘private’. The repeated mention of another, unrelated use case that was 
>>> mentioned in the SE-0025 proposal does not invalidate the real-world use 
>>> cases which have been presented. In fact, it rather makes it appear as if 
>>> the motivation to remove ‘private’ is based on a strange invocation of the 
>>> appeal-to-authority fallacy, rather than an actual improvement to the 
>>> language.
>>> 
>>> I'm not sure how to respond to this. SE-0025, as designed, is not fully 
>>> implemented. And as I said above, IIUC, it cannot be fully implemented 
>>> without ripping out a lot of mangling code that is unlikely to be ripped 
>>> out before Swift 4. _And there is no evidence that anyone cares about this 
>>> flaw; in fact, you are saying as much, that you do not care at all!_ If 
>>> this is not sufficient indication that the design of SE-0025 does not fit 
>>> with the overall direction of Swift, what would be?
>> 
>> Because there are other uses cases for ‘private', *not* involving 
>> extensions, which I *do* care about. The fact that part of the proposal was 
>> badly written (and really, that’s all this is
>> 
>> Huh? The code above *should compile*--that is a primary aim for SE-0025. It 
>> does not compile and there is not a timeline (afaict) for its compiling. It 
>> does not bother you that the 25th proposal considered in the Swift evolution 
>> process, already once revised, is not fully implemented and may never be?
> 
> Someone finding a bug/oversight in the compiler behavior does not compel me 
> to throw out the baby with the bathwater, no.
> 
> You're not hearing the argument. No one "accidentally" included this design 
> as part of SE-0025; it's sentence number one. And no one just "forgot" to 
> make the code above work; it simply can't be accommodated by the current 
> mangling scheme. And--what's more--_no one seems to be bothered by it_. If 
> the first sentence of a proposal can't be implemented, and no one cares (!), 
> is the proposal fundamentally flawed or is it just some bug?

The reason nobody cares much is because this is a degenerate case and is not 
actually how people want to use the feature.  You don’t see people writing 
identically named fileprivate methods in extensions of a type in different 
files either.  The purpose of the feature is not shadowing.  That is a side 
effect.  The purpose is to provide tight compiler-verified encapsulation.  
Nothing more, nothing less.

>> —it uses “class or extension” as a synonym for “any type declaration" when 
>> really, it makes just as much sense for structs to have private members as 
>> classes. Stuff happens!) does not invalidate the other use cases. And yes, 
>> I’m aware that my coding style may differ from other people, who may use the 
>> language in a different way. 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 21, 2017, at 10:02 PM, Xiaodi Wu  wrote:
> 
> On Tue, Mar 21, 2017 at 9:32 PM, Matthew Johnson  > wrote:
> 
>> On Mar 21, 2017, at 9:17 PM, Xiaodi Wu via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Tue, Mar 21, 2017 at 8:31 PM, Charles Srstka > > wrote:
>> 
>>> On Mar 21, 2017, at 8:15 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Tue, Mar 21, 2017 at 8:00 PM, Charles Srstka >> > wrote:
 On Mar 21, 2017, at 7:49 PM, Xiaodi Wu >>> > wrote:
>>> 
 
 On Tue, Mar 21, 2017 at 6:46 PM, Charles Srstka >>> > wrote:
> On Mar 21, 2017, at 5:26 PM, Xiaodi Wu via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> So, if four/five access modifiers are too many, which one is carrying the 
> least weight? Which one could be removed to simplify the scheme while 
> maintaining the most expressiveness? Which one doesn't fulfill even its 
> own stated goals? Well, one of the key goals of `private` was to allow 
> members to be encapsulated within an extension, hidden even from the type 
> being extended (and vice versa for members defined in the type). It says 
> so in the first sentence of SE-0025. As seen above in my discussion with 
> Charles Srstka, even supporters of `private` disagree with that 
> motivation to begin with. The kicker is, _it also doesn't work_. Try, for 
> instance:
> 
> ```
> struct Foo {
>   private var bar: Int { return 42 }
> }
> 
> extension Foo {
>   private var bar: Int { return 43 }
> }
> ```
> 
> The code above should compile and does not. If I understood correctly the 
> explanation from a core team member on this list, it's unclear if it can 
> be made to work without changing how mangling works, which I believe 
> impacts ABI and is not trivial at all. Thus, (a) even proponents of new 
> `private` disagree on one of two key goals stated for new `private`; (b) 
> that goal was never accomplished, and making it work is not trivial; (c) 
> no one even complained about it, suggesting that it was a low-yield goal 
> in the first place.
 
 Multiple people have already brought up cases in which they are using 
 ‘private’. The repeated mention of another, unrelated use case that was 
 mentioned in the SE-0025 proposal does not invalidate the real-world use 
 cases which have been presented. In fact, it rather makes it appear as if 
 the motivation to remove ‘private’ is based on a strange invocation of the 
 appeal-to-authority fallacy, rather than an actual improvement to the 
 language.
 
 I'm not sure how to respond to this. SE-0025, as designed, is not fully 
 implemented. And as I said above, IIUC, it cannot be fully implemented 
 without ripping out a lot of mangling code that is unlikely to be ripped 
 out before Swift 4. _And there is no evidence that anyone cares about this 
 flaw; in fact, you are saying as much, that you do not care at all!_ If 
 this is not sufficient indication that the design of SE-0025 does not fit 
 with the overall direction of Swift, what would be?
>>> 
>>> Because there are other uses cases for ‘private', *not* involving 
>>> extensions, which I *do* care about. The fact that part of the proposal was 
>>> badly written (and really, that’s all this is
>>> 
>>> Huh? The code above *should compile*--that is a primary aim for SE-0025. It 
>>> does not compile and there is not a timeline (afaict) for its compiling. It 
>>> does not bother you that the 25th proposal considered in the Swift 
>>> evolution process, already once revised, is not fully implemented and may 
>>> never be?
>> 
>> Someone finding a bug/oversight in the compiler behavior does not compel me 
>> to throw out the baby with the bathwater, no.
>> 
>> You're not hearing the argument. No one "accidentally" included this design 
>> as part of SE-0025; it's sentence number one. And no one just "forgot" to 
>> make the code above work; it simply can't be accommodated by the current 
>> mangling scheme. And--what's more--_no one seems to be bothered by it_. If 
>> the first sentence of a proposal can't be implemented, and no one cares (!), 
>> is the proposal fundamentally flawed or is it just some bug?
> 
> The reason nobody cares much is because this is a degenerate case and is not 
> actually how people want to use the feature.  You don’t see people writing 
> identically named fileprivate methods in extensions of a type in different 
> files either.  The purpose of the feature is not shadowing.  That is a side 
> effect.  The purpose is to provide tight compiler-verified encapsulation.
> 
> Isn't supporting the following part and parcel of encapsulation?
> 
> ```
> class Foo {

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

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

> * What is your evaluation of the proposal?

+1.  This clarifies the interaction between Swift and Objective-C and reduces 
the magic that exists for bridging.  It’s one more step on the road of Swift 
relying less on the Objective-C runtime - decoupling the semantics of `dynamic` 
from `@objc` is a great thing.

This has potential to be the rockiest feature to migrate to Swift 4 thus far.  
I like Michel’s idea of an option in the migrator to apply `@objc` everywhere 
it is inferred today.  This would help teams that rely on dynamic interactions 
with the Objective-C runtime to migrate safely.

> * Is the problem being addressed significant enough to warrant a change to 
> Swift?

Yes.  It cleans up semantics that can be confusing today and makes Objective-C 
interactions more explicit. 

> * Does this proposal fit well with the feel and direction of Swift?

Yes.

> * If you have you used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

There is a long history of bridging in the Apple ecosystem.  Annotation for 
bridged declarations is customary.

> * How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study? 

A quick read.

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


Re: [swift-evolution] Smart KeyPaths

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

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

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

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

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


Re: [swift-evolution] Smart KeyPaths

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

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

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

> bag[#path]

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

> bag[#things[0]#name]

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

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

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

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


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

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

bag[Bag#things[0].name]

> bag.things[0][#name]

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

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

Sure, if you don’t like the shorthand.

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

Yep.

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

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

used like this:
doSomthing(bag)

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

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

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

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

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

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

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

> Actually, for me personally, any solution will be good as soon as it contains 
> some 'marker' which 

Re: [swift-evolution] Smart KeyPaths

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

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

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

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

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


Re: [swift-evolution] Smart KeyPaths

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

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

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

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

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


Re: [swift-evolution] Swift null safety questions

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

> On Mar 22, 2017, at 12:03 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Mar 6, 2017, at 4:20 PM, Elijah Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hi,
>> 
>> I’ve been recently considering Swift on the server-side, and there came up 
>> the question, “what happens when a null optional is forcibly unwrapped?” and 
>> the answer was clearly that not only would the request crash, but the entire 
>> server would also crash, since the server itself is/would be also written in 
>> Swift.
>> 
>> I think that this highlights serveral weaknesses in Swift’s “null safety” 
>> attempts. The first is that there needs to be a way to isolate blocks of 
>> code so that a “null pointer exception” does not crash the system. I think 
>> it is fair to say, in the language of Java, that these are really “runtime 
>> exceptions” and for some reason are being treated as segmentation faults 
>> would be in C/C++. In my opinion, the existence of these things has the 
>> ability to bring Swift down below Java and closer to an unamanged language. 
>> Not really sure why it would ever be desireable, but in terms of server-side 
>> programming, it is definitely a serious issue.
>> 
>> Secondly, Swift’s “null safety” is really completely undermined by these 
>> “force-unwrap” errors. I agree with the usage of new language features like 
>> guard, optional binding, etc to remove a null value, but I see this 
>> force-unwrap as extremely pervasive for a lot of reasons:
>> 
>> 1. When porting code from a C style language to Swift, force-unwrap is 
>> needed to make the code work without refractoring.
>> 2. XCode itself reccomends this operator and when it is used to satisfy a 
>> requirement, then it can be left in the code
>> 3. Some styles of coding just can’t work without force-unwrap.
>> 
>> I don’t think the logic of making the consequences extreme for making a 
>> mistake are a rational for making better coders. In fact, I personally see 
>> the “force-unwrap” operator having very great potential usage as a 
>> deliberate assertion exception - the programmer demands that a certain value 
>> be non-null for execution to continue, only there should be a proper scope 
>> and context where these exceptions can propogate to. On debug modes, one 
>> might want it to pause on the line, but for other uses, it should be caught 
>> IMO - on regular code by the user, and inside dispatch blocks by the queue 
>> itself. For a multithreaded app or server to exit, the user should have to 
>> explicitly write exit(0), isn’t this the goal of a managed language? Maybe 
>> in some cases, Apple will want the program to crash, but if Swift is given 
>> an audience not just with Apple hardware, then it should have more 
>> flexibility IMO.
> 
> The long-term vision here is to have some form of finer-grained fault 
> isolation ("actors" being the buzzword for that we tend to throw around). As 
> others noted, using `!` is intended to indicate that it is *impossible* for a 
> value to be nil at a certain point, and that the programmers screwed up if 
> the value is nil at that point. The only safe thing to do in a situation the 
> programmers didn't plan for is stop execution; anything else is just going to 
> lead to harder-to-debug, potentially-exploitable inconsistencies further 
> removed from the original problem. With actors, it could become possible for 
> that crash to only take down an isolated subprogram, and give a supervisor 
> subprogram an opportunity to gracefully wind down the process—on clients, 
> this might mean saving application state so that the app can be cleanly 
> restarted, and on the server, this might mean closing the process's accept 
> socket but still letting existing requests complete before restarting the 
> potentially-compromised process. There's still a tradeoff here from a 
> defense-in-depth standpoint, since any requests running in the same process 
> have the potential to corrupt each other's state. Swift's crash-early design 
> hopes to minimize the opportunity for corruption to leak.

Wouldn’t it also be possible to support isolated execution contexts which can 
be statically verified to only mutate state that no other part of the process 
can see?  This would allow the process itself (and other execution contexts in 
the process) to continue running without risk of corrupted state.  This seems 
like an approach that would work well for server processes that can handle 
requests in isolation.

> 
> -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-22 Thread Matthew Johnson via swift-evolution

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

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

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

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

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

Re: [swift-evolution] Smart KeyPaths

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

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

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

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

And something like this in the standard library:

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

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

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

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

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

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

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

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

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

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

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

I agree that the fear seems to be overblown.  That said, key paths are 
synthesizing special values in a way that has some

Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 23, 2017, at 1:22 AM, Matt Gallagher via swift-evolution 
>  wrote:
> 
>> What is your evaluation of the proposal?
> 
> I disagree with this proposal. It removes functionality that I actively use.
> 
> This proposal aims to revert SE-0025 without really addressing the aims of 
> that proposal, merely dismissing the result as "actively harmful" without 
> defining what that means. SE-0159 raises the complaint that "private" is 
> syntactically more natural default while "fileprivate" is a more useful 
> default. On this point, I agree but the proposal is not about mere renaming.
> 
> The other discussion in the proposal is to ask the questions:
> 
>   1. is that distinction between private and fileprivate actively used by 
> the larger community of Swift developers
> 
>   2. if it were used pervasively, would it be worth the cognitive load 
> and complexity of keeping two very similar access levels in the language?
> 
> Fair questions but despite the proposal claiming "This proposal argues that 
> answer to both questions is no", the proposal offers no *arguments* for the 
> answers, it merely states a position.
> 
> For this reason, I feel the proposal is unreasonably dismissive of the aims 
> of SE-0025.
> 
> Frankly, both these questions have subjective answers based on how 
> programmers tend to design their programs. I personally like to build 
> functionality using lots of very tiny types (many just 4 or 5 lines long), 
> therefore, I frequently put multiple types in the same file (they're part of 
> the same functionality, even if they're not part of the same type). However, 
> I want to have actual interfaces and implementation hiding between them 
> otherwise there's always the possibility of accidentally abusing the 
> interface to each type. An access modifier narrower than the file, like the 
> current scoped "private", is the *only* way to achieve this.
> 
> Reverting SE-0025 means the only way to have enforced interfaces between 
> types is to place them in separate files. This is counterproductive for tiny 
> types that form a single conceptual entity. Separate files also requires 
> whole-program optimization for optimal performance.
> 
> The only conclusion I can make is that programmers in favor of this proposal 
> simply don't program this way. However, I find it insulting that this 
> proposal is essentially saying: your way of designing and structuring 
> programs is wrong; you must use big monolithic types in their own files and 
> endure reduced compilation (whole-program optimization) or runtime 
> performance (no inlining between files with whole-program off).
> 
> I can't help but feel that this proposal is really misdirected frustration. 
> Programmers who don't use clusters of tiny types in a single file shouldn't 
> care about the existence of a scoped access modifier because it shouldn't 
> affect them – they should use file access modifiers and be done. Yet 
> apparently, it is file access modifier advocates pushing this proposal.
> 
> It really seems like the existence of a scoped access modifier is taking the 
> blame for people's frustration that the simpler keyword ("private") is a less 
> good default than the clunky keyword ("fileprivate"). I personally agree that 
> the behavior or "fileprivate" is probably a better default so I understand 
> the desire to give "private" back that meaning again. However, I don't want 
> to lose a scoped access modifier because it is *useful* (for reasons of both 
> project structure and compilation or runtime performance).
> 
> So... thumbs down from me. However, if someone wants to rename fileprivate -> 
> private and rename private -> scope (or something) I'd be more supportive.

Huge +1 to everything Matt says here.  

Elsewhere it has been argued that submodules allowing for a submodule scope can 
be combined with file scope to address some of the use cases for scoped access 
control.  This is true, but I want to point out that this combination most 
definitely does not address the use cases Matt describes here.  I often also 
create small types which are in the same file with other types and benefit from 
scoped access control.  As Matt points out, there simply isn’t any other way to 
address this use case.  It would be a shame to see Swift revert to not properly 
supporting this style of code.

It is also true that submodules (depending on their design) can address some of 
the use cases for file level scope.  In fact some people have suggested we 
might be able to drop file level scope after introducing submodules.  I 
wouldn’t want to see us do that (both are useful), but forced to choose between 
file scope and lexical scope in a language with submodules I may well choose 
lexical scope.  

Even if we assume that we want to eliminate either file or lexical scope I 
think it is preliminary to make a decision about which to eliminate.  The 
community should make this decision when we know what submodules look li

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 23, 2017, at 10:51 AM, Andrey Fidrya via swift-evolution 
>  wrote:
> 
>> On 23 Mar 2017, at 05:18, Nevin Brackett-Rozinsky via swift-evolution 
>>  wrote:
>> I strongly prefer that “private” should mean “visible in the current file”.
>> I am ambivalent between eliminating the scoped access level or renaming it 
>> “scoped”, as long as “private” once more denotes file-level visibility.
> 
> Imo opinions are split 50/50 on whether access levels should be file based or 
> type based, it's endless debate.
> What are the downsides of covering both cases? I.e. making private "visible 
> in the current file and type extensions".
> This concept is not that hard to teach and doesn't require complex and 
> syntactically verbose access level systems.

I can’t speak for others, but I want scoped access not type-based access.  
Type-based access control solves different problems than scoped access control 
and isn’t under discussion in this review.

> 
> Andrey
> 
> ___
> 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] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 23, 2017, at 10:54 AM, Zach Waldowski via swift-evolution 
>  wrote:
> 
> 
>> On Mar 23, 2017, at 2:22 AM, Matt Gallagher via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> I can't help but feel that this proposal is really misdirected frustration. 
>> Programmers who don't use clusters of tiny types in a single file shouldn't 
>> care about the existence of a scoped access modifier because it shouldn't 
>> affect them – they should use file access modifiers and be done. Yet 
>> apparently, it is file access modifier advocates pushing this proposal.
> 
> It is equally frustrating that those on the opposite side of this proposal 
> keep indicating “just don’t pay attention to it” is an acceptable answer to 
> the language growing an entire axis of confusion to its access control (i.e., 
> a wart) so early in its life.

I think it’s likely that a non-trivial degree of any confusion is related to 
the mistake we made in choosing the names.  Both `fileprivate` and `private` 
include the word `private` in their name.  If we had left `private` alone and 
introduces scoped access with the name `scoped` I think the difference would 
have been much more clear to most people who have been confused.

> 
> Sincerely,
> Zachary Waldowski
> Sent from my Mac
> 
> ___
> 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] Pitch: Partial Implementations

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

> On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
> MOTIVATION:
> 
> In current Swift, a pattern has emerged among some developers, in order to 
> logically group parts of a class or struct’s declaration, particularly around 
> protocols:
> 
> class Foo {
>   …
> }
> 
> extension Foo: SomeProtocol {
>   ...
> }
> 
> extension Foo: SomeOtherProtocol {
>   ...
> }
> 
> This has certain appealing characteristics; in addition to the obvious 
> organizational property, this pattern also keeps protocol implementations 
> close to the declaration of conformance to the protocol. Unfortunately, there 
> are a couple of problems:
> 
> 1. Extensions cannot contain stored properties. This means that if a protocol 
> requires a property, and it makes sense for that property to be stored, its 
> conformance cannot be completely contained within the extension, but rather 
> some of it must be in the main declaration.
> 
> 2. It’s not uncommon for these protocol conformances to need access to the 
> type’s private internal state, but extensions do not have access to private 
> members within the state. This necessitates declaring the needed state as 
> fileprivate rather than private, a fact has been a primary rallying point in 
> the battle that’s currently raging on this mailing list over whether we 
> should keep the ‘private’ access modifier, and which I would surmise is 
> probably the major remaining use of ‘fileprivate’ in modern Swift code.
> 
> 3. Since members that are declared ‘fileprivate’ cannot be accessed outside 
> the file, these protocol conformance extensions must belong to the same file 
> as the original declaration, which can lead to very long file sizes when the 
> code to implement a protocol is very long, or when a type supports a large 
> number of protocols.
> 
> PROPOSED SOLUTION:
> 
> Add a keyword to declare only part of a type’s implementation. I am 
> suggesting ‘partial’ as the keyword, but this can be changed for a better 
> name if needed. Partial conformances would be declared like this:
> 
> class Foo {
>   private func somePrivateMethod() { … }
> }
> 
> partial Foo: SomeProtocol {
>   var someRequiredProperty: Int = 5
> 
>   func someRequiredMethod() {
>   self.somePrivateMethod()
>   }
> }
> 
> partial Foo: SomeOtherProtocol {
>   func someOtherRequiredMethod() {
>   self.somePrivateMethod()
>   }
> }
> 
> When compiling this, the compiler would simply treat all the contents of 
> partial declarations as if they were located within the original declaration, 
> making the above equivalent to this:
> 
> class Foo: SomeProtocol, SomeOtherProtocol {
>   private func somePrivateMethod() { … }
> 
>   var someRequiredProperty: Int = 5
> 
>   func someRequiredMethod() {
>   self.somePrivateMethod()
>   }
> 
>   func someOtherRequiredMethod() {
>   self.somePrivateMethod()
>   }
> }
> 
> Obviously, partial declarations would only be allowed within the same module 
> (or submodule, once we get them) as the original declaration.
> 
> The advantages to this approach are:
> 
> 1. Given a pattern that many developers are adopting, this proposal would 
> provide a mechanism to follow that pattern properly instead of repurposing a 
> mechanism—extensions—which was intended for something else. The Swift manual 
> claims that extensions are meant to add things “to a type that is declared 
> elsewhere, or even to a type that you imported from a library or a 
> framework,” not for separating your own code into parts.
> 
> 2. Partial implementations can now implement the entirety of a protocol, 
> including stored properties if the protocol necessitates them.
> 
> 3. Since the contents of all partial implementations are considered to be 
> part of the same declaration, the contents of partial implementations can 
> access private members, which should allow the almost complete elimination of 
> ‘fileprivate’ from developers’ codebases, simplifying the access control 
> model.
> 
> 4. Since partial implementations are not dependent on file-based 
> organization, they can be stored in separate files, as long as those files 
> are compiled into the same module, thus allowing for smaller, leaner, source 
> files that are easier to read and understand.
> 
> What do you think?

If we wanted to allow code like this to be written we wouldn’t need a new 
keyword to do it.  You are proposing two things here:

1) Allow stored properties in same-module extensions.  This has been discussed 
in the past and is a possibility, but I suspect it is not in scope for 
consideration during Swift 4.
2) Change the meaning of `private` to not mean lexical scope anymore, but 
instead be lexical scope or an extension of the type introducing the lexical 
scope in the same module.  Changes to access control other than the proposal 
currently under review are out of scope for Swift 4.


> 
> Char

Re: [swift-evolution] Pitch: Partial Implementations

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

> On Mar 23, 2017, at 2:04 PM, Charles Srstka  wrote:
> 
>> On Mar 23, 2017, at 1:21 PM, Matthew Johnson > > wrote:
>> 
>> If we wanted to allow code like this to be written we wouldn’t need a new 
>> keyword to do it.  You are proposing two things here:
>> 
>> 1) Allow stored properties in same-module extensions.  This has been 
>> discussed in the past and is a possibility, but I suspect it is not in scope 
>> for consideration during Swift 4.
>> 2) Change the meaning of `private` to not mean lexical scope anymore, but 
>> instead be lexical scope or an extension of the type introducing the lexical 
>> scope in the same module.  Changes to access control other than the proposal 
>> currently under review are out of scope for Swift 4.
> 
> Neither, actually:
> 
> 1) I’m proposing we no longer encourage extensions at all for this purpose. 
> My proposal is simply to allow breaking up declarations into parts, instead.

What I’m suggesting is that we could accomplish the same functionality by 
enhancing extensions.  You can make a case that using a different keyword for 
same-module extensions that are allowed to have stored properties is a good 
idea.  I’m not sure I would support that though.

> 
> 2) I’m not proposing changing the meaning of ‘private’ here. Since partial 
> implementations would all glom into one lexical scope, all the current access 
> control rules would apply as they currently do. This is simply a way to write 
> a class or struct declaration in multiple parts, without having to use 
> extensions.

This does not fit with any definition of “lexical scope” I am familiar with.  I 
wouldn’t want to see Swift adopt this definition of lexical scope.

> 
> Charles
> 

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 23, 2017, at 2:02 PM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
> On 23 Mar 2017, at 16:49, Drew Crawford  > wrote:
> 
>> 
>> 
>> 
>> On March 23, 2017 at 2:22:20 AM, David Hart (da...@hartbit.com 
>> ) wrote:
>> 
>>> > We will get static linking at some point in the near future.
>> 
>> Static linking does not fix this issue. Just change "framework" to ".a".
>> 
> I'm curious to hear what issue your client had with you using many frameworks 
> that static linking doesn't solve.
> 
>>> > If we wait until we get submodules, we won't be able to revisit. This is 
>>> > probably our last chance to "remove" a feature. Submodules can always add 
>>> > features down the way.
>> 
>> Maybe submodules will solve this issue, maybe not.  But submodules are 
>> *much* more complex than scoped access:
>> 
>> * Performance.  This is hot code we compile with WMO.  Moving it into a 
>> submodule could reduce visibility for optimization in a way that causes a 
>> performance regression.  In particular, we know that specialization of T is 
>> a performance requirement, it isn't clear whether that would be preserved.  
>> Does WMO provide the same visibility across submodules?  Nobody knows.
>> 
> I don't see why submodules could not profit from WMO: the module is still 
> compiled all together. Submodules are simply a scoping/hiding mechanism.
>> * Namespacing.  It's possible that one program may ship 3-4 versions of this 
>> code because each dependency has a slightly different version under our 
>> current samizdat process.  It is not clear whether submodules would avoid 
>> the "duplicate symbols" issue from C/ObjC.  Xiaodi seems quite concerned 
>> about a related "duplicate functions" problem involved with private today, 
>> doubling down on that is not a good idea.
>> 
> That looks like a very corner case. I haven't yet found myself in the case 
> where I needed multiple versions of a code base in a same product (binary, 
> framework, application)
>> * It is not clear whether submodules are from an objectcode point of view 
>> merged into the parent library or kept as individual libraries
>> 
> It would be very strange to me if they were independent libraries: what would 
> different them from modules then? No other language I've used works that way.
>> * It is not clear from a .swiftmodule point of view whether submodules are 
>> merged into the parent module or distributed as .swiftmodules / .swiftdocs
>> 
>> * Not clear how much ABI impact there is from submodules at a time when we 
>> are supposed to be trying to stabilize it
>> 
>> I would love to believe that a proposal on submodules will come through 
>> having solutions to all these issues and many more, then we will implement 
>> it and all sing kumbayah.  But we are a long distance from that, and it may 
>> never happen at all, certainly we cannot evaluate proposals that haven't 
>> been written.  Meanwhile we have a solution in the hand.
>> 
> But at the same time, we can't write and review proposals with no regard for 
> future proposals coming down the road or we end up with a clunky language.

Or we can just wait until access control and / or submodules are part of a 
release theme and address these issues more holistically.  As I have said 
before, the details of the submodule design we eventually end up with could 
influence what problems people want access control to address (or not address). 
 It’s possible that we could end up with a design that allows us to eliminate 
`fileprivate` instead of `private` if we feel we must eliminate one of them.  
Right now we just don’t know enough to say for sure.

> ___
> 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] Pitch: Partial Implementations

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

> On Mar 23, 2017, at 2:37 PM, Charles Srstka  wrote:
> 
>> On Mar 23, 2017, at 2:15 PM, Matthew Johnson > > wrote:
>> 
>> What I’m suggesting is that we could accomplish the same functionality by 
>> enhancing extensions.  You can make a case that using a different keyword 
>> for same-module extensions that are allowed to have stored properties is a 
>> good idea.  I’m not sure I would support that though.
> 
> The problem is that people are using extensions to implement part of the 
> original class definition. Part of what is making that pattern awkward is 
> that private members are not accessible from the extensions. Given the 
> SE-0159 discussion, it appears that there is a non-negligible threat of 
> losing the very ability to have scoped members at all if we don’t think of a 
> better alternate solution.
> 
>>> 2) I’m not proposing changing the meaning of ‘private’ here. Since partial 
>>> implementations would all glom into one lexical scope, all the current 
>>> access control rules would apply as they currently do. This is simply a way 
>>> to write a class or struct declaration in multiple parts, without having to 
>>> use extensions.
>> 
>> This does not fit with any definition of “lexical scope” I am familiar with. 
>>  I wouldn’t want to see Swift adopt this definition of lexical scope.
> 
> No definitions required. All I’m proposing is basically preprocessing the 
> thing into one type declaration.
> 
> class Foo {
>   func bar() {}
> }
> 
> partial Foo {
>   func baz() {}
> }
> 
> just becomes syntactic sugar for:
> 
> class Foo {
>   func bar() {}
>   func baz() {}
> }
> 
> After this conversion, bar and baz are in the same lexical scope. No new 
> definitions of anything are required.

Sure, but this does effectively violate lexical scope boundaries as they exist 
in the original source.

> 
> You can also think of the “Foo_Private.h” headers that can be shared amongst 
> several different files in Objective-C.
> 
> Charles
> 

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


Re: [swift-evolution] Pitch: Partial Implementations

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


Sent from my iPhone

> On Mar 23, 2017, at 2:47 PM, Charles Srstka  wrote:
> 
>> On Mar 23, 2017, at 2:45 PM, Matthew Johnson  wrote:
>> 
>> Sure, but this does effectively violate lexical scope boundaries as they 
>> exist in the original source.
> 
> If the yeas have it on SE-0159, and “private” is turned into “fileprivate”, 
> the lexical scope boundaries of *everything* will be violated as they exist 
> in the original source.

Not exactly  We wouldn't be able to talk about them in the access control 
system at all.

My point is that they would no longer be lexical scopes but something else.  
This is not a judgement, only an observation.


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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 23, 2017, at 8:27 PM, Drew Crawford  wrote:
> 
> 
> 
> 
> Sent from my iPhone
> On Mar 23, 2017, at 6:41 PM, David Hart  wrote:
> 
>> I have difficulties imagining a submodule proposal that could allow us to 
>> eliminate fileprivate. Care to give an example?
> 
> The obvious example would be Rust.  Rust has exactly two visibilities, and 
> merely one keyword.  By default, members are "private" which is visible 
> inside the module (so, like Swift's internal). The "public" keyword is 
> similar to Swift. 
> 
> The reason this works is that unlike in Swift where a module is something 
> like a library or framework (Rust calls those "crates"), in Rust modules in 
> are (explicitly) lexically scoped; a "mod myscope {}" module can be created 
> for the portion of the file for which the member should be visible and it 
> won't be visible outside that scope. Likewise, "fileprivate" can be achieved 
> by enclosing the file in a "mod MyFile {}". And like all lexical scopes, they 
> can be recursively nested to arbitrary depth to achieve any number of 
> visibility behaviors (e.g., declare a module for the first half of two files) 
> that would require complex new keywords to achieve in Swift. Finally there 
> are some shortcut features like the ability to infer a module structure from 
> the file system. 

This is a good example of what I meant.  There is an extremely broad range of 
possible designs for submodules.  Some of them, such as this example, would 
make it relatively easy to get by without fileprivate.  There are also many 
other possible designs that would not.  

We do not have any idea where Swift will end up yet.  It's not reasonable to 
make any assumptions about what use cases the eventual design might or might 
not address.

> 
> 
> 
> In Swift, modules are presently tied to libraries/frameworks in a 1:1 way. 
> Because of this we lack the flexibility of recursively nestable modules of 
> other languages and this is the underlying problem that motivates both 
> scoped/private and fileprivate.  If we fixed that, we would actually not need 
> either keyword. 
> 
> http://rustbyexample.com/mod/visibility.html
> https://doc.rust-lang.org/book/crates-and-modules.html
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 23, 2017, at 9:48 PM, Charles Srstka  wrote:
> 
>> On Mar 23, 2017, at 8:35 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> On Mar 23, 2017, at 8:27 PM, Drew Crawford  wrote:
>> 
>>> 
>>> 
>>> 
>>> Sent from my iPhone
>>> On Mar 23, 2017, at 6:41 PM, David Hart  wrote:
>>> 
>>>> I have difficulties imagining a submodule proposal that could allow us to 
>>>> eliminate fileprivate. Care to give an example?
>>> 
>>> The obvious example would be Rust.  Rust has exactly two visibilities, and 
>>> merely one keyword.  By default, members are "private" which is visible 
>>> inside the module (so, like Swift's internal). The "public" keyword is 
>>> similar to Swift. 
>>> 
>>> The reason this works is that unlike in Swift where a module is something 
>>> like a library or framework (Rust calls those "crates"), in Rust modules in 
>>> are (explicitly) lexically scoped; a "mod myscope {}" module can be created 
>>> for the portion of the file for which the member should be visible and it 
>>> won't be visible outside that scope. Likewise, "fileprivate" can be 
>>> achieved by enclosing the file in a "mod MyFile {}". And like all lexical 
>>> scopes, they can be recursively nested to arbitrary depth to achieve any 
>>> number of visibility behaviors (e.g., declare a module for the first half 
>>> of two files) that would require complex new keywords to achieve in Swift. 
>>> Finally there are some shortcut features like the ability to infer a module 
>>> structure from the file system. 
>> 
>> This is a good example of what I meant.  There is an extremely broad range 
>> of possible designs for submodules.  Some of them, such as this example, 
>> would make it relatively easy to get by without fileprivate.  There are also 
>> many other possible designs that would not.  
>> 
>> We do not have any idea where Swift will end up yet.  It's not reasonable to 
>> make any assumptions about what use cases the eventual design might or might 
>> not address.
> 
> Then why not leave private and fileprivate alone until we do?

That is what I have suggested, with an alternative of renaming if we feel 
compelled to make a change now.

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


Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 24, 2017, at 6:11 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> `scoped` was the name originally proposed in SE-0025, changed by the core 
> team on acceptance to `private`, and `file` was one of the suggestions for 
> what used to be called `private`; I remember because I suggested it too; it 
> was renamed to `fileprivate` after consideration of this alternative.

I believe the original proposal actually used `local` which I thought was not a 
good name.  `scoped` didn't receive significant discussion (any that I recall) 
until after Swift 3 was already released.

> 
> 
>> On Fri, Mar 24, 2017 at 5:27 AM, Vinnie Hesener via swift-evolution 
>>  wrote:
>> This discussion escalated real quickly. There are some very bright minds in 
>> the mud right now, but I think there may still be a way to salvage this 
>> discussion. 
>> 
>> Chris talked about there being two layers to Swift... the easy mode for 
>> adoption and outreach, then the advanced mode for taking over the world. 
>> This requires a delicate balance of features vs usability (e.g. MS Paint vs 
>> Photoshop). There are various ways to approach that balance, but they almost 
>> always require creativity and cooperation from the smartest guys in the room.
>> 
>> I'm not one of those guys, but let me throw out some food for thought. Is 
>> there a way to not only please both generalized arguments, but also solve 
>> the root of the problem? For instance, has anyone thought about why we even 
>> call things public, private, etc? Other than their initial meaning, the 
>> answer may be "other languages do it" or even better "that is what prevents 
>> confusion and dupe questions on stackoverflow". Fair enough.
>> 
>> I realize this would be jolting for most, but would anyone be asking the 
>> stackoverflow ether what a **scope** var was? How about a **file** func? How 
>> about a SO title: "What does **module** let myVar refer to?" 
>> 
>> Don't we have the opportunity to offer, within reason, a large set of 
>> accessors that are self explanatory? I think it may solve the complexity for 
>> usefulness exchange because they are simply there for the advanced users 
>> that want to use them. There's no choosing for newbs because the choice is 
>> in the name, assuming we name them pristinely (I have faith!). 
>> 
>> I'm also a little cooky too, but maybe this can spark some creativity in a 
>> more wholistic solution for both sides. 
>>  
>> 
>> > Hello Swift community,
>> > 
>> > The review of SE-0159 "Fix Private Access Levels" begins now and runs 
>> > through March 27, 2017. The proposal is available here:
>> > 
>> > https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.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. When replying, please try to keep the proposal link at the 
>> > top of the message:
>> > 
>> > Proposal link:
>> > 
>> > https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md
>> > Reply text
>> > Other replies
>> > 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 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
>> > Thank you,
>> > 
>> > -Doug
>> > 
>> > 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
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/list

Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 24, 2017, at 4:59 AM, Jonathan Hull  wrote:
> 
> 
> Several people have asked:  What is the harm it causes?
> 
> I would like to provide a (hopefully) clear answer to that.
> 
> There are a couple of problems with the design which are causing Cognitive 
> Dissonance:
> 
> 1) Private & fileprivate require very different mental models to operate them
> 2) They are named very similarly to each other
> 3) There is a third concept of “private to the type” which requires a third 
> mental model, but is spelled the same way in other languages 
> 
> Any one of these would cause confusion.  All of them together mean that even 
> those of us who understand how they work are bothered by them on a 
> subconscious level (similar to how misaligned graphics will give everyone a 
> subconscious feeling that a graphic design is “off” even if they can’t 
> discern why consciously).  Even many of those who are arguing to keep private 
> have argued to rename things or to make it work in a more type-based way by 
> extending visibility to extensions.  I don’t think anyone is denying there is 
> a problem here with the status quo.
> 
> There is a general rule in design that things that look similar (or in this 
> case are named similarly) need to behave similarly to avoid causing confusion 
> (and conversely things that behave differently *need* to look different).
> 
> **This is not something that will go away simply by learning the behavior.  
> It will continue to be a rough spot in the language that causes discomfort 
> until the underlying design issue is fixed.**
> 
> The ideal solution here would be to choose a single model and make everything 
> coherent under that.  We choose either file-based, scope-based, or type-based 
> access control and unify under that.

All of Swift's access modifiers are already scope-based.  Files and modules 
form scopes.  Maybe this concept is new to a lot of people, but it is not 
internally inconsistent and does not make it a bad design.  I do agree that the 
current names are not great.

> 
> For file-based, that means that our sub-modules, when we add them, would need 
> to be file-based as well.
> 
> If we choose Scope-based, then it really cries out for some sort of 
> parameterized private.  That is you only have private and public, but for 
> private you would be able to name a scope to widen the visibility to the 
> named scope.  Submodules would then need to be scope based, and you would 
> probably use the parameterized private with the submodule name to share data 
> within it.
> 
> Type-based is very common in other languages, but I fear it would not play 
> nicely with the way Swift has grown to work.  The pros are that you could 
> access private variables from extensions, but getting types to work together 
> with the ease they do now would require a lot of design work (and may not 
> even be quite possible).  You also have additional complexities around 
> subtypes, etc...
> 
> 
> We really need to choose a single direction and not mix and match.
> 
> Of the three, I am personally most supportive of file-based because it is the 
> closest to where we are now, and it seems to simplify many of the concerns 
> about “friend” types by having visibility be dependent on proximity… which 
> seems very intuitive to me.
> 
> As I said before, my preference would be to tentatively accept the change, 
> but delay implementation until we design submodules for Swift 5. That way the 
> design can be more cohesive as we can tackle it all at once.  If submodules 
> won’t be in scope until after Swift 5, then we should implement the change 
> now.
> 
> I hope that explanation was at least a bit helpful…
> 
> Thanks,
> Jon
> 
> Technical note:  For the curious, basically we have made a design which is 
> "locally consistent, but globally inconsistent".  That is why the effect 
> doesn’t go away after learning the concepts involved.  Basically we have made 
> the programming equivalent of the following image:
> 
> https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png
>  
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 24, 2017, at 11:53 AM, Drew Crawford via swift-evolution 
>  wrote:
> 
> 
> 
> 
>> On March 24, 2017 at 11:46:00 AM, Charles Srstka (cocoa...@charlessoft.com) 
>> wrote:
>> 
 On Mar 24, 2017, at 11:41 AM, Drew Crawford via swift-evolution 
  wrote:
>>> 
>>> I would argue that supporting whatever the programmer's chosen mental model 
>>> is actually Swift's greatest strength.  We could have a language with only 
>>> reference types for example, it would be far, far simpler and easier to 
>>> teach.  I am glad that we don't have that language.
>> 
>> We kinda do, though, or did, in Objective-C (well, the “Objective” parts of 
>> it, anyway).
>> 
>> Charles
>> 
> 
> Exactly.  I mean the same people who brought us ObjC decided we needed a 
> language with multiple mental models.  They could have shipped reference 
> types only, they shipped value types on day 1.  To me there is no clearer 
> plank in the platform than that.
> 
> If you like your ObjC, you can keep it.  Swift exists exactly because we 
> reject some (not all) of the ObjC way, and it's not just syntax.  One of the 
> things rejected is There Should Be One Way To Do It™.  Swift embraces many 
> ways to write your program and has from 1.0.

+1.  I love this aspect of Swift.  It lets me choose the tool and model best 
suited to each specific task.

> ___
> 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] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 26, 2017, at 4:13 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On Mar 26, 2017, at 4:27 AM, Goffredo Marocchi  wrote:
>>> On 26 Mar 2017, at 06:54, John McCall via swift-evolution 
>>>  wrote:
>>> 
 On Mar 25, 2017, at 2:11 AM, Carl Brown1 via swift-evolution 
  wrote:
 Yes, it would change my opinion of it. I wouldn't become a strong 
 supporter because I don't see any value in it, but a rigorous proof that 
 this proposal could not possibly introduce regressions to any existing 
 codebases would change my opinion from "strongly against" to "doesn't 
 matter to me, I'll stop arguing against it and go get my real work done".
 
>>> Speaking just for myself, this was a key part of why I was attracted to 
>>> this proposal: it seemed to me to be extremely unlikely to cause 
>>> regressions in behavior.  Even without any special behavior in the 
>>> migrator, code will mostly work exactly as before: things that would have 
>>> been invalid before will become valid, but not the other way around.  The 
>>> exception is that old-private declarations from scopes in the same file can 
>>> now be found by lookups in different scopes (but still only within the same 
>>> file).  It should be quite straightforward for the migrator to detect when 
>>> this has happened and report it as something for the programmer to look at. 
>>>  The proposal causes a small regression in functionality, in that there's 
>>> no longer any way to protect scopes from accesses within the file, but (1) 
>>> it's okay for Swift to be opinionated about file size and (2) it seems to 
>>> me that a workable sub-module proposal should solve that more elegantly 
>>> while simultaneously addressing the concerns of the people who dislike 
>>> acknowledging the existence of files.
>> 
>> The opinionated flag sometimes, like being Swifty, is being used to swath 
>> away disagreement, but opinions should be reasonable and pragmatic too... 
>> opinionated as "you will code this way and you will like it" seems hardly 
>> ideal too if abused constantly. Programming is a creative endeavour too.
>> 
>> Also, removing a feature that is used and is useful because "maybe" a year 
>> or more away there could be a feature that may address the concerns of the 
>> people we are stripping away the current feature from seems quite harsh and 
>> unfriendly at best... not very logical either.
> 
> Scoped-private is not some awesomely expressive feature.  It's an access 
> restriction.  The "opinion" I'm talking about hardly prevents you from coding 
> however you like.  It's just this: organizing your code into smaller, more 
> self-contained components separated by file is good practice anyway, and when 
> you do that, Swift will let you enforce that each component is properly 
> encapsulated.

This does not address the case where we have a small helper type that is only 
10s of lines long, is not visible outside the file, and encapsulates an 
important part of the implementation using scoped private.  The whole file is 
usually only a couple hundred lines.  This is not an excessively long file and 
already contains a single component that is presented to the rest of the 
program.

Some designs of submodules might allow us to properly encapsulate everything 
but if that requires us to put a small helper type in a separate file that 
would be a very unfortunate and inflexible constraint on how we are able to 
organize our code. 

 I don't want encapsulation concerns dictating how I physically organize my 
code.  That is significant and unnecessary complexity if you ask me.  It forces 
a tradeoff between desired physical organization and desired encapsulation.  We 
should not force users to make this tradeoff.

> 
> John.
> 
>> 
>>> 
>>> John.
 -Carl
 
 Xiaodi Wu ---03/25/2017 12:33:55 AM---Would it change your 
 opinion on the proposal? On Sat, Mar 25, 2017 at 12:10 AM, Carl Brown1 
 >>> 
 From: Xiaodi Wu 
 To: Carl Brown1/US/IBM@IBM
 Cc: Drew Crawford , Jonathan Hull 
 , swift-evolution 
 Date: 03/25/2017 12:33 AM
 Subject: Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels
 
 
 
 
 Would it change your opinion on the proposal?
 
 
 On Sat, Mar 25, 2017 at 12:10 AM, Carl Brown1  wrote:
 I would very much like to see your proof that the resultant code is 
 unchanged in an arbitrary codebase. 
 
 -Carl
 
 Xiaodi Wu ---03/25/2017 12:01:26 AM---On Fri, Mar 24, 2017 at 
 11:55 PM, Carl Brown1  wrote: > Maybe this is the core
 
 From: Xiaodi Wu 
 To: Carl Brown1/US/IBM@IBM
 Cc: Drew Crawford , Jonathan Hull 
 , swift-evolution 
 Date: 03/25/2017 12:01 AM
 Subject: Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels
 
 
 
 On Fri, Mar 24, 2017 at 11:55 PM, Carl Brown1  wrote:
 My point is that, in rolling back the specific por

Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 26, 2017, at 12:15 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> On Mar 26, 2017, at 11:57 AM, David Sweeris via swift-evolution 
>>  wrote:
>> 
>> On Mar 26, 2017, at 08:50, David James via swift-evolution 
>>  wrote:
>> 
>>> • What is your evaluation of the proposal?
>>> -1 as written (see below)
>>> 
>>> • Is the problem being addressed significant enough to warrant a change to 
>>> Swift?
>>> Not as written
>>> 
>>> • Does this proposal fit well with the feel and direction of Swift?
>>> It does in terms of apparent simplicity, but not in terms of practicality. 
>>> I like to think of Swift as a practical language that does not sacrifice 
>>> utility for apparent simplicity.
>>> 
>>> • If you have used other languages or libraries with a similar feature, how 
>>> do you feel that this proposal compares to those?
>>> Can’t be compared. Swift has already set a precedent by making “private” 
>>> mean something non-traditional (pre SE-0025), and I think it was a good 
>>> decision, taking us away from the idea that private is only useful with 
>>> parent inheritance structures. 
>>> 
>>> • How much effort did you put into your review? A glance, a quick reading, 
>>> or an in-depth study?
>>> Have been following it since SE-0025, the aftermath, extensive experience 
>>> using the modifiers in framework code I write and reading all related 
>>> threads on SE.
>>> 
>>> ***
>>> 
>>> I propose instead that we revise to use Alternative #3, per Vladimir’s 
>>> comment and revision.
>>> 
>>> Revised version:
>>> 
>>> “3. Revert private to be file-based and introduce the scope-based access 
>>> level under a new name (e.g.: scoped, local, etc), provided that the 
>>> scope-based access modifier is not used at the top level of the file.” 
>>> (addendum via Vladimir’s revised comment)
>> 
>> Yeah, within reason, I couldn't care less how "private"/"fileprivate" are 
>> spelled. What I'm against is removing the functionalityof the current 
>> "private" without simultaneously providing a semantically equivalent 
>> replacement.
> 
> I’ll second that. Don’t care what the scoped access modifier is called, as 
> long as there is one.

Agree.  I don't think any supporters are insisting it be called private.  
Renaming seems like the compromise that satisfies the greatest number of people.

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


Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 26, 2017, at 10:43 AM, Xiaodi Wu  wrote:
> 
> This reaches the crux of the issue, doesn't it? The Swift 2 design for access 
> modifiers does exactly what you reject: that design is based on the premise 
> that it is wise for file organization to follow encapsulation.

It's always a gamble speculating about the premise of someone else's design.  
That said, if I had to guess I would imagine maybe it had as much to do with 
the legacy of C-family languages and header files as anything else.

> 
> Now, afaik, the accepted rationale for "new private" was that there needed to 
> be something _more_ to fill out that scheme. And here the argument is that it 
> didn't really add much benefit but brought about more complexity.
> 
> If, however, what you're saying is that you reject the whole idea behind 
> "fileprivate" altogether, well...I don't know if making it possible to ignore 
> file-based encapsulation was ever really on the menu.

I'm not saying I reject the idea of file scopes at all.  There are submodule 
designs that would make file scopes redundant, but that is as far as I've gone. 
 We certainly need it in Swift 4 where we won't have submodules at all. 

However, if the community strongly desires a change to remove one of the access 
modifiers I do think we should explore submodule designs that would fill the 
use cases for file scope and perhaps allow us to eliminate that.  This would 
obviously need to happen in a future release where that is in scope.  That is 
why I've been arguing that we should not force churn on users now.  We should 
wait until we are ready to address all problems related to access control and 
submodules more holistically.

It sounds like the comments in my reply to John may not have even clear to you. 
  What I'm saying is that file scopes and submodules cannot replace scoped 
access without forcing a tradeoff between code organization and encapsulation.  
This is a tradeoff I don't want to be forced to make.  If I choose 
encapsulation that would result in many more very small files (10s of lines) 
than I would like.  Just as large files can make code difficult to navigate, 
too many very small files can also make code difficult to navigate and can 
result in a lot of thrashing between files.  

It should be possible to place small types together in the same file without 
sacrificing encapsulation.  It should also be possible to have a small helper 
type in the same file as the type it is supporting without sacrificing 
encapsulation.  This requirement can only be met by scoped access or something 
very similar.

In fact, I very often use file scopes in conjunction with scopes access.  
`private` is used to encapsulate state which is crucial to preserving 
invariants, etc of a helper type and `fileprivate` is used to restrict 
visibility of the helper type to the current file.


>> On Sun, Mar 26, 2017 at 07:30 Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Mar 26, 2017, at 4:13 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>>>> On Mar 26, 2017, at 4:27 AM, Goffredo Marocchi  wrote:
>>>> On 26 Mar 2017, at 06:54, John McCall via swift-evolution 
>>>>  wrote:
>>>> 
>>>>>> On Mar 25, 2017, at 2:11 AM, Carl Brown1 via swift-evolution 
>>>>>>  wrote:
>>>>>> Yes, it would change my opinion of it. I wouldn't become a strong 
>>>>>> supporter because I don't see any value in it, but a rigorous proof that 
>>>>>> this proposal could not possibly introduce regressions to any existing 
>>>>>> codebases would change my opinion from "strongly against" to "doesn't 
>>>>>> matter to me, I'll stop arguing against it and go get my real work done".
>>>>>> 
>>>>> Speaking just for myself, this was a key part of why I was attracted to 
>>>>> this proposal: it seemed to me to be extremely unlikely to cause 
>>>>> regressions in behavior.  Even without any special behavior in the 
>>>>> migrator, code will mostly work exactly as before: things that would have 
>>>>> been invalid before will become valid, but not the other way around.  The 
>>>>> exception is that old-private declarations from scopes in the same file 
>>>>> can now be found by lookups in different scopes (but still only within 
>>>>> the same file).  It should be quite straightforward for the migrator to 
>>>>> detect when this has happened and report it as something for the 
>>>>> programmer to look at.

Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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

> On Mar 26, 2017, at 12:26 PM, John McCall  wrote:
> 
>> On Mar 26, 2017, at 8:30 AM, Matthew Johnson > > wrote:
>> On Mar 26, 2017, at 4:13 AM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
 On Mar 26, 2017, at 4:27 AM, Goffredo Marocchi >>> > wrote:
 On 26 Mar 2017, at 06:54, John McCall via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
>> On Mar 25, 2017, at 2:11 AM, Carl Brown1 via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> Yes, it would change my opinion of it. I wouldn't become a strong 
>> supporter because I don't see any value in it, but a rigorous proof that 
>> this proposal could not possibly introduce regressions to any existing 
>> codebases would change my opinion from "strongly against" to "doesn't 
>> matter to me, I'll stop arguing against it and go get my real work done".
>> 
> Speaking just for myself, this was a key part of why I was attracted to 
> this proposal: it seemed to me to be extremely unlikely to cause 
> regressions in behavior.  Even without any special behavior in the 
> migrator, code will mostly work exactly as before: things that would have 
> been invalid before will become valid, but not the other way around.  The 
> exception is that old-private declarations from scopes in the same file 
> can now be found by lookups in different scopes (but still only within 
> the same file).  It should be quite straightforward for the migrator to 
> detect when this has happened and report it as something for the 
> programmer to look at.  The proposal causes a small regression in 
> functionality, in that there's no longer any way to protect scopes from 
> accesses within the file, but (1) it's okay for Swift to be opinionated 
> about file size and (2) it seems to me that a workable sub-module 
> proposal should solve that more elegantly while simultaneously addressing 
> the concerns of the people who dislike acknowledging the existence of 
> files.
 
 The opinionated flag sometimes, like being Swifty, is being used to swath 
 away disagreement, but opinions should be reasonable and pragmatic too... 
 opinionated as "you will code this way and you will like it" seems hardly 
 ideal too if abused constantly. Programming is a creative endeavour too.
 
 Also, removing a feature that is used and is useful because "maybe" a year 
 or more away there could be a feature that may address the concerns of the 
 people we are stripping away the current feature from seems quite harsh 
 and unfriendly at best... not very logical either.
>>> 
>>> Scoped-private is not some awesomely expressive feature.  It's an access 
>>> restriction.  The "opinion" I'm talking about hardly prevents you from 
>>> coding however you like.  It's just this: organizing your code into 
>>> smaller, more self-contained components separated by file is good practice 
>>> anyway, and when you do that, Swift will let you enforce that each 
>>> component is properly encapsulated.
>> 
>> This does not address the case where we have a small helper type that is 
>> only 10s of lines long, is not visible outside the file, and encapsulates an 
>> important part of the implementation using scoped private.  The whole file 
>> is usually only a couple hundred lines.  This is not an excessively long 
>> file and already contains a single component that is presented to the rest 
>> of the program.
> 
> I acknowledge that this case exists, but by definition, it's a tiny amount of 
> code being "protected" from an almost equally tiny amount of code.

Sure, but I’ve seen cases where it can be used to avoid problems that arise in 
real projects with experienced programmers.  Compiler verification provides a 
useful “reminder” to both maintainers and reviewers about the correct thing to 
do.  This can be especially helpful when somebody is new to a project or when 
revisiting code you haven’t looked at in quite some time.

I would never argue that this is as important as many other features in Swift 
but that isn’t the standard that has been set.  The standard that has been set 
for breaking changes is one of “actively harmful”.  As I have stated before, I 
think one can make a reasonable case that the current names `fileprivate` and 
`private` are actively harmful.  However, I don’t think a strong case can be 
made that scoped access in itself is actively harmful.  Instead, I think a 
reasonably strong case has been made that it is actively harmful to remove it.  
If that were not the case we wouldn’t see roughly half of the responses to this 
thread saying no to this proposal.  People are benefiting from this feature.

> 
> Access control is primarily communicative.  A person who adds unwanted uses 
> of a private property can also just as easily cha

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

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


Sent from my iPad

> On Mar 26, 2017, at 7:03 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> 
>> On Mar 26, 2017, at 11:12 AM, Karl Wagner via swift-evolution 
>>  wrote:
>> 
>> I’d like to pitch the following two language changes. Both of them are 
>> technically possible today if you manually write thunks for the relevant 
>> protocol requirements, but it would be nice if we allowed them to be written 
>> directly:
>> 
>> 1) Allow closures to satisfy function requirements in protocols
> 
> I have mixed feelings about this one because of the argument labels issue.
> 
> 
>> 
>> 2) Allow functions with default parameters to satisfy function requirements 
>> in protocols
>> 
> 
> This would be an excellent improvement. I don’t think it needs an SE 
> proposal, it is “obvious” how it would work.
> 
> I would also add the following for full generality:
> 
> 3) Allow enum cases without payloads to satisfy static read-only property 
> requirements
> 4) Allow enum cases with payloads to satisfy static method requirements

I was just thinking about these the other day.  Good to know you're already 
thinking about them!

> 
> Slava
> 
> ___
> 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] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 26, 2017, at 8:44 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Mar 26, 2017, at 10:43 AM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>>> On Mar 26, 2017, at 10:43 AM, Xiaodi Wu  wrote:
>>> 
>>> This reaches the crux of the issue, doesn't it? The Swift 2 design for 
>>> access modifiers does exactly what you reject: that design is based on the 
>>> premise that it is wise for file organization to follow encapsulation.
>> 
>> It's always a gamble speculating about the premise of someone else's design. 
>>  That said, if I had to guess I would imagine maybe it had as much to do 
>> with the legacy of C-family languages and header files as anything else.
> 
> 
> I've seen people say this several times in access control threads, but 
> personally, I don't think the use of files for access control is a "legacy" 
> or a coincidence. I think it's a pretty smart move.
> 
> By its nature, the `internal` scope is already defined by files: There is a 
> certain set of files which are compiled together to form the module, and 
> those files all see the same `internal` scope. Unless we entirely abandon the 
> idea of Swift as a fully textual language and move to a FoxPro-style system 
> where code is stored in a structured database, this will always be true in 
> Swift. I have a hard time imagining an environment for writing Swift code 
> where there *aren't* files or some equivalent named-chunk-of-arbitrary-code 
> unit of organization like the "pages" in a playground.
> 
> Using files to scope `private` is thus a natural extension of the `internal` 
> scope's rules (one group of files defines the `internal` scope; one single 
> file defines the `private` scope). It also happens to fit well with typical 
> programmer behavior. Organizing your code into files by concern is generally 
> considered a best practice, but files do not carry any other semantic 
> meaning: there's nothing (else) in the language that forces you to put a 
> given declaration in one file or another. So with file-based `private`, there 
> are only two reasons to care about which file a piece of code is in—`private` 
> access and subjective code organization—and these two things are usually 
> aligned.

They're usually aligned at one level of granularity but often not at another.  
Small helper types are subjectively best placed in the same file as the type 
they are assisting yet there are still good reasons to encapsulate their state. 
 Further, they should not be visible beyond the code they are helping.  

Even if you can properly encapsulate everything as desired using separate files 
and submodules you are left with code organization that subjectively and 
pragmatically is suboptimal.  I don't want a bunch of files with 20 line helper 
types in my project.  This leads to way too much file switching which 
significantly reduces clarity. 

> 
> This point is actually implicitly acknowledged by, for instance, the 
> submodule proposal Jonathan Hull put forth upthread, where each file is 
> implicitly its own submodule if not declared to be part of a different one. 
> Files aren't always the right encapsulation boundary, but they often are.

I agree that files are often the right boundary for encapsulation and have not 
argued against allowing us to address file scopes (unless of course we get a 
submodule solution that makes them redundant).  I also agree that using groups 
of files to organize code into submodules makes a lot of sense.

My point is simply that there is nothing inevitable about using them as an 
access control boundary.  There are tradeoffs involved.  Having files be the 
largest addressable scope smaller than the module is largely responsible for 
the long file problem in Swift code.  Certainly far more responsible than 
scoped access control.  (This point was made in response to John's reference to 
10,000 line files).

I have nothing at all against all the uses of files you describe above.  I just 
don't think files are the answer to every use case for access control.  There 
are strong pragmatic reasons for allowing encapsulation of types within a file. 
 

> 
> What *can't* file-based organization do, but explicit or implicit scope 
> boundaries can? Well, they can't nest. But as I've previously argued, 
> limiting access to the confines of a nested scope is often problematic 
> because you can only address the current scope, not a surrounding scope;

This is not an inevitable state of affairs.  Again we have a tradeoff and could 
allow addressing containing scopes if desired.  But let's not have that debate 
right now.

For scopes smaller than a file, the current scope is by far t

Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

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


Sent from my iPad

> On Mar 26, 2017, at 9:44 PM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Mar 26, 2017, at 8:44 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Mar 26, 2017, at 10:43 AM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>>> On Mar 26, 2017, at 10:43 AM, Xiaodi Wu  wrote:
>>>> 
>>>> This reaches the crux of the issue, doesn't it? The Swift 2 design for 
>>>> access modifiers does exactly what you reject: that design is based on the 
>>>> premise that it is wise for file organization to follow encapsulation.
>>> 
>>> It's always a gamble speculating about the premise of someone else's 
>>> design.  That said, if I had to guess I would imagine maybe it had as much 
>>> to do with the legacy of C-family languages and header files as anything 
>>> else.
>> 
>> 
>> I've seen people say this several times in access control threads, but 
>> personally, I don't think the use of files for access control is a "legacy" 
>> or a coincidence. I think it's a pretty smart move.
>> 
>> By its nature, the `internal` scope is already defined by files: There is a 
>> certain set of files which are compiled together to form the module, and 
>> those files all see the same `internal` scope. Unless we entirely abandon 
>> the idea of Swift as a fully textual language and move to a FoxPro-style 
>> system where code is stored in a structured database, this will always be 
>> true in Swift. I have a hard time imagining an environment for writing Swift 
>> code where there *aren't* files or some equivalent 
>> named-chunk-of-arbitrary-code unit of organization like the "pages" in a 
>> playground.
>> 
>> Using files to scope `private` is thus a natural extension of the `internal` 
>> scope's rules (one group of files defines the `internal` scope; one single 
>> file defines the `private` scope). It also happens to fit well with typical 
>> programmer behavior. Organizing your code into files by concern is generally 
>> considered a best practice, but files do not carry any other semantic 
>> meaning: there's nothing (else) in the language that forces you to put a 
>> given declaration in one file or another. So with file-based `private`, 
>> there are only two reasons to care about which file a piece of code is 
>> in—`private` access and subjective code organization—and these two things 
>> are usually aligned.
> 
> They're usually aligned at one level of granularity but often not at another. 
>  Small helper types are subjectively best placed in the same file as the type 
> they are assisting yet there are still good reasons to encapsulate their 
> state.  Further, they should not be visible beyond the code they are helping. 
>  
> 
> Even if you can properly encapsulate everything as desired using separate 
> files and submodules you are left with code organization that subjectively 
> and pragmatically is suboptimal.  I don't want a bunch of files with 20 line 
> helper types in my project.  This leads to way too much file switching which 
> significantly reduces clarity. 

I should have also mentioned that helper types are not the only use case for 
scoped access.  I often use `private` to hide encapsulates state of a type from 
much of the implementation of the type itself.  The state and basis methods 
that operate on it are placed in the type declaration.  Other methods which are 
defined in terms of the basis methods are placed in extensions.  The basis 
methods may or may not be visible outside the file.

All of the concerns relevant for helper types are relevant for this use case.  
It is a very useful way to organize code.  It would be unfortunate to see the 
language lose the excellent support it currently has for this style of 
programming.

> 
>> 
>> This point is actually implicitly acknowledged by, for instance, the 
>> submodule proposal Jonathan Hull put forth upthread, where each file is 
>> implicitly its own submodule if not declared to be part of a different one. 
>> Files aren't always the right encapsulation boundary, but they often are.
> 
> I agree that files are often the right boundary for encapsulation and have 
> not argued against allowing us to address file scopes (unless of course we 
> get a submodule solution that makes them redundant).  I also agree that using 
> groups of files to organize code into submodules makes a lot of sense.
> 
> My point is simply that there is nothing inevitable about using them as an 
> access control boundary.  There are tradeoff

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

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

> On Mar 26, 2017, at 8:01 PM, Slava Pestov  wrote:
> 
>> 
>> On Mar 26, 2017, at 5:32 PM, Matthew Johnson > > wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>> On Mar 26, 2017, at 7:03 PM, Slava Pestov via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
 On Mar 26, 2017, at 11:12 AM, Karl Wagner via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 I’d like to pitch the following two language changes. Both of them are 
 technically possible today if you manually write thunks for the relevant 
 protocol requirements, but it would be nice if we allowed them to be 
 written directly:
 
 1) Allow closures to satisfy function requirements in protocols
>>> 
>>> I have mixed feelings about this one because of the argument labels issue.
>>> 
>>> 
 
 2) Allow functions with default parameters to satisfy function 
 requirements in protocols
 
>>> 
>>> This would be an excellent improvement. I don’t think it needs an SE 
>>> proposal, it is “obvious” how it would work.
>>> 
>>> I would also add the following for full generality:
>>> 
>>> 3) Allow enum cases without payloads to satisfy static read-only property 
>>> requirements
>>> 4) Allow enum cases with payloads to satisfy static method requirements
>> 
>> I was just thinking about these the other day.  Good to know you're already 
>> thinking about them!
> 
> Want to try your hand at implementing them? ;-) Would be a good starter 
> project for diving into Sema and SILGen. I can give pointers and guidance.

I’d love to but alas I have too many projects and too little time already.  :)

> 
> Slava
> 
>> 
>>> 
>>> Slava
>>> 
>>> ___
>>> 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-27 Thread Matthew Johnson via swift-evolution

> On Mar 27, 2017, at 12:25 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Mar 24, 2017, at 6: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.
> 
> It was, indeed, something of a policy goal for awhile to not have any 
> compiler warnings in Swift.  The idea was that anything suspect should be an 
> error.  We deliberately backed away from that because it was actually really 
> disruptive to the development experience: even very conscientious programmers 
> who diligently fix all their warnings sometimes have code "in flight", so to 
> speak, and want to be able to test and debug it without immediately making 
> invasive edits.  To use a germane example, if unreachable code were always an 
> error, a programmer trying to debug a problem wouldn't be able to 
> short-circuit a function by just adding a return; they'd also have to comment 
> out the rest of the function.
> 
> I think we're comfortable with the current balance.  It's understood that 
> some programmers just ignore compiler warnings, but there are costs on the 
> other side, too.

+1.  I like this being a warning for exactly the reasons you state.  It’s very 
useful to sometimes be able to just insert an early return when debugging.

> 
> John.
> 
>> 
>> If you would like to see more defect examples from open-source software 
>> (other languages for the moment), I am able to dig up such things.
>> 
>> Thanks
>> 
>> --
>> Peter Dillinger, Ph.D.
>> Software Engineering Manager, Coverity Analysis, Software Integrity Group | 
>> Synopsys
>> www.synopsys.com/software
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Smart KeyPaths

2017-03-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 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 
>>> mailto:swift-evolution@swift.org>> 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-30 Thread Matthew Johnson via swift-evolution


Sent from my iPad

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

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

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

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

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

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0155: Normalize Enum Case Representation

2017-04-01 Thread Matthew Johnson via swift-evolution

>   • What is your evaluation of the proposal?

+1.  I am very happy with the tradeoffs made in the revision of this proposal.  
It feels like the right step for Swift 4.  It updates enum cases to align with 
the general direction Swift has taken.  This improves consistency now and 
provides the right foundation for the future enhancements.

>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?

Yes, enum cases as they exist in Swift 3.1 are a bit out of sync with the rest 
of the language.  This proposal addresses this directly.

>   • Does this proposal fit well with the feel and direction of Swift?

Yes, very much.

>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

N/A

>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

I have followed all of the relevant threads and drafts closely and provided 
feedback regularly.  The final draft shows that the authors have done great job 
of listening to the community and incorporating feedback.  Thank you very much 
for continuing to push this forward!

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


Re: [swift-evolution] [Review] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-01 Thread Matthew Johnson via swift-evolution
> 
> What is your evaluation of the proposal?
+1.  This is a fantastic proposal!  I have been looking forward to the ability 
to access unbound properties ever since Swift was first released.  I am very 
happy to see it coming to the language.  The design of this feature is even 
better than I had been hoping for!

That said, I do feel like the syntax changes in the revised draft were a step 
backwards on two fronts.  The new syntax is inconsistent with that of the 
syntax used for unbound methods.  IMO all unbound members should be available 
using the same syntax.  Second, the new syntax is (IMO) too cumbersome, 
especially in the shorthand case where a type context is known.  

This feature can be leveraged to build libraries with DSL-like interfaces of 
various kinds.  The more cumbersome syntax significantly reduces the elegance 
of these designs.  This is unfortunate.  As I have mentioned before, I think we 
should consider using the `#` separator to indicate the start of the unbound 
portion of a member chain.  This aligns with the convention of # indicating 
compiler magic and is very lightweight.

While I am not fully satisfied with the current syntax I would not want to see 
that stop the proposal from being accepted.  It is a huge step forward and new 
syntactic sugar could be added in the future without breaking old code.


> Is the problem being addressed significant enough to warrant a change to 
> Swift?
Yes, this is a huge improvement!

> Does this proposal fit well with the feel and direction of Swift?
Very much.

> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
It is better than other languages I have used where unbound property access was 
limited to direct properties, not entire chains or properties and subscripts.

> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
In depth study.  And I am already writing code that will use Smart KeyPaths as 
soon as they are implemented.

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


Re: [swift-evolution] Type-based ‘private’ access within a file

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

> On Apr 3, 2017, at 2:55 PM, Daniel Duan via swift-evolution 
>  wrote:
> 
> I’m concerned that we will have access control changes in a future version 
> yet again, when light-weight modules, or other type of enforced namespace is 
> introduced. Does the core team have any foresight on how this change would 
> interact with such things? I had the same concern for SE-0159 as well. 
> 
> There’s a implicit drawback to all access control changes that 
> migrator/fix-its cannot fix: we organize our code with tools in the language. 
> Some colleague of mine had came up with schemes that combines file scope and 
> Swift 3 `private` to hide details among separate protocol extensions, for 
> example. Code ends up in certain places for a reason and updating access 
> control invalidate those reasons.
> 
> I hesitate to support any changes until we have some ideas for what “ultimate 
> glory” looks like.

+1.  

If we must make a change in Swift 4, the only change I can support for Swift 4 
is renaming the existing access levels.  That would cause some churn but can be 
automated and has no semantic impact.  I feel strongly that the semantics of 
access control should remain the same until submodules and access control can 
be considered together as part of the theme of a larger Swift release.  I 
believe the churn caused by continuing to poke at the semantics of access 
control without addressing the broader issues would be a mistake that would 
cause further frustration in the community.  

As others have already pointed out, code has been developed and organized with 
the new scoped access model in mind.  I think the frustration over a 
semantically neutral, fully automated migration to new names would be pretty 
minimal and certainly much less than the frustration over the suggested 
semantic change.  

Renaming would restore the original intent of SE-0025 which was to leave 
private alone and introduce a new name for scoped access.  One of the big 
reasons that approach was rejected is that we did not have consensus on what to 
call it.  Now that we seem to have reached consensus about what the name should 
be if it is changed it is reasonable to correct the mistake that was made in 
Swift 3.

Finally, I am not at all convinced that type-based private is the right 
semantics.  I think the strictly hierarchical foundation of the existing access 
levels is a much stronger design.  The suggested proposal for a same-file 
type-based approach has already resulted in requests for expanding that model 
to the whole module.  Types and scopes are orthogonal dimensions.  If we want 
to consider a hybrid model for access control I think it is best not to rush.  
We should take our time and consider it properly in the future.

> 
>> On Apr 3, 2017, at 11:34 AM, Douglas Gregor via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hello Swift Community,
>> 
>> In rejecting SE-0159 
>> ,
>>  the core team described a potential direction we would like to investigate 
>> for “private” access control that admits a limited form of type-based access 
>> control within files. The core team is seeking some discussion here and a 
>> motivated volunteer to put together a proposal along these lines for review 
>> in the Swift 4 time-frame (i.e., very soon). To be clear, the core team it’s 
>> sure this is the right direction to go… but it appears promising and we 
>> would *love* to be able to settle the access-control issue.
>> 
>> The design, specifically, is that a “private” member declared within a type 
>> “X” or an extension thereof would be accessible from:
>> 
>>  * An extension of “X” in the same file
>>  * The definition of “X”, if it occurs in the same file
>>  * A nested type (or extension thereof) of one of the above that occurs 
>> in the same file
>> 
>> This design has a number of apparent benefits:
>>  + “private” becomes the right default for “less than whole module” 
>> visibility, and aligns well with Swift coding style that divides a type’s 
>> definition into a number of extensions.
>>  + “fileprivate” remains for existing use cases, but now it’s use it 
>> more rare, which has several advantages:
>>  + It fits well with the "progressive disclosure” philosophy 
>> behind Swift: you can use public/internal/private for a while before 
>> encountering and having to learn about “fileprivate”   (note: we thought 
>> this was going to be true of SE-0025 
>> ,
>>  but we were clearly wrong)
>>  + When “fileprivate” occurs, it means there’s some interesting 
>> coupling between different types in the same file. That makes fileprivate a 
>> useful alert to the reader rather than, potentially, something that we 
>> routinely use and overlook so that we can separate impleme

Re: [swift-evolution] Type-based ‘private’ access within a file

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

> On Apr 3, 2017, at 3:54 PM, Douglas Gregor  wrote:
> 
> 
>> On Apr 3, 2017, at 1:13 PM, Matthew Johnson > > wrote:
>> 
>>> 
>>> On Apr 3, 2017, at 2:55 PM, Daniel Duan via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I’m concerned that we will have access control changes in a future version 
>>> yet again, when light-weight modules, or other type of enforced namespace 
>>> is introduced. Does the core team have any foresight on how this change 
>>> would interact with such things? I had the same concern for SE-0159 as 
>>> well. 
>>> 
>>> There’s a implicit drawback to all access control changes that 
>>> migrator/fix-its cannot fix: we organize our code with tools in the 
>>> language. Some colleague of mine had came up with schemes that combines 
>>> file scope and Swift 3 `private` to hide details among separate protocol 
>>> extensions, for example. Code ends up in certain places for a reason and 
>>> updating access control invalidate those reasons.
>>> 
>>> I hesitate to support any changes until we have some ideas for what 
>>> “ultimate glory” looks like.
>> 
>> +1.  
>> 
>> If we must make a change in Swift 4, the only change I can support for Swift 
>> 4 is renaming the existing access levels.  
> 
> We don’t have to make a change in Swift 4. If there’s a change that can 
> resolve this issue, great…
> 
>> That would cause some churn but can be automated and has no semantic impact. 
>>  I feel strongly that the semantics of access control should remain the same 
>> until submodules and access control can be considered together as part of 
>> the theme of a larger Swift release.  I believe the churn caused by 
>> continuing to poke at the semantics of access control without addressing the 
>> broader issues would be a mistake that would cause further frustration in 
>> the community.  
> 
> … but if not, then let’s shelve access control changes until some time when 
> we can considered it holistically with something like submodules, as you note 
> above.

This is certainly what I would prefer.  I only mention renaming because there 
is such strong interest in changing something.  I would be happy to defer this 
topic and have been arguing for that approach ever since your note that only 
SE-0159 would be considered in scope for Swift 4.

> 
>> As others have already pointed out, code has been developed and organized 
>> with the new scoped access model in mind.  I think the frustration over a 
>> semantically neutral, fully automated migration to new names would be pretty 
>> minimal 
> 
> The core team felt strongly that we couldn’t change these keywords. Source 
> stability is important to Swift 4, and “don’t break source compatibility so 
> much” is one of the top requests we hear from Swift developers, much more so 
> than requests for specific new language features.

That’s fair.

> 
>> and certainly much less than the frustration over the suggested semantic 
>> change.  
> 
> This isn’t clear to me. There could certainly be frustration over the 
> suggested semantic change, for a number of reasons:
> 
> * It’s not as “tight” a meaning of private as the current scope-based private.
> * It means we have a hybrid type-based/scope-based model.
> * It’s the third meaning of ‘private’ in three years.
> 
> However, it is unlikely to break code (one would need to construct an 
> ambiguity between two private declarations in different extensions of the 
> same type in the same file), and causes zero code churn, because it’s 
> widening the meaning of “private”, not changing it.

I’m speculating based on my read of the community here as well as other Swift 
developers I know.  I could be wrong, but my sense is that the items you list 
would cause more frustration than renaming, especially if the name change 
purged `fileprivate`.  I don’t know anyone outside the evolution community who 
I think would complain if access control was left alone for a while.  Some were 
not happy with the changes in Swift 3 but I don’t hear too much about it off 
the list anymore now that the migration is over and people have adapted.

> 
>   - Doug
> 
>> 
>>> 
 On Apr 3, 2017, at 11:34 AM, Douglas Gregor via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 Hello Swift Community,
 
 In rejecting SE-0159 
 ,
  the core team described a potential direction we would like to 
 investigate for “private” access control that admits a limited form of 
 type-based access control within files. The core team is seeking some 
 discussion here and a motivated volunteer to put together a proposal along 
 these lines for review in the Swift 4 time-frame (i.e., very soon). To be 
 clear, the core team it’s sure this is the right direction to go… but it 
 appears promising and we would *love* to be able to set

Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-05 Thread Matthew Johnson via swift-evolution

> On Apr 5, 2017, at 10:30 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> On Apr 5, 2017, at 5:13 AM, Michel Fortin  > wrote:
>> 
>>> Le 5 avr. 2017 à 0:02, Chris Lattner via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>>  - fileprivate should really become much more rare, which makes it more 
>>> meaningful and significant where it occurs.  This was the original idea and 
>>> intent behind SE-0025.
>> 
>> I think this will end up being a flawed assumption, just like last time.
> 
> I’m curious to know why you state this, you seem to agree with it below.
> 
>> Granted: there will be less need for `fileprivate` with this.
> 
> Right, glad to hear that you agree it will become more rare.
> 
>> Files that implement a type will not need `fileprivate` regardless of how 
>> many extensions they use to implement the type. But note that if there is 
>> only one type defined in that file (as is often the case), `private` has 
>> absolutely the same meaning as `fileprivate`.
> 
> Agreed on both points.
> 
>> Files that extend multiple types for the purpose of implementing a 
>> particular feature will still require `fileprivate` if those extensions want 
>> to share some implementation details.
> 
> Right.  That’s the part that makes fileprivate more meaningful.  This was 
> exactly the *purpose* of having fileprivate in the first place.  We want to 
> enable this sort of sharing of private implementation details, but we want to 
> make it explicit at the point of declaration when something like that is 
> going on.

Thanks for jumping in to this thread Chris!  It’s always interesting to hear 
your perspective.

This makes sharing across types within the file more explicit, but it also 
makes state that should be tightly encapsulated less explicit unless you create 
a wrapper type for that state. 

One pattern I have used to good effect is placing this kind of state and the 
basis operations that manipulate it inside the type declaration and placing 
operations defined in terms of the basis operations in extensions on the type 
in the same file.  This pattern no longer works as intended under this 
proposal.  In order to migrate code written this way it is necessary to 
introduce a new type that encapsulates the state and provides the basis 
operations.  This would obviously be a manual migration.  I don’t know how many 
people have adopted styles in Swift 3 that will require manual migration to 
preserve semantics but it is greater than zero.  This is churn that matters and 
shouldn’t be ignored.

I suppose a reasonable argument can be made that requiring encapsulation of 
this kind of state in its own type is a good pattern to that should be 
encouraged.  It certainly calls more attention than the distinction between 
`private` and `fileprivate` by requiring some boilerplate.  The current 
proposal makes sense to me if you assume that this pattern is worth the 
boilerplate because it really stands out.  It means we encourage the “right” 
pattern (again, if you agree this pattern is good) and it means we also call 
special attention to cross-type sharing via `fileprivate` (because as you note 
it will be more rarely used).

On the other hand, if you disagree with the argument that we should have to 
create a new type for this kind of encapsulation then most important question 
becomes whether it is more important to highlight cross-type sharing within the 
file or have the convenience of encapsulating fragile state and highlighting it 
as such without the need to create a new type.  IMO highlighting and tightly 
encapsulating fragile state is a more important concern.

Do we (the community and the core team) want to encourage programmers to create 
new types when this kind of encapsulation is needed rather than requiring on 
lexically scoped access control (that does not cross same-file, same-type 
extension boundaries)?  If yes, then do we think encouraging this and gaining 
the benefit of highlighting same-file, cross-type interactions are big enough 
benefits to offset the “hybrid” (type and scope) access control model and 
another change to the meaning of `private`?

I like the elegance of a purely scope-based access control model and the tight 
encapsulation of lexically scoped access control but I can also see some merit 
in the arguments for this change.  I’m interested in hearing any reactions to 
the lines of reasoning for and against the proposal I have outlined above.

> 
>> 
>>>  - Similarly, this simplifies access control for most people.  Most people 
>>> will now only care about private/internal/public.  fileprivate will become 
>>> an expert feature used in specific cases to solve a specific class of 
>>> problems.  Progressive disclosure of complexity is important.
>> 
>> People who only care about private/internal/public and ignore `fileprivate` 
>> will thus be restricted when it comes to using extensions on multiple types 
>> a

Re: [swift-evolution] [swift-evolution-announce] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-05 Thread Matthew Johnson via swift-evolution

> On Apr 5, 2017, at 6:01 PM, Douglas Gregor  wrote:
> 
> Proposal Link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md
>  
> 
> 
> Hello Swift community,
> 
> The review of SE-0161 “Smart KeyPaths: Better Key-Value Coding for Swift” ran 
> from March 30...April 5, 2017. The proposal was very well-received *except* 
> that reviewers felt that the #keyPath syntax was far too heavy for this new 
> language construct, and preferred the lighter-weight syntax of the pre-review 
> drafts. This proposal is returned for revision to address the syntax.
> 
> The heavyweight #keyPath syntax was requested by the core team after 
> reviewing earlier drafts, which used a far lighter syntax:
> 
>   // (Rejected) syntax from pre-review drafts
>   let firstFriendsNameKeyPath = Person.friends[0].name
>   print(luke[keyPath: .friends[0].name])
> 
> The core team’s specific concern was that these key path expressions (e.g., 
> Person.friends[0].name) don’t make it sufficiently clear that the actual 
> property accesses are being delayed, and that the contextual cues (“Person." 
> vs. “luke.”) are insufficient to disambiguate for the human reader. Hence, 
> the request for a different (more explicit) syntax.
> 
> Reviewers rightly point out that it is natural for key-paths to use the same 
> syntax as unapplied instance method references, e.g., 
> Person.someInstanceMethod produces a value of some function type with the 
> “Self” type curried, e.g., (Person) -> (param-types) -> result-type. The core 
> team agrees with this sentiment. The core team also felt that Swift’s 
> existing unapplied method references suffer from the same clarity problems as 
> the initial key-path syntax, i.e., that it isn’t sufficiently clear that the 
> actual application of “self” is being delayed.
> 
> The core team has a specific proposal: use the backslash (‘\’) to as a 
> leading indicator for key paths. Specifically,
> 
>   // Proposed syntax for second revision
>   let firstFriendsNameKeyPath = \Person.friends[0].name
>   print(luke[keyPath: \.friends[0].name])
> 
> The backslash is a visual cue that the actual application of this chain of 
> property references is delayed, eliminating ambiguities, yet is still quite 
> lightweight and feels “first-class” in the language.
> 
> The core team felt that, in the future, the backslash should also be used for 
> unapplied instance method references, to match the proposed syntax for key 
> paths and improve clarity for this non obvious feature. This change could be 
> staged in as a revision to the accepted-but-never-implemented SE-0042: 
> Flattening the function type of unapplied method references 
> ,
>  e.g.,
> 
>   // Proposed future syntax for unapplied instance method references
> class Person {
> func instanceMethod(_: String) -> Int { … }
>   }
> 
>   let f1 = Person.instanceMethod   // to-be-deprecated; produces a value 
> of type (Person) -> (String) -> Int
>   let f2 = \Person.instanceMethod  // to-be-introduced via a revised 
> SE-0042: produces a value of type (Person, String) -> Int
> 
> Such an approach gives us a way to stage in SE-0042 and get to eventual 
> consistency between key paths and unapplied instance method references.

+1000.  This is excellent news!  I have been looking forward to seeing SE-0042 
implemented.

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

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-05 Thread Matthew Johnson via swift-evolution

> On Apr 5, 2017, at 7:11 PM, Colin Barrett via swift-evolution 
>  wrote:
> 
> I'm broadly in favor of this.
> 
> On Mon, Apr 3, 2017 at 2:35 PM Douglas Gregor via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Hello Swift Community,
> 
> In rejecting SE-0159 
> ,
>  the core team described a potential direction we would like to investigate 
> for “private” access control that admits a limited form of type-based access 
> control within files. The core team is seeking some discussion here and a 
> motivated volunteer to put together a proposal along these lines for review 
> in the Swift 4 time-frame (i.e., very soon). To be clear, the core team it’s 
> sure this is the right direction to go… but it appears promising and we would 
> *love* to be able to settle the access-control issue.
> 
> The design, specifically, is that a “private” member declared within a type 
> “X” or an extension thereof would be accessible from:
> 
>   * An extension of “X” in the same file
>   * The definition of “X”, if it occurs in the same file
>   * A nested type (or extension thereof) of one of the above that occurs 
> in the same file
> 
> This design has a number of apparent benefits:
>   + “private” becomes the right default for “less than whole module” 
> visibility, and aligns well with Swift coding style that divides a type’s 
> definition into a number of extensions.
>   + “fileprivate” remains for existing use cases, but now it’s use it 
> more rare, which has several advantages:
>   + It fits well with the "progressive disclosure” philosophy 
> behind Swift: you can use public/internal/private for a while before 
> encountering and having to learn about “fileprivate”   (note: we thought this 
> was going to be true of SE-0025 
> ,
>  but we were clearly wrong)
>   + When “fileprivate” occurs, it means there’s some interesting 
> coupling between different types in the same file. That makes fileprivate a 
> useful alert to the reader rather than, potentially, something that we 
> routinely use and overlook so that we can separate implementations into 
> extensions.
>   + “private” is more closely aligned with other programming languages 
> that use type-based access control, which can help programmers just coming to 
> Swift. When they reach for “private”, they’re likely to get something similar 
> to what they expect—with a little Swift twist due to Swift’s heavy use of 
> extensions.
>   + Loosening the access restrictions on “private” is unlikely to break 
> existing code.
> 
> There are likely some drawbacks:
>   - Developers using patterns that depend on the existing 
> lexically-scoped access control of “private” may find this new interpretation 
> of “private” to be insufficiently strict
>   - Swift’s access control would go from “entirely lexical” to “partly 
> lexical and partly type-based”, which can be viewed as being more complicated
> 
> I think it might not as complicated as it may first appear. I haven't fully 
> convinced myself of this, but I believe that it would be lexically scoped 
> modulo inlining extensions.
> 
> To put it somewhat more formally (and awkwardly), if one imagines a textual 
> transformation which blindly inlines any extension in a single file into 
> their type definitions (should those definitions occur within that file) then 
> accessing a "private" member in the original file would compile if and only 
> if the access would be lexically scoped if the above postulated 
> transformation were to be applied to it.
> 
> This is a pleasing property (to me anyway) as it means that it is unlikely 
> (impossible?) for moving code from one extension (or definition) to another 
> to cause a compilation failure.
> 
> Take this with a grain of salt of course, as there's probably an edge case 
> I'm not thinking of :P (This is why we write proofs!)

This is a very interesting perspective Colin.  This idea seems to align well 
with the intent for extensions that Chris stated earlier.  This way of thinking 
about it does make the proposal much cleaner conceptually.  If we’re going to 
adopt this perspective I think we should go all the way - same file extensions 
really should be inline semantically.  This means same file extensions would 
also have the ability to include stored properties which is something many 
people have asked for.  

I wonder how David and the core team would feel about modifying the proposal to 
adopt this “inline same file extensions" perspective.  IMO this  motivates the 
proposal better by acknowledging that most developers in the community use same 
file extensions for purely organization purposes.  The implicit desire is that 
they be transparent boundaries that carry no semantic weight at all.  I thi

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-05 Thread Matthew Johnson via swift-evolution

> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>  wrote:
> 
> The rationale for using the same syntax is that a KeyPath is an unapplied 
> property/subscript access. Even the multi-segment part of it isn't 
> necessarily dissimilar: I don't think it would be unreasonable to imagine 
> that \Foo.someMethod.someOtherMethod could work*, that'd just be function 
> composition after all.
> 
> KeyPath : Properties/Subscripts :: Functions with a self argument : Methods
> 
>   David
> 
> *not proposing this, haven't thought carefully about whether there are edge 
> cases I'm missing here, but I think the analogy holds

I alluded to this kind of thing in the earlier threads.  It would be very cool 
to see this explored in the future.

I really like the latest draft and am eagerly anticipating Smart KeyPaths being 
implemented.  Thank you for listening to feedback from the community!

One possible future direction I have been wondering about is whether it might 
be interesting to expose an anonymous type for each distinct key path which 
would have static members for getting (and setting if mutable) the value.  The 
types would inherit from the most specific matching key path type included in 
this proposal.  This would allow us pass key paths statically using the type 
system and therefore not requiring any runtime overhead.  

I have experimented with this approach in some of my own code and it looks like 
it would be a very promising approach aside from the boilerplate required to 
write these types manually.  I have abandoned this approach for now because of 
the boilerplate and because the syntactic sugar of the key path shorthand in 
this proposal is too attractive to pass up.  I would love to explore it again 
in the future if key paths were to support this approach.

Matthew

> 
>> On Apr 5, 2017, at 5:16 PM, Patrick Smith via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I too find the backslash odd, as it’s usually of course used to escape 
>> something.
>> 
>> What about three periods?
>> 
>> let firstFriendsNameKeyPath = Person...friends[0].name
>> print(luke[keyPath: ...friends[0].name])
>> 
>> 
>> I also find wanting to use the same syntax for unapplied methods strange, as 
>> they would product two totally different things: one a key path value, the 
>> other a function.
>> 
>> Patrick
>> On Thu, 6 Apr 2017 at 10:00 am, Douglas Gregor via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> On Apr 5, 2017, at 4:55 PM, Colin Barrett >> > wrote:
>>> 
>>> Is the choice of backslash up for review? I think another operator,
>> 
>> We talked through basically everything on the keyboard, and there really 
>> aren’t other options that don’t stomp on existing behavior.
>> 
>>> perhaps backtick (`), would work better.
>> 
>> Backtick (`) is already taken for escaping identifiers, e.g., 
>> 
>>  var `func` = { /* some code */ }
>> 
>>  - 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
> 
> ___
> 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] [swift-evolution-announce] [Review #2] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-05 Thread Matthew Johnson via swift-evolution
> 
> What is your evaluation of the proposal?
This proposal is excellent. A big thanks goes out to everyone who worked on it!

The \ sigil may not make for the prettiest syntax but our options are very 
limited and it is a vast improvement over the previous draft.  If the core team 
likes the :: suggestion others have made I would be also be fine with that if 
we could elide the leading `.` in the shorthand version but would prefer not to 
have to write `::.`.  Overall, the choice of sigil is relatively unimportant to 
me.  The important thing IMO is that it is concise and will work great in DSLs.

> Is the problem being addressed significant enough to warrant a change to 
> Swift?
Yes.  The lack of unbound property references is a big hole in the language.

> Does this proposal fit well with the feel and direction of Swift?
Absolutely.  

> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
I have used lenses a bit in my own code.  Key paths are a really awesome way to 
build them right into the language with syntactic support that is not possible 
for libraries.

> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
In depth study.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Compound name `foo(:)` for nullary functions

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 7:02 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Given that \foo(bar:baz:) will work, and that \foo() will be unambiguously 
> distinguished from foo(), I think that would be the only logical result.

Agree.  It seem like this would fit nicely into the revision of SE-0042 that 
Doug mentioned.

> 
> 
> On Thu, Apr 6, 2017 at 00:40 Jacob Bandes-Storch via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Now that escaping with \ has been proposed for KeyPaths, this makes me wonder 
> whether it would be appropriate to use "\foo()" rather than "foo(_)"/"foo(:)" 
> ?  It still feels a bit strange, as \foo() looks like escaping the result of 
> a call.
> 
> 
> On Sat, Feb 25, 2017 at 1:43 PM, David Hart  > wrote:
> 
>> On 25 Feb 2017, at 00:56, Jordan Rose via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I don't have a good answer for this, but I'll vote against 'foo(:)' because 
>> that's what a lot of people think the name of 'foo(_:)' should be. I'd 
>> rather be able to offer fix-its for that even when you have both 'foo()' and 
>> 'foo(_:)' defined. I'd rather go with 'foo(_)' despite the tiny ambiguity in 
>> pattern contexts.
>> 
>> (I'm personally in favor of killing unapplied function references altogether 
>> in favor of closures, on the grounds that they are overly terse, make 
>> type-checking more complicated, and often lead to retain cycles. Then we'd 
>> only need this for #selector, and it's perfectly unambiguous to use 'foo()' 
>> there. But I wasn't planning to fight that particular battle now, and it is 
>> rather annoying to require the 'as' in the meantime.)
> 
> It is potentially going to be hard to fight that battle. I think a lot of 
> functional/Haskell people love them and would be sad to see them go away (I 
> plead guilty). But it isn’t a well known part of the language so I don’t 
> think the general community would miss it.
> 
>> Jordan
>> 
>> 
>>> On Feb 21, 2017, at 23:05, Jacob Bandes-Storch >> > wrote:
>>> 
>>> Evolutioniers,
>>> 
>>> Compound name syntax — foo(_:), foo(bar:), foo(bar:baz:) — is used to 
>>> disambiguate references to functions. (You might've used it inside a 
>>> #selector expression.) But there's currently no compound name for a 
>>> function with no arguments.
>>> 
>>> func foo() {}  // no compound syntax for this one :(
>>> func foo(_ bar: Int) {}  // foo(_:)
>>> func foo(bar: Int) {}  // foo(bar:)
>>> func foo(bar: String, baz: Double) {}  // foo(bar:baz:)
>>> 
>>> Given these four functions, only the first one has no compound name syntax. 
>>> And the simple reference "let myfn = foo" is ambiguous because it could 
>>> refer to any of the four. A workaround is to specify a contextual type, 
>>> e.g. "let myfn = foo as () -> Void".
>>> 
>>> I filed SR-3550  for this a while 
>>> ago, and there was some discussion in JIRA about it. I'd like to continue 
>>> exploring solutions here and then write up a formal proposal.
>>> 
>>> To kick off the discussion, I'd like to propose foo(:) for nullary 
>>> functions.
>>> 
>>> Advantages:
>>> - the colon marks a clear similarity to the foo(bar:) form when argument 
>>> labels are present.
>>> - cutely parallels the empty dictionary literal, [:].
>>> 
>>> Disadvantages:
>>> - violates intuition about one-colon-per-argument.
>>> - the parallel between #selector(foo(:)) and @selector(foo) is not quite as 
>>> obvious as between #selector(foo(_:)) and @selector(foo:).
>>> 
>>> 
>>> For the sake of discussion, another option would be foo(_). This was my 
>>> original choice, and I like that the number of colons matches the number of 
>>> parameters. However, it's a little less obvious as a function reference. It 
>>> would preclude _ from acting as an actual identifier, and might conflict 
>>> with pattern-matching syntax (although it appears functions can't be 
>>> compared with ~= anyway).
>>> 
>>> 
>>> Looking forward to everyone's bikeshed color ideas,
>>> Jacob
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 12:32 PM, John McCall  wrote:
> 
>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> The rationale for using the same syntax is that a KeyPath is an unapplied 
>>> property/subscript access. Even the multi-segment part of it isn't 
>>> necessarily dissimilar: I don't think it would be unreasonable to imagine 
>>> that \Foo.someMethod.someOtherMethod could work*, that'd just be function 
>>> composition after all.
>>> 
>>> KeyPath : Properties/Subscripts :: Functions with a self argument : Methods
>>> 
>>> David
>>> 
>>> *not proposing this, haven't thought carefully about whether there are edge 
>>> cases I'm missing here, but I think the analogy holds
>> 
>> I alluded to this kind of thing in the earlier threads.  It would be very 
>> cool to see this explored in the future.
>> 
>> I really like the latest draft and am eagerly anticipating Smart KeyPaths 
>> being implemented.  Thank you for listening to feedback from the community!
>> 
>> One possible future direction I have been wondering about is whether it 
>> might be interesting to expose an anonymous type for each distinct key path 
>> which would have static members for getting (and setting if mutable) the 
>> value.  The types would inherit from the most specific matching key path 
>> type included in this proposal.  This would allow us pass key paths 
>> statically using the type system and therefore not requiring any runtime 
>> overhead.  
>> 
>> I have experimented with this approach in some of my own code and it looks 
>> like it would be a very promising approach aside from the boilerplate 
>> required to write these types manually.  I have abandoned this approach for 
>> now because of the boilerplate and because the syntactic sugar of the key 
>> path shorthand in this proposal is too attractive to pass up.  I would love 
>> to explore it again in the future if key paths were to support this approach.
> 
> Our generics system does not require generic code to be de-genericized 
> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in order 
> to be run.  The generic code for applying a value of an unknown key-path type 
> would look exactly like the non-generic code for applying a dynamic key-path 
> type.  To get a runtime benefit, the compiler would have to de-genericize all 
> the code between the function that formed the concrete key path and the 
> function that applied it.  If the compiler can do that, it can also 
> specialize that code for a known key path argument, the same way that it can 
> specialize a function for a known function argument.  So there's no point.

Thanks for the reply John.  There may not be any additional optimization 
opportunities in terms of code generation when using the key path but wouldn’t 
it save on storage and reference counting related to key path value?

As a secondary question, wouldn’t this be similar to the difference between 
generics and existentials?  In theory the same optimizations could be applied 
but in practice they are not always right now.  Is the plan to eventually put 
existentials on equal footing in terms of optimization?

> 
> John.
> 
>> 
>> Matthew
>> 
>>> 
>>>> On Apr 5, 2017, at 5:16 PM, Patrick Smith via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> I too find the backslash odd, as it’s usually of course used to escape 
>>>> something.
>>>> 
>>>> What about three periods?
>>>> 
>>>> let firstFriendsNameKeyPath = Person...friends[0].name
>>>> print(luke[keyPath: ...friends[0].name])
>>>> 
>>>> 
>>>> I also find wanting to use the same syntax for unapplied methods strange, 
>>>> as they would product two totally different things: one a key path value, 
>>>> the other a function.
>>>> 
>>>> Patrick
>>>> On Thu, 6 Apr 2017 at 10:00 am, Douglas Gregor via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> On Apr 5, 2017, at 4:55 PM, Colin Barrett >>>> <mailto:co...@springsandstruts.com>> wrote:
>>>>> 
>>>>> Is the choice of backslash up for review? I think another operator, 
>>>> 
>>>&g

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 1:06 PM, John McCall  wrote:
> 
>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson > <mailto:matt...@anandabits.com>> wrote:
>>> On Apr 6, 2017, at 12:32 PM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> The rationale for using the same syntax is that a KeyPath is an unapplied 
>>>>> property/subscript access. Even the multi-segment part of it isn't 
>>>>> necessarily dissimilar: I don't think it would be unreasonable to imagine 
>>>>> that \Foo.someMethod.someOtherMethod could work*, that'd just be function 
>>>>> composition after all.
>>>>> 
>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>> Methods
>>>>> 
>>>>>   David
>>>>> 
>>>>> *not proposing this, haven't thought carefully about whether there are 
>>>>> edge cases I'm missing here, but I think the analogy holds
>>>> 
>>>> I alluded to this kind of thing in the earlier threads.  It would be very 
>>>> cool to see this explored in the future.
>>>> 
>>>> I really like the latest draft and am eagerly anticipating Smart KeyPaths 
>>>> being implemented.  Thank you for listening to feedback from the community!
>>>> 
>>>> One possible future direction I have been wondering about is whether it 
>>>> might be interesting to expose an anonymous type for each distinct key 
>>>> path which would have static members for getting (and setting if mutable) 
>>>> the value.  The types would inherit from the most specific matching key 
>>>> path type included in this proposal.  This would allow us pass key paths 
>>>> statically using the type system and therefore not requiring any runtime 
>>>> overhead.  
>>>> 
>>>> I have experimented with this approach in some of my own code and it looks 
>>>> like it would be a very promising approach aside from the boilerplate 
>>>> required to write these types manually.  I have abandoned this approach 
>>>> for now because of the boilerplate and because the syntactic sugar of the 
>>>> key path shorthand in this proposal is too attractive to pass up.  I would 
>>>> love to explore it again in the future if key paths were to support this 
>>>> approach.
>>> 
>>> Our generics system does not require generic code to be de-genericized 
>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in order 
>>> to be run.  The generic code for applying a value of an unknown key-path 
>>> type would look exactly like the non-generic code for applying a dynamic 
>>> key-path type.  To get a runtime benefit, the compiler would have to 
>>> de-genericize all the code between the function that formed the concrete 
>>> key path and the function that applied it.  If the compiler can do that, it 
>>> can also specialize that code for a known key path argument, the same way 
>>> that it can specialize a function for a known function argument.  So 
>>> there's no point.
>> 
>> Thanks for the reply John.  There may not be any additional optimization 
>> opportunities in terms of code generation when using the key path but 
>> wouldn’t it save on storage and reference counting related to key path value?
> 
> If you're specializing all the way down, any sort of boxing should be 
> possible to eliminate as well.
> 
> If you mean in unspecialized code, well, I'm not entirely sure what 
> representation Joe is using, but I would assume that the fast path — where a 
> key path doesn't capture anything — does not require any allocation.  In that 
> sense, there's a strong parallel with how we represent functions: yes, 
> avoiding an extra allocation would be nice, but if you're willing to accept 
> an occasional allocation in more complex cases, there are also a lot of 
> benefits from being able to always give the type a concrete, fixed-size 
> representation.

Key paths in this proposal are classes which require storage of the pointer as 
well as reference counting unless there is special of key path values.  Is 

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 1:21 PM, John McCall  wrote:
> 
>> On Apr 6, 2017, at 2:12 PM, Matthew Johnson > <mailto:matt...@anandabits.com>> wrote:
>>> On Apr 6, 2017, at 1:06 PM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>> wrote:
>>>>> On Apr 6, 2017, at 12:32 PM, John McCall >>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>> 
>>>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> The rationale for using the same syntax is that a KeyPath is an 
>>>>>>> unapplied property/subscript access. Even the multi-segment part of it 
>>>>>>> isn't necessarily dissimilar: I don't think it would be unreasonable to 
>>>>>>> imagine that \Foo.someMethod.someOtherMethod could work*, that'd just 
>>>>>>> be function composition after all.
>>>>>>> 
>>>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>>>> Methods
>>>>>>> 
>>>>>>> David
>>>>>>> 
>>>>>>> *not proposing this, haven't thought carefully about whether there are 
>>>>>>> edge cases I'm missing here, but I think the analogy holds
>>>>>> 
>>>>>> I alluded to this kind of thing in the earlier threads.  It would be 
>>>>>> very cool to see this explored in the future.
>>>>>> 
>>>>>> I really like the latest draft and am eagerly anticipating Smart 
>>>>>> KeyPaths being implemented.  Thank you for listening to feedback from 
>>>>>> the community!
>>>>>> 
>>>>>> One possible future direction I have been wondering about is whether it 
>>>>>> might be interesting to expose an anonymous type for each distinct key 
>>>>>> path which would have static members for getting (and setting if 
>>>>>> mutable) the value.  The types would inherit from the most specific 
>>>>>> matching key path type included in this proposal.  This would allow us 
>>>>>> pass key paths statically using the type system and therefore not 
>>>>>> requiring any runtime overhead.  
>>>>>> 
>>>>>> I have experimented with this approach in some of my own code and it 
>>>>>> looks like it would be a very promising approach aside from the 
>>>>>> boilerplate required to write these types manually.  I have abandoned 
>>>>>> this approach for now because of the boilerplate and because the 
>>>>>> syntactic sugar of the key path shorthand in this proposal is too 
>>>>>> attractive to pass up.  I would love to explore it again in the future 
>>>>>> if key paths were to support this approach.
>>>>> 
>>>>> Our generics system does not require generic code to be de-genericized 
>>>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in 
>>>>> order to be run.  The generic code for applying a value of an unknown 
>>>>> key-path type would look exactly like the non-generic code for applying a 
>>>>> dynamic key-path type.  To get a runtime benefit, the compiler would have 
>>>>> to de-genericize all the code between the function that formed the 
>>>>> concrete key path and the function that applied it.  If the compiler can 
>>>>> do that, it can also specialize that code for a known key path argument, 
>>>>> the same way that it can specialize a function for a known function 
>>>>> argument.  So there's no point.
>>>> 
>>>> Thanks for the reply John.  There may not be any additional optimization 
>>>> opportunities in terms of code generation when using the key path but 
>>>> wouldn’t it save on storage and reference counting related to key path 
>>>> value?
>>> 
>>> If you're specializing all the way down, any sort of boxing should be 
>>> possible to eli

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 2:54 PM, John McCall  wrote:
> 
>> 
>> On Apr 6, 2017, at 3:05 PM, Matthew Johnson > <mailto:matt...@anandabits.com>> wrote:
>> 
>> 
>>> On Apr 6, 2017, at 1:21 PM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>> On Apr 6, 2017, at 2:12 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>> wrote:
>>>>> On Apr 6, 2017, at 1:06 PM, John McCall >>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>> 
>>>>>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson >>>>> <mailto:matt...@anandabits.com>> wrote:
>>>>>>> On Apr 6, 2017, at 12:32 PM, John McCall >>>>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>>>> 
>>>>>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>>> 
>>>>>>>>> The rationale for using the same syntax is that a KeyPath is an 
>>>>>>>>> unapplied property/subscript access. Even the multi-segment part of 
>>>>>>>>> it isn't necessarily dissimilar: I don't think it would be 
>>>>>>>>> unreasonable to imagine that \Foo.someMethod.someOtherMethod could 
>>>>>>>>> work*, that'd just be function composition after all.
>>>>>>>>> 
>>>>>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>>>>>> Methods
>>>>>>>>> 
>>>>>>>>>   David
>>>>>>>>> 
>>>>>>>>> *not proposing this, haven't thought carefully about whether there 
>>>>>>>>> are edge cases I'm missing here, but I think the analogy holds
>>>>>>>> 
>>>>>>>> I alluded to this kind of thing in the earlier threads.  It would be 
>>>>>>>> very cool to see this explored in the future.
>>>>>>>> 
>>>>>>>> I really like the latest draft and am eagerly anticipating Smart 
>>>>>>>> KeyPaths being implemented.  Thank you for listening to feedback from 
>>>>>>>> the community!
>>>>>>>> 
>>>>>>>> One possible future direction I have been wondering about is whether 
>>>>>>>> it might be interesting to expose an anonymous type for each distinct 
>>>>>>>> key path which would have static members for getting (and setting if 
>>>>>>>> mutable) the value.  The types would inherit from the most specific 
>>>>>>>> matching key path type included in this proposal.  This would allow us 
>>>>>>>> pass key paths statically using the type system and therefore not 
>>>>>>>> requiring any runtime overhead.  
>>>>>>>> 
>>>>>>>> I have experimented with this approach in some of my own code and it 
>>>>>>>> looks like it would be a very promising approach aside from the 
>>>>>>>> boilerplate required to write these types manually.  I have abandoned 
>>>>>>>> this approach for now because of the boilerplate and because the 
>>>>>>>> syntactic sugar of the key path shorthand in this proposal is too 
>>>>>>>> attractive to pass up.  I would love to explore it again in the future 
>>>>>>>> if key paths were to support this approach.
>>>>>>> 
>>>>>>> Our generics system does not require generic code to be de-genericized 
>>>>>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in 
>>>>>>> order to be run.  The generic code for applying a value of an unknown 
>>>>>>> key-path type would look exactly like the non-generic code for applying 
>>>>>>> a dynamic key-path type.  To get a runtime benefit, the compiler would 
>>>>>>> have to de-genericize all the code between the function that formed the 
>>>>>>> concrete key path and the func

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 1:11 PM, Joe Groff  wrote:
> 
> 
>> On Apr 6, 2017, at 11:06 AM, John McCall  wrote:
>> 
>>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson  wrote:
>>>> On Apr 6, 2017, at 12:32 PM, John McCall  wrote:
>>>> 
>>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>>>  wrote:
>>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>>>  wrote:
>>>>>> 
>>>>>> The rationale for using the same syntax is that a KeyPath is an 
>>>>>> unapplied property/subscript access. Even the multi-segment part of it 
>>>>>> isn't necessarily dissimilar: I don't think it would be unreasonable to 
>>>>>> imagine that \Foo.someMethod.someOtherMethod could work*, that'd just be 
>>>>>> function composition after all.
>>>>>> 
>>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>>> Methods
>>>>>> 
>>>>>>  David
>>>>>> 
>>>>>> *not proposing this, haven't thought carefully about whether there are 
>>>>>> edge cases I'm missing here, but I think the analogy holds
>>>>> 
>>>>> I alluded to this kind of thing in the earlier threads.  It would be very 
>>>>> cool to see this explored in the future.
>>>>> 
>>>>> I really like the latest draft and am eagerly anticipating Smart KeyPaths 
>>>>> being implemented.  Thank you for listening to feedback from the 
>>>>> community!
>>>>> 
>>>>> One possible future direction I have been wondering about is whether it 
>>>>> might be interesting to expose an anonymous type for each distinct key 
>>>>> path which would have static members for getting (and setting if mutable) 
>>>>> the value.  The types would inherit from the most specific matching key 
>>>>> path type included in this proposal.  This would allow us pass key paths 
>>>>> statically using the type system and therefore not requiring any runtime 
>>>>> overhead.  
>>>>> 
>>>>> I have experimented with this approach in some of my own code and it 
>>>>> looks like it would be a very promising approach aside from the 
>>>>> boilerplate required to write these types manually.  I have abandoned 
>>>>> this approach for now because of the boilerplate and because the 
>>>>> syntactic sugar of the key path shorthand in this proposal is too 
>>>>> attractive to pass up.  I would love to explore it again in the future if 
>>>>> key paths were to support this approach.
>>>> 
>>>> Our generics system does not require generic code to be de-genericized 
>>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in 
>>>> order to be run.  The generic code for applying a value of an unknown 
>>>> key-path type would look exactly like the non-generic code for applying a 
>>>> dynamic key-path type.  To get a runtime benefit, the compiler would have 
>>>> to de-genericize all the code between the function that formed the 
>>>> concrete key path and the function that applied it.  If the compiler can 
>>>> do that, it can also specialize that code for a known key path argument, 
>>>> the same way that it can specialize a function for a known function 
>>>> argument.  So there's no point.
>>> 
>>> Thanks for the reply John.  There may not be any additional optimization 
>>> opportunities in terms of code generation when using the key path but 
>>> wouldn’t it save on storage and reference counting related to key path 
>>> value?
>> 
>> If you're specializing all the way down, any sort of boxing should be 
>> possible to eliminate as well.
>> 
>> If you mean in unspecialized code, well, I'm not entirely sure what 
>> representation Joe is using, but I would assume that the fast path — where a 
>> key path doesn't capture anything — does not require any allocation.  In 
>> that sense, there's a strong parallel with how we represent functions: yes, 
>> avoiding an extra allocation would be nice, but if you're willing to accept 
>> an occasional allocation in more complex cases, there are also a lot of 
>> benefits from being able to always give the t

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 4:22 PM, Joe Groff  wrote:
> 
>> 
>> On Apr 6, 2017, at 2:15 PM, Matthew Johnson  wrote:
>> 
>> 
>>> On Apr 6, 2017, at 1:11 PM, Joe Groff  wrote:
>>> 
>>> 
>>>> On Apr 6, 2017, at 11:06 AM, John McCall  wrote:
>>>> 
>>>>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson  
>>>>> wrote:
>>>>>> On Apr 6, 2017, at 12:32 PM, John McCall  wrote:
>>>>>> 
>>>>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>>>>>  wrote:
>>>>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>>>>>  wrote:
>>>>>>>> 
>>>>>>>> The rationale for using the same syntax is that a KeyPath is an 
>>>>>>>> unapplied property/subscript access. Even the multi-segment part of it 
>>>>>>>> isn't necessarily dissimilar: I don't think it would be unreasonable 
>>>>>>>> to imagine that \Foo.someMethod.someOtherMethod could work*, that'd 
>>>>>>>> just be function composition after all.
>>>>>>>> 
>>>>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>>>>> Methods
>>>>>>>> 
>>>>>>>>David
>>>>>>>> 
>>>>>>>> *not proposing this, haven't thought carefully about whether there are 
>>>>>>>> edge cases I'm missing here, but I think the analogy holds
>>>>>>> 
>>>>>>> I alluded to this kind of thing in the earlier threads.  It would be 
>>>>>>> very cool to see this explored in the future.
>>>>>>> 
>>>>>>> I really like the latest draft and am eagerly anticipating Smart 
>>>>>>> KeyPaths being implemented.  Thank you for listening to feedback from 
>>>>>>> the community!
>>>>>>> 
>>>>>>> One possible future direction I have been wondering about is whether it 
>>>>>>> might be interesting to expose an anonymous type for each distinct key 
>>>>>>> path which would have static members for getting (and setting if 
>>>>>>> mutable) the value.  The types would inherit from the most specific 
>>>>>>> matching key path type included in this proposal.  This would allow us 
>>>>>>> pass key paths statically using the type system and therefore not 
>>>>>>> requiring any runtime overhead.  
>>>>>>> 
>>>>>>> I have experimented with this approach in some of my own code and it 
>>>>>>> looks like it would be a very promising approach aside from the 
>>>>>>> boilerplate required to write these types manually.  I have abandoned 
>>>>>>> this approach for now because of the boilerplate and because the 
>>>>>>> syntactic sugar of the key path shorthand in this proposal is too 
>>>>>>> attractive to pass up.  I would love to explore it again in the future 
>>>>>>> if key paths were to support this approach.
>>>>>> 
>>>>>> Our generics system does not require generic code to be de-genericized 
>>>>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in 
>>>>>> order to be run.  The generic code for applying a value of an unknown 
>>>>>> key-path type would look exactly like the non-generic code for applying 
>>>>>> a dynamic key-path type.  To get a runtime benefit, the compiler would 
>>>>>> have to de-genericize all the code between the function that formed the 
>>>>>> concrete key path and the function that applied it.  If the compiler can 
>>>>>> do that, it can also specialize that code for a known key path argument, 
>>>>>> the same way that it can specialize a function for a known function 
>>>>>> argument.  So there's no point.
>>>>> 
>>>>> Thanks for the reply John.  There may not be any additional optimization 
>>>>> opportunities in terms of code generation when using the key path but 
>>>>> wouldn’t it save on storage and reference counting related to key path 
>>>>> value?
>>>> 
>>&g

Re: [swift-evolution] [Returned for revision] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-06 Thread Matthew Johnson via swift-evolution

> On Apr 6, 2017, at 4:39 PM, Joe Groff  wrote:
> 
>> 
>> On Apr 6, 2017, at 2:35 PM, Matthew Johnson  wrote:
>> 
>>> 
>>> On Apr 6, 2017, at 4:22 PM, Joe Groff  wrote:
>>> 
>>>> 
>>>> On Apr 6, 2017, at 2:15 PM, Matthew Johnson  wrote:
>>>> 
>>>> 
>>>>> On Apr 6, 2017, at 1:11 PM, Joe Groff  wrote:
>>>>> 
>>>>> 
>>>>>> On Apr 6, 2017, at 11:06 AM, John McCall  wrote:
>>>>>> 
>>>>>>> On Apr 6, 2017, at 1:41 PM, Matthew Johnson  
>>>>>>> wrote:
>>>>>>>> On Apr 6, 2017, at 12:32 PM, John McCall  wrote:
>>>>>>>> 
>>>>>>>>> On Apr 5, 2017, at 9:46 PM, Matthew Johnson via swift-evolution 
>>>>>>>>>  wrote:
>>>>>>>>>> On Apr 5, 2017, at 7:32 PM, David Smith via swift-evolution 
>>>>>>>>>>  wrote:
>>>>>>>>>> 
>>>>>>>>>> The rationale for using the same syntax is that a KeyPath is an 
>>>>>>>>>> unapplied property/subscript access. Even the multi-segment part of 
>>>>>>>>>> it isn't necessarily dissimilar: I don't think it would be 
>>>>>>>>>> unreasonable to imagine that \Foo.someMethod.someOtherMethod could 
>>>>>>>>>> work*, that'd just be function composition after all.
>>>>>>>>>> 
>>>>>>>>>> KeyPath : Properties/Subscripts :: Functions with a self argument : 
>>>>>>>>>> Methods
>>>>>>>>>> 
>>>>>>>>>>  David
>>>>>>>>>> 
>>>>>>>>>> *not proposing this, haven't thought carefully about whether there 
>>>>>>>>>> are edge cases I'm missing here, but I think the analogy holds
>>>>>>>>> 
>>>>>>>>> I alluded to this kind of thing in the earlier threads.  It would be 
>>>>>>>>> very cool to see this explored in the future.
>>>>>>>>> 
>>>>>>>>> I really like the latest draft and am eagerly anticipating Smart 
>>>>>>>>> KeyPaths being implemented.  Thank you for listening to feedback from 
>>>>>>>>> the community!
>>>>>>>>> 
>>>>>>>>> One possible future direction I have been wondering about is whether 
>>>>>>>>> it might be interesting to expose an anonymous type for each distinct 
>>>>>>>>> key path which would have static members for getting (and setting if 
>>>>>>>>> mutable) the value.  The types would inherit from the most specific 
>>>>>>>>> matching key path type included in this proposal. This would allow us 
>>>>>>>>> pass key paths statically using the type system and therefore not 
>>>>>>>>> requiring any runtime overhead.  
>>>>>>>>> 
>>>>>>>>> I have experimented with this approach in some of my own code and it 
>>>>>>>>> looks like it would be a very promising approach aside from the 
>>>>>>>>> boilerplate required to write these types manually.  I have abandoned 
>>>>>>>>> this approach for now because of the boilerplate and because the 
>>>>>>>>> syntactic sugar of the key path shorthand in this proposal is too 
>>>>>>>>> attractive to pass up.  I would love to explore it again in the 
>>>>>>>>> future if key paths were to support this approach.
>>>>>>>> 
>>>>>>>> Our generics system does not require generic code to be de-genericized 
>>>>>>>> ("instantiated" in C++ terminology, "monomorphized" in Rust, etc.) in 
>>>>>>>> order to be run. The generic code for applying a value of an unknown 
>>>>>>>> key-path type would look exactly like the non-generic code for 
>>>>>>>> applying a dynamic key-path type.  To get a runtime benefit, the 
>>>>>>>> compiler would have to de-genericize all the code between the function 
>>>>>>>> that formed the concrete key path and 

Re: [swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

2017-04-07 Thread Matthew Johnson via swift-evolution
> 
> What is your evaluation of the proposal?
-1.  I have been a vocal proponent of scoped access all along.  Despite that I 
really tried to keep an open mind about this proposal.  In the end, I just 
don’t think it is the right decision.

I can see why some people would like to consider a main type declaration and 
extensions to be considered the same scope when they are in the same file.  
Extensions of a type within a file are usually used primarily for 
organizational purposes.  The intent often isn’t really to create a scope 
boundary.  Needing to use the slightly verbose `fileprivate` is unfortunate.  
But the keyword isn’t a scoping problem, it is a naming problem.

I think the most compelling argument in the proposal is the one that says it is 
important to highlight same-file, cross-type communication using the 
`fileprivate` keyword.  The argument is that by making this the only case where 
`fileprivate` is used will make these special cross-type members stand out 
more.  I considered this carefully and ultimately concluded that I just don’t 
think it’s that important.  

The reason I put scopes for more than one type in the same file to begin with 
is that privileged access of one kind or another is necessary.  For this 
reason, I think if we’re going to have a “soft default” that works in the vast 
majority of cases it should be file scope.  It would be nice if file scope 
could regain the name `private` without losing the scoped access feature but if 
we just can’t make that happen maybe we’ll just have to live without the “soft 
default”.

It isn’t cross-type members that I want to stand out.  It is same-scope-only 
members that need to stand out.  These members are scoped for important reasons 
and it is valuable to tightly bound code that can access them and avoid needing 
to look elsewhere in the same file for accesses.  Brent made an eloquent case 
for this despite having supported the rollback to Swift 2 access levels.

In the end, I still think the name `fileprivate` was a mistake and that the 
best design is Swift 2 `private` with `scoped` as the name for the Swift 3 
`private`.  If we’re not going to fix that we should just leave access control 
alone in Swift 4.  

When we’re ready to discuss submodules as part of a release theme I hope we 
will also be willing to revise access control as a part of that them if that 
makes sense in the context of whatever submodules end up looking like.  At this 
time we would not only have more context regarding submodules, we would also 
have the benefit of more time and experience with the current access levels 
which may be helpful in informing our decision.

In recent threads on this topic there has been some discussion of introducing 
some kind of organizational mechanism that can be used within the scope of a 
type declaration.  I think this is an interesting approach and is the right 
approach to explore if we want to have a way to organize a type’s declaration 
without creating scope boundaries.  It would allow people to organize their 
members while still using `private` more often and better highlighting members 
that are visible file-wide.  

In Objective-C MARK comments were very commonly used for this purpose.  In 
Swift this is still possible but has been mostly replaced with extensions.  
People want to use an organizational mechanism that is supported by the 
language.  Maybe we need some kind of organizational mechanism that does not 
create a scope boundary.  This is a topic for another discussion, but is worth 
keeping in mind while considering the merit of the current proposal.

> Is the problem being addressed significant enough to warrant a change to 
> Swift?
No.  I believe it makes the language worse, not better.  It doesn’t address the 
real problems with access control.  The largest problem is the inability to 
form scopes between files and the entire module.  The problem with 
`fileprivate` and `private` is a naming problem, not a semantics problem.

I also believe the proposal does not adequately acknowledge the impact on 
existing code.  While most code will still compile the semantics will be 
significantly different for people who are using scoped access as it was 
intended - to closely bound access to members when there are good reasons for 
doing that.  In order to maintain semantic compatibility this code will need to 
be re-written to introduce a new type if there remains a desire to highlight 
access to these members.  Even then, it will be possible to extend that type 
elsewhere in the file to open a new scope which can access the members.  

We no longer have a tight bound, only a way to make it more verbose and obvious 
when the scope is opened elsewhere in the file.  This is a significant, not a 
small impact on this code.  The core team rejected SE-0159 because it 
determined people are using scoped access control for good reasons.  I don’t 
understand how we could go from that decision to making a change th

Re: [swift-evolution] [Pitch] Remove type-inference for stored property

2017-04-07 Thread Matthew Johnson via swift-evolution

> On Apr 7, 2017, at 2:21 AM, Daniel Duan via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> In a discussion about inferring parameter types from default value, Slava 
> brought up some performance problems caused by type inference for stored 
> properties in side types:
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033882.html
> 
> Towards the end, the post mentioned that some Swift team members contemplated 
> requiring types for stored properties in type declarations. I think this idea 
> deserves some more attention. Hence this last minute idea-floating.
> 
> In addition to solving a performance headache in implementation, there're 
> always the general benefit of making type declartion more explicit and 
> readable (clarity for reader should out-weigh pleasure of the author). Making 
> the
> language slightly more consistent (we are not inferring types for default 
> parameter values in function anyways).
> 
> The cons for doing this are obvious too: the inference makes the language 
> feels more friendly and is, undoubtedly, a beloved feature for many. This 
> would be a source breaking change.
> 
> Just thought I'd float the idea to gather some quick reaction. What do y'all 
> think?

I’m willing to keep an open mind on this topic but I don’t think wholesale 
banning of inference is the right thing to do.  Here is an example of a case 
where I do not want to give up inference.  When a property is initialized 
inline by calling an initializer of a non-generic type (very common) any 
annotation is strictly redundant.

struct {
let foo = Foo()
}

Requiring a type annotation here feels very unnecessary and boilerplate-y.  I 
adds no additional clarity to a reader of the code, only noise.  Noise reduces 
clarity.  Small amounts of unnecessary or redundant information such as in an 
individual stored property declaration are not that big a deal.  But on balance 
they add up quickly and have an undesirable impact on the overall clarity of 
code.  

> 
> Daniel Duan
> ___
> 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] Type-based ‘private’ access within a file

2017-04-07 Thread Matthew Johnson via swift-evolution

> On Apr 7, 2017, at 9:48 AM, David Hart via swift-evolution 
>  wrote:
> 
>> 
>> On 7 Apr 2017, at 15:41, BJ Homer via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> -0.5
>> 
>> SE-0159 was rejected because it was determined that some developers are 
>> actively using strongly-scoped access control. This proposal removes that 
>> strong scoping, so I do not see how we can reasonably reject that proposal 
>> but accept this one.
> 
> I don’t know what you mean by strong in strong-scoped access, but your 
> statement seems false. It does not remove the scoped access control, it only 
> relaxes it in extensions to types in the same file.

This relaxation makes the resulting scoping decidedly less strong.  It is no 
longer lexical and would require a user to consider all code in the file.  This 
means the strong, compiler-verified guarantee of scoped access that a small 
number of lines can see a member is eliminated.  The whole file must be 
considered.  As others have noted, that defeats the primary purpose of having 
scoped access control in the first place.

> 
>> The entire reason we're having this discussion is that "fileprivate" is such 
>> an awkward term for something that's so common in the language. I think the 
>> main thing we need to fix is the naming of that keyword.
> 
> The name of fileprivate is not reason for this proposal. fileprivate has an 
> awkward name precisely because it was planned for it to be used less often. 
> This proposal’s goal is to make private more attractive to fulfil that 
> original goal. fileprivate’s awkwardness is good, because it attracts 
> attention to it when it is used.

Your previous proposal eliminated this distinction entirely and if I understand 
correctly you still believe that is the best solution.  With that in mind, do 
you really consider it important to call special attention to same-file, 
cross-type members?  If we’re going to have a distinction in the language, do 
you really consider this a more important and useful distinction than the 
distinction supporting the use cases for scoped access?  If the answer to 
either of those questions is no I find it hard to understand how this issue is 
not simply about having the ability to say `private` most of the time (which is 
a naming issue not a semantics issue).

> 
>> I continue to believe that the best solution is to revert "private" to mean 
>> file scope as in Swift 2, and introduce a new "scoped" keyword for those 
>> developers who are specifically desiring the scoped functionality. This was 
>> rejected during the discussion because the migration would be too 
>> disruptive, but it is only disruptive if the migrator rewrites 
>> "private"->"scoped". I assert that most developers would not *want* that 
>> migration to happen; most developers use "private" because they want the 
>> default less-than-internal access control. The few developers who are using 
>> specifically scoped control can modify their code manually. Under this 
>> model, scoped access control is still available for those who need it, and 
>> most users can once again use "private" in cases where it is the natural 
>> default. 
>> 
>> This proposal proposes that "fileprivate" would become a marker to call out 
>> cases where exceptional across-type access is happening. In practice, I 
>> don't believe that will happen, simply because there are many existing cases 
>> of "fileprivate" out there, and this proposal does not suggest migrating 
>> them.
>> 
>> I also disagree that it's useful to call out "fileprivate" as an exceptional 
>> case. It's slightly useful, I'll acknowledge, but it would be *more* useful 
>> to call out the exceptional cases where scope-only control is being used.
>> 
>> So I disagree with the proposal. But I give it only -0.5 because even with 
>> all of that, this is a better definition for "private" than the current one.
>> 
>> -BJ
>> 
>> On Apr 3, 2017, at 12:34 PM, Douglas Gregor via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> Hello Swift Community,
>>> 
>>> In rejecting SE-0159 
>>> ,
>>>  the core team described a potential direction we would like to investigate 
>>> for “private” access control that admits a limited form of type-based 
>>> access control within files. The core team is seeking some discussion here 
>>> and a motivated volunteer to put together a proposal along these lines for 
>>> review in the Swift 4 time-frame (i.e., very soon). To be clear, the core 
>>> team it’s sure this is the right direction to go… but it appears promising 
>>> and we would *love* to be able to settle the access-control issue.
>>> 
>>> The design, specifically, is that a “private” member declared within a type 
>>> “X” or an extension thereof would be accessible from:
>>> 
>>> * An extension of “X” in the same file
>>> * The definition of “X”, if it occurs

Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-07 Thread Matthew Johnson via swift-evolution

> On Apr 7, 2017, at 10:06 AM, BJ Homer via swift-evolution 
>  wrote:
> 
>> It does not remove the scoped access control, it only relaxes it in 
>> extensions to types in the same file.
> 
> Many of the use cases for scoped access given during the review of SE-0159 
> specifically related to restricting access between extensions in the same 
> file. I don't personally use this, but it seems it is definitely used by some 
> developers. 

The most common thing is to have some stored properties that are private and 
include a handful of fileprivate (or higher) methods that operate on these 
properties in the type declaration.  All members that don’t need direct access 
to these properties are placed in extensions specifically to prevent the direct 
access to stored properties which they don’t need.  This minimizes the lines of 
code with access to such properties.

> 
> -BJ
> ___
> 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] Type-based ‘private’ access within a file

2017-04-07 Thread Matthew Johnson via swift-evolution

> On Apr 7, 2017, at 10:32 AM, BJ Homer  wrote:
> 
> 
> On Apr 7, 2017, at 9:23 AM, Matthew Johnson  > wrote:
> 
>> The most common thing is to have some stored properties that are private and 
>> include a handful of fileprivate (or higher) methods that operate on these 
>> properties in the type declaration.  All members that don’t need direct 
>> access to these properties are placed in extensions specifically to prevent 
>> the direct access to stored properties which they don’t need.  This 
>> minimizes the lines of code with access to such properties.
> 
> Is there a reason this could not be implemented by putting all the sensitive 
> stored properties in a separate type from the rest of the code?

This has already been discussed extensively in the threads.  The problem with 
this approach under the current proposal is that there is no way to hide that 
type or its members from the rest of the file.  It can be extended anywhere in 
the file which means the kind of encapsulation intended by users of scoped 
access is not really available.  This is a kind of half-solution that relies on 
not extending the separate type and therefore offers a weaker guarantee while 
requiring extra boilerplate.  It is also a kind of half-solution for those who 
wanted to revert SE-0025.  

Setting aside source compatibility concerns for a brief moment, is there anyone 
who would choose this approach over reverting SE-0025, renaming the current 
modifier, or maintaining the current access modifiers?  If this is nobody’s 
first choice that should be a big cautionary sign.  It would indicate that this 
is the result of “design by committee” where nobody really likes it and it is 
at best the closest to consensus we could get.  I don’t think “this is the best 
we can do because of source compatibility” is an appropriate justification for 
accepting this kind of solution.  If source compatibility is such a paramount 
concern we should probably maintain the status quo or keep looking for a 
better, more source-compatible solution in the future (probably Swift 5).

I think one of the goals for Swift is to try and avoid that kind of decision 
making.  If I’m going to be dissatisfied with part of the language I would 
rather it be for some other reason than that SE has caused the language to 
suffer from “design by committee” kinds of flaws.

> 
> -BJ

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


Re: [swift-evolution] [Review #2] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-07 Thread Matthew Johnson via swift-evolution

> On Apr 7, 2017, at 1:50 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Apr 7, 2017, at 11:48 AM, John McCall  wrote:
>> 
>>> On Apr 7, 2017, at 1:40 PM, Joe Groff  wrote:
 On Apr 7, 2017, at 10:20 AM, John McCall via swift-evolution 
  wrote:
 
> 
> On Apr 7, 2017, at 12:48 AM, Douglas Gregor  wrote:
> 
> 
>> On Apr 6, 2017, at 9:46 PM, John McCall  wrote:
>> 
>>> On Apr 7, 2017, at 12:27 AM, Rick Mann  wrote:
 On Apr 6, 2017, at 20:37 , John McCall  wrote:
 
> On Apr 6, 2017, at 9:28 PM, Rick Mann via swift-evolution 
>  wrote:
> I tend to dislike the backslash as well, but can't suggest a good 
> alternative.
> 
> Does any of this allow for operations within the key path? e.g. 
> Department.employees.@sum.salary?
 
 You can express things like this in the feature as proposed using 
 subscripts:
 
 extension Collection {
 subscript(summing path: KeyPath) -> T {
 var sum: T = 0
 for let elt in self {
 sum += elt[keyPath: path]
 }
 return sum
 }
 }
>>> 
>>> I'm just remembering how AppKit/Cocoa lets you do things like this in a 
>>> very expressive way. Your proposal seems a bit cumbersome. Maybe when 
>>> we have custom annotations, they can be extended to use within key 
>>> paths.
>> 
>> I'm not seriously endorsing this exact spelling.  It would be much 
>> better to be able to write something like:
>> \Department.employees.sum(of: \.salary)
>> However, since "sum" would presumably be a method on Collection, I think 
>> this would have to be a future extension to the proposal, and the 
>> overall thing might have to be a function rather than a key path because 
>> it would no longer have identity.
> 
> Also, less clever but potentially easier to reason about:
> 
>   extension Array where Element == Employee {
> var sumOfSalary: Double {
>   return // ...
> }
>   }
> 
> If you can express it in a computed property, you can refer to it via a 
> key path:
> 
>   \Department.employees.sumOfSalary
 
 Yeah, you can, but that's definitely an expressivity hit.
>>> 
>>> True, but there are some benefits to requiring a subscript/property rather 
>>> than an arbitrary closure, particularly that it gives the operation a 
>>> stable identity and structure so the key path can still be equated/hashed 
>>> and (eventually) iterated through.
>> 
>> Right, I think if you add a method to the chain, the result definitely has 
>> to be a function rather than a key path.  The idea is that you basically 
>> decompose:
>> 
>> \Base.A.B.C
>> 
>> into
>> ([inout]? Base, parameters(A)..., parameters(B)..., parameters(C)...) -> 
>> result(C)
>> 
>> except that if all of the components A, B, and C are just properties or 
>> applied subscripts you can make it a KeyPath instead, which can then 
>> contextually devolve into a function.
> 
> It seems to me that method references (non-mutating ones, at least) could 
> still be treated as read-only key path components. There's not much more than 
> syntax as a difference between a nonmutating method and get-only property or 
> subscript. The method decl is still something we can ascribe identity to.

I like where you guys are going with this!

> 
> -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] Enhancing access levels without breaking changes

2017-04-10 Thread Matthew Johnson via swift-evolution

> On Apr 10, 2017, at 10:26 AM, Tino Heth via swift-evolution 
>  wrote:
> 
>> I’m not sure that this solves anything meaningful (whether in relation to 
>> SE-0169 or more generally), does it? What advantage does this provide over 
>> just declaring the protocol conformance and those methods as a direct part 
>> of the parent type? This seems like it would just introduce more 
>> indentation, and more lines of code, for zero benefit.
> Well, I'm not overwhelmingly convinced of this whole "we put same-module 
> stuff into extensions" anyways, so it's debatable wether proposals like 
> SE-0169 have any meaningful effects at all… do you think that conformances in 
> same-file extensions have a real benefit? 

I think the primary benefit is organizational.  People like having the members 
that implement a conformance grouped together with the conformance declaration.

> 
> If nothing else, nested extensions could save those who actually don't care 
> much about such issues from another breaking change in Swift — and imho it 
> adds consistency:
> We can nest types, so why can't we nest extensions?
> ___
> 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] [Pitch] Remove type-inference for stored property

2017-04-10 Thread Matthew Johnson via swift-evolution

> On Apr 10, 2017, at 11:11 AM, Daniel Duan via swift-evolution 
>  wrote:
> 
> I’m not questioning the value of type inference in general. Just that there 
> are practical implications when we want more of them. There’s a difference in 
> inferencing type declaration properties and local variables: the former is 
> more likely to be exported and read by others. These arguments are all in the 
> draft proposal.

When a declaration is exported outside a module whoever is reading it isn’t 
reading the source directly.  They are reading documentation or a generated 
header of some kind.  The annotation can easily be added by tools that produce 
these.

> 
>> On Apr 10, 2017, at 9:07 AM, Sean Heber  wrote:
>> 
>> Well, I’m not really a beginner, but for me personally, the computer is here 
>> to help me do my work and to do some of the thinking for me. I really hate 
>> repeating myself when it comes to types - especially if the types get wordy 
>> (collections, etc). Swift is pretty good about it - but these warts stick 
>> out. The idea that we should make it *less* good at this really rubs me the 
>> wrong way. How many times have you seen lines of code like this in 
>> C++-ish/C#-ish languages:
>> 
>> Foo foo = new Foo();
>> 
>> Every time I see that sort of thing, I cringe a little.
>> 
>> IMO if you wanted to be super opinionated, the language would actually warn 
>> if you did this:
>> 
>> let foo: Foo = Foo()
>> 
>> And offer a fixit to:
>> 
>> let foo = Foo()
>> 
>> With no warning for things like this because you’re obviously doing 
>> something intentional:
>> 
>> let foo: FooSuperclass = Foo()
>> 
>> But I’d settle for no warnings and getting the inference to work in all 
>> contexts. :)
>> 
>> l8r
>> Sean
>> 
>> 
>>> On Apr 10, 2017, at 10:58 AM, Daniel Duan  wrote:
>>> 
>>> It is helpful in the sense that it tells us what’s really inconsistent: 
>>> beginner’s have to learn when inference is available when declaring their 
>>> types. That’s story is sketchy.
 On Apr 10, 2017, at 8:55 AM, Sean Heber  wrote:
 
 This is not really a helpful comment, but: I kinda wish they did.
 
 l8r
 Sean
 
> On Apr 10, 2017, at 10:54 AM, Daniel Duan via swift-evolution 
>  wrote:
> 
> Neither of these works btw.
> 
> func bar(myString = “hello”)
> class Baz {
> let myString = { return “hello” }()
> }
> 
>> On Apr 9, 2017, at 11:26 PM, Jean-Daniel  wrote:
>> 
>> I’m full -1 on this one. It will make the language inconsistent. How do 
>> you explain a new comer that type inference work in some case, but not 
>> in other cases, while in both the compiler is completely capable to 
>> define the type.
>> 
>> Why 
>> 
>> let myString = "hello" 
>> 
>> would be accepted but not 
>> 
>> class Foo {
>>  let myString = "hello" 
>> }
>> 
>> 
>> 
>>> Le 10 avr. 2017 à 04:05, Daniel Duan via swift-evolution 
>>>  a écrit :
>>> 
>>> I’m still not sure whether *I* want this. But here’s a proposal 
>>> anyways: https://gist.github.com/dduan/5017a0b0f0880d014f4ce14c4ca7fb55
>>> 
 On Apr 7, 2017, at 12:21 AM, Daniel Duan via swift-evolution 
  wrote:
 
 Hi all,
 
 In a discussion about inferring parameter types from default value, 
 Slava brought up some performance problems caused by type inference 
 for stored properties in side types:
 
 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033882.html
 
 Towards the end, the post mentioned that some Swift team members 
 contemplated requiring types for stored properties in type 
 declarations. I think this idea deserves some more attention. Hence 
 this last minute idea-floating.
 
 In addition to solving a performance headache in implementation, 
 there're always the general benefit of making type declartion more 
 explicit and readable (clarity for reader should out-weigh pleasure of 
 the author). Making the
 language slightly more consistent (we are not inferring types for 
 default parameter values in function anyways).
 
 The cons for doing this are obvious too: the inference makes the 
 language feels more friendly and is, undoubtedly, a beloved feature 
 for many. This would be a source breaking change.
 
 Just thought I'd float the idea to gather some quick reaction. What do 
 y'all think?
 
 Daniel Duan
 ___
 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

Re: [swift-evolution] [Pitch] Remove type-inference for stored property

2017-04-10 Thread Matthew Johnson via swift-evolution

> On Apr 10, 2017, at 11:22 AM, Daniel Duan  wrote:
> 
> I guess I'm using the word "export" loosely. Often times I find myself 
> reading type signatures in my own codebase either because it's written by 
> someone else on my team or by myself long time ago. I think open-source 
> library users have the same problem. Exposure to a particular local variable 
> is less likely.

If you’re reading code in a codebase you work on most of the time you’ll be 
reading it using a tool that can give you the annotation using something like 
opt-click in Xcode.  I don’t think it’s worth cluttering up our code with 
annotations that are readily available to most readers.  Most of the time 
annotations introduce noise that reduces clarity.  I don’t think relying on 
tools in the occasional case where the type isn’t obvious to an individual 
reader is a bad thing.

> 
> Daniel Duan
> Sent from my iPhone
> 
>> On Apr 10, 2017, at 9:16 AM, Matthew Johnson  wrote:
>> 
>> 
>>> On Apr 10, 2017, at 11:11 AM, Daniel Duan via swift-evolution 
>>>  wrote:
>>> 
>>> I’m not questioning the value of type inference in general. Just that there 
>>> are practical implications when we want more of them. There’s a difference 
>>> in inferencing type declaration properties and local variables: the former 
>>> is more likely to be exported and read by others. These arguments are all 
>>> in the draft proposal.
>> 
>> When a declaration is exported outside a module whoever is reading it isn’t 
>> reading the source directly.  They are reading documentation or a generated 
>> header of some kind.  The annotation can easily be added by tools that 
>> produce these.
>> 
>>> 
 On Apr 10, 2017, at 9:07 AM, Sean Heber  wrote:
 
 Well, I’m not really a beginner, but for me personally, the computer is 
 here to help me do my work and to do some of the thinking for me. I really 
 hate repeating myself when it comes to types - especially if the types get 
 wordy (collections, etc). Swift is pretty good about it - but these warts 
 stick out. The idea that we should make it *less* good at this really rubs 
 me the wrong way. How many times have you seen lines of code like this in 
 C++-ish/C#-ish languages:
 
 Foo foo = new Foo();
 
 Every time I see that sort of thing, I cringe a little.
 
 IMO if you wanted to be super opinionated, the language would actually 
 warn if you did this:
 
 let foo: Foo = Foo()
 
 And offer a fixit to:
 
 let foo = Foo()
 
 With no warning for things like this because you’re obviously doing 
 something intentional:
 
 let foo: FooSuperclass = Foo()
 
 But I’d settle for no warnings and getting the inference to work in all 
 contexts. :)
 
 l8r
 Sean
 
 
> On Apr 10, 2017, at 10:58 AM, Daniel Duan  wrote:
> 
> It is helpful in the sense that it tells us what’s really inconsistent: 
> beginner’s have to learn when inference is available when declaring their 
> types. That’s story is sketchy.
>> On Apr 10, 2017, at 8:55 AM, Sean Heber  wrote:
>> 
>> This is not really a helpful comment, but: I kinda wish they did.
>> 
>> l8r
>> Sean
>> 
>>> On Apr 10, 2017, at 10:54 AM, Daniel Duan via swift-evolution 
>>>  wrote:
>>> 
>>> Neither of these works btw.
>>> 
>>> func bar(myString = “hello”)
>>> class Baz {
>>> let myString = { return “hello” }()
>>> }
>>> 
 On Apr 9, 2017, at 11:26 PM, Jean-Daniel  wrote:
 
 I’m full -1 on this one. It will make the language inconsistent. How 
 do you explain a new comer that type inference work in some case, but 
 not in other cases, while in both the compiler is completely capable 
 to define the type.
 
 Why 
 
 let myString = "hello" 
 
 would be accepted but not 
 
 class Foo {
   let myString = "hello" 
 }
 
 
 
> Le 10 avr. 2017 à 04:05, Daniel Duan via swift-evolution 
>  a écrit :
> 
> I’m still not sure whether *I* want this. But here’s a proposal 
> anyways: 
> https://gist.github.com/dduan/5017a0b0f0880d014f4ce14c4ca7fb55
> 
>> On Apr 7, 2017, at 12:21 AM, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>> Hi all,
>> 
>> In a discussion about inferring parameter types from default value, 
>> Slava brought up some performance problems caused by type inference 
>> for stored properties in side types:
>> 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033882.html
>> 
>> Towards the end, the post mentioned that some Swift team members 
>> contemplated requiring types for stored properties in type 
>> declarations. I thin

Re: [swift-evolution] [Pitch] Remove type-inference for stored property

2017-04-10 Thread Matthew Johnson via swift-evolution

> On Apr 10, 2017, at 11:38 AM, Daniel Duan  wrote:
> 
> Using tools isn't a bad thing. Designing language assuming users are using 
> tools with certain capability is kind of a bad thing.
> 
> Where tools *can* help is if the tools enhance the language user's 
> experience, which is why I proposed the inference capabilities be kept for 
> diagnostics.
> 
> I also disagree with the characterization that types in properties is 
> "clustering up" the code. The value inference provided here is make the 
> authoring experience better. I can see for obvious default expressions 
> (string/number literal perhaps) the readability isn't degraded by too much. 
> But it's not as clear as explicit types for the *reader*.

I said “cluttering”, not “clustering” (which has a more derogatory implication 
for many people).  

In any case, this is an area where there are differing perspectives each with 
some merit.  I think it’s best to leave it up to each of us what makes the most 
sense for our code.  IMO, and that of at least some others who have commented, 
some code is more clear to readers with annotations and some is more clear to 
readers without annotations.  

Like I said earlier, I’m willing to keep an open mind on proposals in this area 
but I don’t support a wholesale ban on inference directly initialized member 
declarations.  It may not be possible to do something less than a wholesale ban 
without introducing more confusion than we have today as to when inference is 
permitted and when it isn’t.  If it isn’t that’s ok with me.  If it is, I’ll 
consider such a proposal on its merit if one is brought forward.

> 
> Daniel Duan
> Sent from my iPhone
> 
> On Apr 10, 2017, at 9:26 AM, Matthew Johnson  > wrote:
> 
>> 
>>> On Apr 10, 2017, at 11:22 AM, Daniel Duan >> > wrote:
>>> 
>>> I guess I'm using the word "export" loosely. Often times I find myself 
>>> reading type signatures in my own codebase either because it's written by 
>>> someone else on my team or by myself long time ago. I think open-source 
>>> library users have the same problem. Exposure to a particular local 
>>> variable is less likely.
>> 
>> If you’re reading code in a codebase you work on most of the time you’ll be 
>> reading it using a tool that can give you the annotation using something 
>> like opt-click in Xcode.  I don’t think it’s worth cluttering up our code 
>> with annotations that are readily available to most readers.  Most of the 
>> time annotations introduce noise that reduces clarity.  I don’t think 
>> relying on tools in the occasional case where the type isn’t obvious to an 
>> individual reader is a bad thing.
>> 
>>> 
>>> Daniel Duan
>>> Sent from my iPhone
>>> 
 On Apr 10, 2017, at 9:16 AM, Matthew Johnson >>> > wrote:
 
 
> On Apr 10, 2017, at 11:11 AM, Daniel Duan via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> I’m not questioning the value of type inference in general. Just that 
> there are practical implications when we want more of them. There’s a 
> difference in inferencing type declaration properties and local 
> variables: the former is more likely to be exported and read by others. 
> These arguments are all in the draft proposal.
 
 When a declaration is exported outside a module whoever is reading it 
 isn’t reading the source directly.  They are reading documentation or a 
 generated header of some kind.  The annotation can easily be added by 
 tools that produce these.
 
> 
>> On Apr 10, 2017, at 9:07 AM, Sean Heber > > wrote:
>> 
>> Well, I’m not really a beginner, but for me personally, the computer is 
>> here to help me do my work and to do some of the thinking for me. I 
>> really hate repeating myself when it comes to types - especially if the 
>> types get wordy (collections, etc). Swift is pretty good about it - but 
>> these warts stick out. The idea that we should make it *less* good at 
>> this really rubs me the wrong way. How many times have you seen lines of 
>> code like this in C++-ish/C#-ish languages:
>> 
>> Foo foo = new Foo();
>> 
>> Every time I see that sort of thing, I cringe a little.
>> 
>> IMO if you wanted to be super opinionated, the language would actually 
>> warn if you did this:
>> 
>> let foo: Foo = Foo()
>> 
>> And offer a fixit to:
>> 
>> let foo = Foo()
>> 
>> With no warning for things like this because you’re obviously doing 
>> something intentional:
>> 
>> let foo: FooSuperclass = Foo()
>> 
>> But I’d settle for no warnings and getting the inference to work in all 
>> contexts. :)
>> 
>> l8r
>> Sean
>> 
>> 
>>> On Apr 10, 2017, at 10:58 AM, Daniel Duan >> > wrote:
>>> 
>>> It is 

  1   2   3   4   5   6   7   8   9   10   >