Re: [swift-evolution] [Pitch] Extending [at]autoclosure

2017-07-01 Thread Jaden Geller via swift-evolution
"you can pass an autoclosure to an autoclosure”

This is very surprising to me! I think that should be an error… When I write an 
argument of type `@autoclosure () -> T`, only arguments of type `T` ought to be 
accepted.

> On Jul 1, 2017, at 3:50 PM, Adrian Zubarev  
> wrote:
> 
> It’s not about whether I should use these like this or not. It’s about that 
> you can pass an autoclosure to an autoclosure (where the metatype is the same 
> as a normal closure), but you cannot pass a normal closure to an autoclosure. 
> @escaping making things even worse. When using Void as a return type Xcode 
> will provide you an additional completion option which only will result in an 
> error!
> 
> func foo(_: @autoclosure () -> Void) { }
> 
> func bar(_ test: @autoclosure () -> Void) {
> foo(test) // works
> }
> 
> func baz(_ test: @autoclosure @escaping () -> Void) {
> print(type(of: test)) // prints `() -> ()`
> foo(test) // error because it's `@escaping`
> }
> 
> let closure: () -> Void = {}
> 
> bar(())
> 
> bar(closure) // error
> 
> // Suggested autocompletion by Xcode which results in an error
> bar {
> <#code#>
> }
> Long story short autoclosure is bugged and deserves this fix.
> 
> Here a few examples where I’m using the mentioned non-generic extension 
> instead of an if statement:
> 
> self.shouldPop.whenTrue(execute: self.toView.isUserInteractionEnabled = false)
> 
> ($0 == .end).whenTrue(execute: completion)
> (!option.isInteractive).whenTrue(execute: sendEvents)
> There are other cases where I’d use it, but I cannot because the generic 
> autoclosure function simply does not work as I’d expect it to work:
> 
> @discardableReuslt
> func whenTrue(execute closure: @autoclosure () -> T) -> T? {
>if self { return closure() }
>return nil
> }
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 2. Juli 2017 um 00:23:43, Jaden Geller (jaden.gel...@gmail.com 
> ) schrieb:
> 
>> I feel strongly that you shouldn’t be using autoclosure in these cases. 
>> Instead, write `true.whenTrue { … }` and `true.whenTrue(myClosure)`.
>> 
>>> On Jul 1, 2017, at 3:17 PM, Adrian Zubarev >> > wrote:
>>> 
>>> I clearly disagree with your point. Autoclosure supposed to be a 
>>> syntactically convenience feature to omit braces, which as a consequence 
>>> needs to disable arguments. However it is not said that you cannot pass a 
>>> closure with the same signature to the autoclosure, which currently is not 
>>> possible unless it’s another autoclosure. This doesn’t feel right at all.
>>> 
>>> func foo(_: @autoclosure () -> Void) {}
>>> 
>>> func bar(_ test: @autoclosure () -> Void) {
>>>foo(test) // works 
>>> }
>>> 
>>> let closure: () -> Void = {}
>>> 
>>> foo(closure) // error
>>> Here is another example where autoclosure takes over and produces false 
>>> result even when the correct overload is present but the resolution ends up 
>>> picking an autoclosure.
>>> 
>>> extension Bool {
>>> 
>>> /// #1
>>> func whenTrue(execute closure: () -> Void) {
>>> if self { closure() }
>>> }
>>> 
>>> /// #2
>>> func whenTrue(execute closure: @autoclosure () -> Void) {
>>> if self { closure() }
>>> }
>>> 
>>> /// #3
>>> func whenTrue(execute closure: @autoclosure () -> T) -> T? {
>>> if self { return closure() }
>>> return nil
>>> }
>>> }
>>> 
>>> let test: () -> Void = { }
>>> // #3 wins and produces a wrong type () -> (() -> Void)?, but I expect #1 
>>> here
>>> // () -> Void?
>>> true.whenTrue(execute: test)   
>>> A syntactical convenience feature should not disable explicitness!
>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 1. Juli 2017 um 19:46:55, jaden.gel...@gmail.com 
>>>  (jaden.gel...@gmail.com 
>>> ) schrieb:
>>> 
 
 
 On Jun 30, 2017, at 1:48 AM, Adrian Zubarev via swift-evolution 
 > wrote:
 
> Well as Jordan Rose said on the linked SR, option (1) will probably never 
> happen. Option (3) only makes sense if all of the options are supported 
> (in that case there wouldn’t be any need for explicit @autoclosure, which 
> could simply be merged into the closure type), or (2) is NOT supported so 
> that one could pass a default autoclosure.
> 
> It leaves us only with (2), which is potentially a (small) breaking 
> change, but it also feels more like a fix. I cannot imagine anyone is 
> wrapping whole closures with auto closure, nor do I think a ‘convenience’ 
> operation should disable the explicit ability to pass in a closure with 
> the same signature. The latter feels like a bug. Furthermore I think most 
> code that relies on this is already doing something like.

Re: [swift-evolution] [Pitch] Extending [at]autoclosure

2017-07-01 Thread Jaden Geller via swift-evolution
I feel strongly that you shouldn’t be using autoclosure in these cases. 
Instead, write `true.whenTrue { … }` and `true.whenTrue(myClosure)`.

> On Jul 1, 2017, at 3:17 PM, Adrian Zubarev  
> wrote:
> 
> I clearly disagree with your point. Autoclosure supposed to be a 
> syntactically convenience feature to omit braces, which as a consequence 
> needs to disable arguments. However it is not said that you cannot pass a 
> closure with the same signature to the autoclosure, which currently is not 
> possible unless it’s another autoclosure. This doesn’t feel right at all.
> 
> func foo(_: @autoclosure () -> Void) {}
> 
> func bar(_ test: @autoclosure () -> Void) {
>foo(test) // works
> }
> 
> let closure: () -> Void = {}
> 
> foo(closure) // error
> Here is another example where autoclosure takes over and produces false 
> result even when the correct overload is present but the resolution ends up 
> picking an autoclosure.
> 
> extension Bool {
> 
> /// #1
> func whenTrue(execute closure: () -> Void) {
> if self { closure() }
> }
> 
> /// #2
> func whenTrue(execute closure: @autoclosure () -> Void) {
> if self { closure() }
> }
> 
> /// #3
> func whenTrue(execute closure: @autoclosure () -> T) -> T? {
> if self { return closure() }
> return nil
> }
> }
> 
> let test: () -> Void = { }
> // #3 wins and produces a wrong type () -> (() -> Void)?, but I expect #1 here
> // () -> Void?
> true.whenTrue(execute: test)  
> A syntactical convenience feature should not disable explicitness!
> 
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 1. Juli 2017 um 19:46:55, jaden.gel...@gmail.com 
>  (jaden.gel...@gmail.com 
> ) schrieb:
> 
>> 
>> 
>> On Jun 30, 2017, at 1:48 AM, Adrian Zubarev via swift-evolution 
>> > wrote:
>> 
>>> Well as Jordan Rose said on the linked SR, option (1) will probably never 
>>> happen. Option (3) only makes sense if all of the options are supported (in 
>>> that case there wouldn’t be any need for explicit @autoclosure, which could 
>>> simply be merged into the closure type), or (2) is NOT supported so that 
>>> one could pass a default autoclosure.
>>> 
>>> It leaves us only with (2), which is potentially a (small) breaking change, 
>>> but it also feels more like a fix. I cannot imagine anyone is wrapping 
>>> whole closures with auto closure, nor do I think a ‘convenience’ operation 
>>> should disable the explicit ability to pass in a closure with the same 
>>> signature. The latter feels like a bug. Furthermore I think most code that 
>>> relies on this is already doing something like.
>>> 
>>> func bar(_ closure: @autoclosure () -> Int) { foo(closure)}
>>> 
>>> func foo(_ closure: () -> Int)
>>> But this is only an assumption of mine.
>>> 
>>> Theoretically it suppose to work the other way around, right? Again 
>>> @autoclosure supposed to be a syntactical convenience feature which implies 
>>> that it won’t disable *too* much from the closure type. Disallowing 
>>> arguments is logical consequence but not the other issues I mentioned here 
>>> and in the SR.
>>> 
>>> —
>>> 
>>> One question: Do we need to go through a full evolution process for pitch 
>>> (2) or is a bug report enough here?
>>> 
>> Surely the former—I'm fully against this change, and imagine others are 
>> also. Autoclosure exists to provide opt-in lazy evaluation of values by 
>> wrapping them in a closure. I think it's semantically incorrect to accept an 
>> already wrapped value here, and adding this sort of implicit conversion can 
>> introduce potential ambiguity when used with generic functions.
>> 
>> Very large -1.
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 30. Juni 2017 um 00:59:45, Beta (rwidm...@apple.com 
>>> ) schrieb:
>>> 
 These are all interesting ideas at first blush, but introduce some 
 oddities into the type system
 
 1. We accept this .  If we were to take this as an official language 
 change it would mean that we would allow coercing T to (_) -> T by 
 emitting a closure that takes an argument list (of arity given by the 
 contextual type) that we throw away anyways.  I would much prefer we 
 diagnose this instead.  @autoclosure is a syntactically convenient way to 
 ask for laziness - that’s it.
 
 2. Doing this collapses overloads on @autoclosure
 
 func foo(_ f : @autoclosure () -> String) {}
 func foo(_ f : () -> String) {}
 
 
 Which is fine by me except for the code you would break that relies on 
 this.  I don’t see a reasonable migration path here - perhaps you have one 
 in mind.
 
 3. @autoclosure is a parameter attribute.  Allowing it to appear in other 
 positions is redundant and doesn’t actually 

Re: [swift-evolution] [Pitch] Extending [at]autoclosure

2017-07-01 Thread Jaden Geller via swift-evolution


> On Jun 30, 2017, at 1:48 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> Well as Jordan Rose said on the linked SR, option (1) will probably never 
> happen. Option (3) only makes sense if all of the options are supported (in 
> that case there wouldn’t be any need for explicit @autoclosure, which could 
> simply be merged into the closure type), or (2) is NOT supported so that one 
> could pass a default autoclosure.
> 
> It leaves us only with (2), which is potentially a (small) breaking change, 
> but it also feels more like a fix. I cannot imagine anyone is wrapping whole 
> closures with auto closure, nor do I think a ‘convenience’ operation should 
> disable the explicit ability to pass in a closure with the same signature. 
> The latter feels like a bug. Furthermore I think most code that relies on 
> this is already doing something like.
> 
> func bar(_ closure: @autoclosure () -> Int) { foo(closure)}
> 
> func foo(_ closure: () -> Int)
> But this is only an assumption of mine.
> 
> Theoretically it suppose to work the other way around, right? Again 
> @autoclosure supposed to be a syntactical convenience feature which implies 
> that it won’t disable *too* much from the closure type. Disallowing arguments 
> is logical consequence but not the other issues I mentioned here and in the 
> SR.
> 
> —
> 
> One question: Do we need to go through a full evolution process for pitch (2) 
> or is a bug report enough here?
> 
Surely the former—I'm fully against this change, and imagine others are also. 
Autoclosure exists to provide opt-in lazy evaluation of values by wrapping them 
in a closure. I think it's semantically incorrect to accept an already wrapped 
value here, and adding this sort of implicit conversion can introduce potential 
ambiguity when used with generic functions.

Very large -1.
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 30. Juni 2017 um 00:59:45, Beta (rwidm...@apple.com) schrieb:
> 
>> These are all interesting ideas at first blush, but introduce some oddities 
>> into the type system
>> 
>> 1. We accept this .  If we were to take this as an official language change 
>> it would mean that we would allow coercing T to (_) -> T by emitting a 
>> closure that takes an argument list (of arity given by the contextual type) 
>> that we throw away anyways.  I would much prefer we diagnose this instead.  
>> @autoclosure is a syntactically convenient way to ask for laziness - that’s 
>> it.
>> 
>> 2. Doing this collapses overloads on @autoclosure
>> 
>> func foo(_ f : @autoclosure () -> String) {}
>> func foo(_ f : () -> String) {}
>> 
>> 
>> Which is fine by me except for the code you would break that relies on this. 
>>  I don’t see a reasonable migration path here - perhaps you have one in mind.
>> 
>> 3. @autoclosure is a parameter attribute.  Allowing it to appear in other 
>> positions is redundant and doesn’t actually accomplish anything outside of 
>> maintaining consistency with the first point.
>> 
>> I hope I don’t come off as too harsh.  It’s just a little shocking to me 
>> that we accept the code in the linked SR.
>> 
>> ~Robert Widmann
>> 
>>> On Jun 24, 2017, at 9:10 AM, Adrian Zubarev via swift-evolution 
>>>  wrote:
>>> 
>>> Hello folks,
>>> 
>>> Here is a quick and straightforward pitch about @autoclosure. Currently the 
>>> attribute indicates that the caller has to pass an expression so that the 
>>> braces can be omitted. This is a convenient behavior only, but it also has 
>>> it’s shortcomings.
>>> 
>>> I would like to propose an extension of that behavior.
>>> 
>>> 
>>> 1. Allow access to arguments and shorthand argument names:
>>> // Bug: https://bugs.swift.org/browse/SR-5296
>>> func foo(_ test: @autoclosure (Int) -> Int = { $0 }) {
>>> print(test(42))
>>> }
>>> 
>>> // Convenient access using shorthand arguments
>>> foo(Int(Double($0) * 3.14)))
>>> 
>>> 2. Make @autoclosure only wrap when necessary:
>>> func bar(_ test: @autoclosure () -> Int) {
>>> print(test())
>>> }
>>> 
>>> let test = { 42 }
>>> 
>>> // function produces expected type 'Int'; did you mean to call it with '()'?
>>> bar(test)
>>> 
>>> 3. Extend @autoclosure to closure types in general (this change is for 
>>> consistent alignment):
>>> // Note how we're using the shorthand argument list for this expression
>>> let uppercaseWrapper: @autoclosure (String) -> String = $0.uppercased()
>>> 
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-29 Thread Jaden Geller via swift-evolution

> On Jun 29, 2017, at 7:35 PM, Yuta Koshizawa  wrote:
> 
> "In -Ounchecked builds, the optimizer may assume that this function is never 
> called. Failure to satisfy that assumption is a serious programming error.”
> 
> Yes, and so the following `!!` can perform identically to `!` in -Ounchecked 
> builds when it is inlined.

Yes, I guess I wasn’t clear. I mean that there’s no problem.

> public static func !!(optional: Optional, errorMessage:
> @autoclosure () -> String) -> Wrapped {
> precondition(optional != nil, errorMessage())
> return optional!
> }
> 
> --
> Yuta
> 
> 
> 2017-06-29 6:42 GMT+09:00 Jaden Geller  >:
> 
> > On Jun 28, 2017, at 7:47 AM, Erica Sadun via swift-evolution 
> > > wrote:
> >
> >
> >> On Jun 28, 2017, at 3:52 AM, Yuta Koshizawa via swift-evolution 
> >> > wrote:
> >>
> >> Hi, I think it is an orthogonal issue if we need a new operator. It is
> >> also possible to introduce an infix `!` for it.
> >>
> >> I am sure that we do not need to avoid `precondition` as long as we
> >> use it appropriately. It is useful to realize consistent behavior with
> >> `Array`'s `subscript`, forced unwrapping `!`, `&+` and so on. In this
> >> context, `precondition` does not mean a general word "precondition"
> >> but the `precondition` function in the Swift standard library, which
> >> is removed when -Ounchecked.
> >
> >
> > How would the line run then? Would it simply act as a forced unwrapped 
> > under -Ounchecked?
> 
> From the docs:
> 
> "In -Ounchecked builds, the optimizer may assume that this function is never 
> called. Failure to satisfy that assumption is a serious programming error.”
> 
> Aka, v. bad things happen if the precondition does not hold.
> 
> >
> > -- E
> >
> > ___
> > 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] Introducing the "Unwrap or Die" operator to the standard library

2017-06-28 Thread Jaden Geller via swift-evolution
I realize that, which is why I’m strongly against this proposal. I could 
potentially be for adding the `??` overload temporarily, but I don’t really 
feel it is necessary either.

> On Jun 28, 2017, at 2:55 PM, Adrian Zubarev <adrian.zuba...@devandartist.com> 
> wrote:
> 
> Besides all that Never as a bottom type means that you can use fatalError() 
> literally everywhere not only on the RHS of ??.
> 
> func foo(_: Int) {}
> 
> foo(fatalError())
> That said, we can kill our application everywhere we would ever imagine, 
> regardless of whether there is ? or ! operator present somewhere.
> 
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 28. Juni 2017 um 23:50:18, Jaden Geller via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> I’m strongly against not using the `??` operator for `x ?? fatalError()` 
>> since that is naturally what will be possible once the `Never` type is a 
>> real bottom type. If you want to use `!!` for the `x !! “bad things!”` 
>> convenience form, I don’t care. But the `Never` form should definitely, 
>> definitely use `??`.
>> 
>>> On Jun 28, 2017, at 1:30 PM, Erica Sadun via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Based on the feedback on this thread, I'm coming to the following 
>>> conclusions:
>>> 
>>> `!!` sends the right semantic message. "Unwrap or die" is an unsafe 
>>> operation. It is based on `!`, the unsafe forced unwrap operator, and not 
>>> on `??`, the safe fallback nil-coalescing operator. Its symbology should 
>>> therefore follow `!` and not `?`. 
>>> 
>>> The `!!` operator should follow the same semantics as 
>>> `Optional.unsafelyUnwrapped`, which establishes a precedent for this 
>>> approach:
>>> 
>>> > "The unsafelyUnwrapped property provides the same value as the forced 
>>> > unwrap operator (postfix !). However, in optimized builds (-O), no check 
>>> > is performed to ensure that the current instance actually has a value. 
>>> > Accessing this property in the case of a nil value is a serious 
>>> > programming error and could lead to undefined behavior or a runtime 
>>> > error."
>>> 
>>> By following `Optional.unsafelyUnwrapped`, this approach is consistent with 
>>> https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures
>>>  
>>> <https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures>
>>> 
>>> > "Logic failures are intended to be handled by fixing the code. It means 
>>> > checks of logic failures can be removed if the code is tested enough.
>>> Actually checks of logic failures for various operations, `!`, `array[i]`, 
>>> `&+` and so on, are designed and implemented to be removed
>>> when we use `-Ounchecked`. It is useful for heavy computation like image 
>>> processing and machine learning in which overhead of those checks is not 
>>> permissible."
>>> 
>>> The right hand side should use a string (or more properly a string 
>>> autoclosure) in preference to using a `Never` bottom type or a `() -> 
>>> Never` closure. A string provides the cleanest user experience, and allows 
>>> the greatest degree of self-documentation. 
>>> 
>>> - A string is cleaner and more readable to type. It respects DRY, and 
>>> avoids using *both* the operator and the call to `fatalError` or 
>>> `preconditionFailure` to signal an unsafe condition:
>>> `let last = array.last !! “Array guaranteed non-empty" // readable`
>>> than: 
>>> `let last = array.last !! fatalError(“Array guaranteed non-empty”) // 
>>> redundant, violates DRY`
>>> 
>>> - A string allows the operator *itself* to unsafely fail, just as the unary 
>>> version of `!` does now. It does this with additional feedback to the 
>>> developer during testing, code reading, and code maintenance. The string 
>>> provides a self-auditing in-line annotation of the reason why the forced 
>>> unwrap has been well considered, using a language construct to support this.
>>> 
>>> - A string disallows a potentially unsafe `Never` call that does not 
>>> reflect a serious programming error, for example:
>>> let last = array.last !! f() // where func f() -> Never { while true {} }
>>> 
>>> - Although as several l

Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-28 Thread Jaden Geller via swift-evolution

> On Jun 28, 2017, at 7:47 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Jun 28, 2017, at 3:52 AM, Yuta Koshizawa via swift-evolution 
>>  wrote:
>> 
>> Hi, I think it is an orthogonal issue if we need a new operator. It is
>> also possible to introduce an infix `!` for it.
>> 
>> I am sure that we do not need to avoid `precondition` as long as we
>> use it appropriately. It is useful to realize consistent behavior with
>> `Array`'s `subscript`, forced unwrapping `!`, `&+` and so on. In this
>> context, `precondition` does not mean a general word "precondition"
>> but the `precondition` function in the Swift standard library, which
>> is removed when -Ounchecked.
> 
> 
> How would the line run then? Would it simply act as a forced unwrapped under 
> -Ounchecked? 

From the docs:

"In -Ounchecked builds, the optimizer may assume that this function is never 
called. Failure to satisfy that assumption is a serious programming error.”

Aka, v. bad things happen if the precondition does not hold.

> 
> -- E
> 
> ___
> 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] Introducing the "Unwrap or Die" operator to the standard library

2017-06-28 Thread Jaden Geller via swift-evolution
I’m strongly against not using the `??` operator for `x ?? fatalError()` since 
that is naturally what will be possible once the `Never` type is a real bottom 
type. If you want to use `!!` for the `x !! “bad things!”` convenience form, I 
don’t care. But the `Never` form should definitely, definitely use `??`.

> On Jun 28, 2017, at 1:30 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Based on the feedback on this thread, I'm coming to the following conclusions:
> 
> `!!` sends the right semantic message. "Unwrap or die" is an unsafe 
> operation. It is based on `!`, the unsafe forced unwrap operator, and not on 
> `??`, the safe fallback nil-coalescing operator. Its symbology should 
> therefore follow `!` and not `?`. 
> 
> The `!!` operator should follow the same semantics as 
> `Optional.unsafelyUnwrapped`, which establishes a precedent for this approach:
> 
> > "The unsafelyUnwrapped property provides the same value as the forced 
> > unwrap operator (postfix !). However, in optimized builds (-O), no check is 
> > performed to ensure that the current instance actually has a value. 
> > Accessing this property in the case of a nil value is a serious programming 
> > error and could lead to undefined behavior or a runtime error."
> 
> By following `Optional.unsafelyUnwrapped`, this approach is consistent with 
> https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures
>  
> 
> 
> > "Logic failures are intended to be handled by fixing the code. It means 
> > checks of logic failures can be removed if the code is tested enough.
> Actually checks of logic failures for various operations, `!`, `array[i]`, 
> `&+` and so on, are designed and implemented to be removed
> when we use `-Ounchecked`. It is useful for heavy computation like image 
> processing and machine learning in which overhead of those checks is not 
> permissible."
> 
> The right hand side should use a string (or more properly a string 
> autoclosure) in preference to using a `Never` bottom type or a `() -> Never` 
> closure. A string provides the cleanest user experience, and allows the 
> greatest degree of self-documentation. 
> 
> - A string is cleaner and more readable to type. It respects DRY, and avoids 
> using *both* the operator and the call to `fatalError` or 
> `preconditionFailure` to signal an unsafe condition:
> `let last = array.last !! “Array guaranteed non-empty" // readable`
> than: 
> `let last = array.last !! fatalError(“Array guaranteed non-empty”) // 
> redundant, violates DRY`
> 
> - A string allows the operator *itself* to unsafely fail, just as the unary 
> version of `!` does now. It does this with additional feedback to the 
> developer during testing, code reading, and code maintenance. The string 
> provides a self-auditing in-line annotation of the reason why the forced 
> unwrap has been well considered, using a language construct to support this.
> 
> - A string disallows a potentially unsafe `Never` call that does not reflect 
> a serious programming error, for example:
> let last = array.last !! f() // where func f() -> Never { while true {} }
> 
> - Although as several list members mention, a `Never` closure solution is 
> available today in Swift, so is the `!!` operator solution. Neither one 
> requires a fundamental change to the language.
> 
> - Pushing forward on this proposal does not in any way reflect on adopting 
> the still-desirable `Never` bottom type.
> 
>> On Jun 28, 2017, at 12:42 PM, Tony Allevato via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>> On Wed, Jun 28, 2017 at 11:15 AM Dave DeLong > > wrote:
>>> On Jun 28, 2017, at 10:44 AM, Adrian Zubarev via swift-evolution 
>>> > wrote:
>>> 
>>> Well the main debate is that, we all want early access to a feature that 
>>> will be part of Swift as soon as `Never` becomes the bottom type. When this 
>>> happens the `??` will automatically support the pitched behavior. Until 
>>> then if we all agree that we should add it now in a way that will not break 
>>> anything we can simply add an overload to `??` as I previously showed.
>>> 
>> 
>> I believe we should add it now, but I like the recent observation that 
>> making ?? suddenly become a potentially crashing operator violates the 
>> expectation that ? is an indication of safety.
>> 
>> ?? does *not* become a potentially crashing operator. The *fatalError* (or 
>> whatever else the user chooses to put there) on the right-hand side is the 
>> crashing operation.
>> 
>> 
>> On the other hand, the existing semantics of Swift are that ! is always 
>> dangerous, so making !! be the a potentially crashing operator is much more 
>> consistent with the language.
>> 
>>> There is no 

Re: [swift-evolution] [Proposal] Associated Type and Generic One-to-One Mapping

2017-06-27 Thread Jaden Geller via swift-evolution
I’ve run into this issue many times in the real world as well. For example, 
consider the following protocol:

protocol OptionalType {
associatedtype Wrapped
}

It is not possible to conform `Optional` to this protocol because its generic 
type is already named `Wrapped`. Only when the associated type can be inferred 
is conformance possible.

I definitely think we need a solution, but I don’t know what that solution 
should be.

Cheers,
Jaden Geller

> On Jun 23, 2017, at 3:52 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> There could be source-breaking implications for such a feature, especially 
> with retroactive conformance. Therefore, I think this could be very tricky 
> and I'd want to be convinced that the benefits are very great to risk such a 
> disturbance. Here, I think the problem is rather mild, and here's why:
> 
> It is true that, in your example specifically, renaming T to U is the only 
> solution (that I know of, anyway). However, for any "serious" protocol P, 
> there's likely to be a required property of type P.T, or a function that 
> takes an argument of type P.T or returns a value of type P.T. Therefore, 
> implementing that requirement in Bar with a corresponding 
> property/argument/return value of type Bar.T would generally do the trick.
> 
> Have you got any real-world examples where you're running into this issue?
> 
> On Fri, Jun 23, 2017 at 17:03 David Moore via swift-evolution 
> > wrote:
> Hello Swift Evolution,
> 
> This may have already been discussed before, but I just came across a 
> bothersome language aspect which reminded me to propose a solution. 
> Currently, if we want to add generics to a protocol the only way to do so is 
> with associated types. I am quite fine with the current approach with respect 
> to those semantics.
> 
> There is, however, a weakness that is built in with using associated types. 
> That weakness is the lack of associated type and generic inference. To be 
> more clear about what I mean, take the following as an example.
> 
> protocol Foo {
> associatedtype T
> }
> 
> The foregoing protocol is quite basic, but uses an associated type with the 
> name “T.” Giving the associated type that name will illustrate the dilemma 
> encountered later on down the pipeline.
> 
> struct Bar : Foo {
> // What am I supposed to do? The name is used for both the generic and 
> the type alias Foo needs for conformance.
> typealias T = T // Error!
> }
> 
> The above illustrates a situation where we want to connect the generic, which 
> is supposedly named appropriately, and the protocol’s associated type. There 
> is no elegant solution for this at the moment. All I could do is the 
> following.
> 
> struct Bar : Foo {
> typealias T = U // Not nearly as readable.
> }
> 
> Now, there may be a few ways to go about adding support for generic 
> inference. The compiler as it is already does some awesome inference get when 
> it comes to generics, so why not take it a step further? I propose the 
> introduction of a keyword, or anything else that could work, to specify 
> explicitly what a given type alias declaration would do when it comes to 
> inferencing. Requiring a keyword would ensure source compatibility remains 
> intact, and it would also make the code more readable.
> 
> I don’t know if this would be something that people could find useful, but I 
> surely would. The implicit mapping of an associated type and a given generic 
> by their names, would be a natural development.
> 
> Let me know if this is just useless, or if could be a potential feature.
> 
> Thank you,
> David Moore
> ___
> 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] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-27 Thread Jaden Geller via swift-evolution
I like this idea, but I like idea of treating `Never` as a bottom type more. 
This would allow other `Never`-returning functions like `preconditionFailure` 
to be used as well.

let x = y ?? preconditonFailure("reason")

This also avoids the issue of `!!` needing `file` and `line` arguments.

Cheers,
Jaden Geller

> On Jun 27, 2017, at 10:16 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Using an operator to provide feedback on the context of a failed unwrap has 
> become a commonly implemented approach in the Swift developer Community. What 
> are your thoughts about adopting this widely-used operator into the standard 
> library?
> 
> guard !lastItem.isEmpty else { return }
> let lastItem = array.last !! "Array must be non-empty"
> 
> Details here:  https://gist.github.com/erica/423e4b1c63b95c4c90338cdff4939a9b 
> 
> 
> Thank you for your thoughtful feedback, -- E
> 
> ___
> 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] Sparse (fixed-size) array literal syntax

2017-06-02 Thread Jaden Geller via swift-evolution
Why would this not be possible with fixed sized arrays? Theoretically you could 
create a type that wrapped a fixed array and make it conform to whatever 
protocol you want, including the “ExpressibleBy” protocols.

> On Jun 2, 2017, at 12:22 AM, Daryle Walker  wrote:
> 
>> 
>> On Jun 2, 2017, at 2:11 AM, Jaden Geller > > wrote:
>> 
>> Comments inline.
>> 
>>> On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution 
>>> > wrote:
>>> 
>>> Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or 
>>> linear arrays, but isn’t so great later on when we add fixed-size arrays 
>>> and the defined (non-zero) elements are sparse and/or the array is 
>>> multi-dimensional (not nested). In these cases I’m thinking of leading each 
>>> element with its coordinate:
>>> 
>>> … 6: a, …  // complete value, linear array
>> 
>> You can already do this with a dictionary since a Int can be used as the key 
>> type.
>> 
>>> … (1, 2): b, …  // complete value, multi-dimensional array
>> 
>> This would be possible if tuples of hashable types were considered hahable. 
>> Right now, you could define some point type.
>> 
>>> … (let x, let y) where y % 2 == 0: c * y + x, …  // pattern of qualifying 
>>> coordinates
>> 
>> You can build this sort of thing using an initializer that takes a function. 
>> You wouldn’t get this sugar, but I don’t think it is necessary.
>> 
>>> … default: d, …  // when no other initializer covers an element (Use “_” 
>>> instead?)
>> 
>> This one is a bit harder. I think it would be reasonable for there to exist 
>> some subtype of the dictionary literal type that also included information 
>> about a default value, but I think this should be motivated by the Swift 
>> standard library (e.g. a defaultable dictionary type).
>> 
>> Right now, you can just make literal syntax default to a `nil` default 
>> value, and then you can define a function that nil-coalesces the default 
>> value. This is definitely less elegant, but I don’t think it matters a whole 
>> lot.
>> ```
>> Sparse([1: “foo”, 5: “bar”, 100: “baz”], default: “”)
>> ```
> 
> I’m not asking how to do this in current Swift with current types, but 
> fixed-sized arrays in a future Swift. I’m asking if this mixing of array- and 
> dictionary-literals for these advanced-array literals would be too hard for 
> compiler implementors to implement.
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 

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


Re: [swift-evolution] Sparse (fixed-size) array literal syntax

2017-06-02 Thread Jaden Geller via swift-evolution
I don’t know if you’re aware, but you can extend arbitrary nominal types with 
literal syntax.

```
extension FixedSizedArray: ExpressibleAsDictionaryLiteral { … }
```

Nothing special needs to be done on the implementation side to make this 
possible. If fixed sized arrays are not nominal types (like tuples, unlike 
`Array`s), then you will only be able to give this sugar to types that wrap 
them, not the type itself (w/o special support).

What’s the discussion on enhanced array and dictionary literals? I think I 
missed that.

Cheers,
Jaden Geller

> On Jun 2, 2017, at 1:02 AM, Daryle Walker  wrote:
> 
> 
>> On Jun 2, 2017, at 3:56 AM, Jaden Geller  wrote:
>> 
>> Why would this not be possible with fixed sized arrays? Theoretically you 
>> could create a type that wrapped a fixed array and make it conform to 
>> whatever protocol you want, including the “ExpressibleBy” protocols.
> 
> I DO want it to be possible with future fixed-sized arrays. This is not a 
> user-side question, but implementor-side. I’m asking if the parsing routines 
> for it would conflict with the current array- and dictionary-literal rules, 
> since they will co-exist. If this syntax would make determining whether we 
> have an enhanced array literal or a dictionary literal too hard, then we 
> should change it before anything is finalized.
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 

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


Re: [swift-evolution] Sparse (fixed-size) array literal syntax

2017-06-02 Thread Jaden Geller via swift-evolution
Comments inline.

> On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear 
> arrays, but isn’t so great later on when we add fixed-size arrays and the 
> defined (non-zero) elements are sparse and/or the array is multi-dimensional 
> (not nested). In these cases I’m thinking of leading each element with its 
> coordinate:
> 
> … 6: a, …  // complete value, linear array

You can already do this with a dictionary since a Int can be used as the key 
type.

> … (1, 2): b, …  // complete value, multi-dimensional array

This would be possible if tuples of hashable types were considered hahable. 
Right now, you could define some point type.

> … (let x, let y) where y % 2 == 0: c * y + x, …  // pattern of qualifying 
> coordinates

You can build this sort of thing using an initializer that takes a function. 
You wouldn’t get this sugar, but I don’t think it is necessary.

> … default: d, …  // when no other initializer covers an element (Use “_” 
> instead?)

This one is a bit harder. I think it would be reasonable for there to exist 
some subtype of the dictionary literal type that also included information 
about a default value, but I think this should be motivated by the Swift 
standard library (e.g. a defaultable dictionary type).

Right now, you can just make literal syntax default to a `nil` default value, 
and then you can define a function that nil-coalesces the default value. This 
is definitely less elegant, but I don’t think it matters a whole lot.
```
Sparse([1: “foo”, 5: “bar”, 100: “baz”], default: “”)
```

> 
> A complete coordinate beats a pattern, which beats a default. The issue I see 
> here is that I’m using a colon as a separator between the coordinate 
> expression and the value expression. Would that interfere with dictionary 
> literal syntax? Would it help the we’ll most likely have to demand that the 
> object receiving the literal has to have its type specified (with whatever 
> syntax we agree on), as either a declared object with a type annotation or a 
> function parameter (for a function either without overload or with the 
> variant used otherwise made clear)?
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

Cheers,
Jaden Geller

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


Re: [swift-evolution] [Pitch] Enumerate from offset

2017-05-04 Thread Jaden Geller via swift-evolution
It's been suggested by a core team member that enumerated itself might not hold 
its weight in the standard library. Instead, we ought to write 
`zip(foo.indices, foo)` or `zip(0..., foo)`. It's easier for the caller to see 
which side of the tuple stores the index and whether the index is an integer or 
an actual index type. This use case seems to further support this design since 
`zip(x…, foo)` and `zip(foo.indicies.drop(x), foo)` can be easily written.

> On May 4, 2017, at 8:50 AM, BJ Homer via swift-evolution 
>  wrote:
> 
>> On May 4, 2017, at 8:51 AM, André Videla via swift-evolution 
>>  wrote:
>> 
>> You can do this trivially with drop. But enumerated from has one nice 
>> property:
>> 
>> myArray.enumerated().dropFirst(6) // counts from 6
>> 
>> myArray.dropFirst(6).enumerated() // counts from 0
>> 
>> Those two lines do very different things even though they look similar
> 
> Neither of those does what the proposed enumerated(from:) does, if I 
> understand correctly:
> 
> let a = [1, 2, 3, 4, 5]
> let result = a.enumerated().dropFirst(2)
> /*
>  (offset: 2, element: 3)
>  (offset: 3, element: 4)
>  (offset: 4, element: 5)
> 
>  */
> 
> let result2 = a.dropFirst(2).enumerated()
> /*
>  (offset: 0, element: 3)
>  (offset: 1, element: 4)
>  (offset: 2, element: 5)
>  */
> 
> 
> let proposed = a.enumerated(from: 2)
> /*
>  (offset: 2, element: 1)
>  (offset: 3, element: 2)
>  (offset: 4, element: 3)
>  (offset: 5, element: 4)
>  (offset: 6, element: 5)
>  */
> The enumerated(from:) name is not clear; it reads (to me) like it’s going to 
> enumerate elements starting at the Nth element. What it actually does (as 
> proposed) is start counting at N, instead of counting at 0. 
> 
> I’m not convinced this is a valuable addition to the language. The use cases 
> are not widely applicable, and if you need it it’s easy to get the same 
> results in a way that avoids the confusion.
> 
> let a = [1, 2, 3, 4, 5]
> 
> let result = a.enumerated().map { (idx, element) in
> return (idx+2, element)
> }
> 
> // OR
> 
> for (idx, element) in a.enumerated() {
> let offsetIndex = idx + 2
> // Use offsetIndex how you will
> }
> 
> 
> -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] Replace throws with Result

2017-05-03 Thread Jaden Geller via swift-evolution
To be frank, there’s no way this is happening. The rationale for Swift’s error 
handling is documented 
, and this 
system was designed and implemented *after* optionals already existed in the 
language. I don’t think there’s any evidence that this was a horrible decision, 
especially one that requires a *majorly* source-breaking change to remove.

– Jaden

> On May 3, 2017, at 3:06 AM, Jose Manuel Sánchez Peñarroja via swift-evolution 
>  wrote:
> 
> There is currently a discussion open about throws, but it seems that the idea 
> would be to add optionals to throws. In my opinion it would be much better to 
> just get rid of all the throw error system.
> 
> I think an *Result* type would provide much better error handling 
> than the current solution:
> 
> - It would work just like Optional. We could use ?, ??, map, all those 
> concepts that are already in use. A Result would basically be like a missing 
> value with an error attached. *mapError* could also be added to transform 
> error types to the appropriate value. 
> 
> - We would have a specific error type. Right now throws just returns an 
> *Error*, which is basically a glorified *Any*. Anything can go in there, and 
> it's really hard (or impossible) to know if we are dealing with all the 
> possible options. a Result type would enforce a specific error, so we would 
> gain type safety and we could be sure we are dealing with all the cases.
> 
> - It would simplify everything. We could get rid of *try*, *try?*, *throws*, 
> *rethrows*, *do … catch*.
> 
> - It could be used asynchronously by just passing the *Result* value. Right 
> now there is a different mechanism for handling async and sync calls. The 
> sync calls have all the *throws*, *rethrows*, must be taken care with *try* 
> and *do … catch*, while in a callback you just send the error.
> 
> ___
> 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-0174: Change `filter` to return an associated type

2017-04-28 Thread Jaden Geller via swift-evolution
I think that the alternatives considered section isn’t entirely correct. Even 
if we had a more expressive type system, it would not be possible to make the 
return value of `map` preserve the element type *while* still allowing types 
like `String`, which aren’t parameterized by an element, to conform.

I think this would require two separate mapping protocols (ignore the straw man 
names and syntax):

protocol Mappable: Sequence {
func map(_ transform: (Iterator.Element) -> Iterator.Element) -> Self
// could also add `mapInPlace`
}

protocol MappableFunctor: Mappable {
kind Self
func map(_ transform: (Iterator.Element) -> T) -> Self
}

I think we’d also require either a way for the generic function to conform to 
the non-generic signature if there exists a conforming instantiation if both 
functions were to have the same name.

Also, we’d probably want a way to say that the `T` in the generic signature has 
the same type constraints as the generic parameter would need to…

—

Anyway, the point is that we *could* consider adding the first protocol right 
now (or more likely, add the requirement to `Sequence`) even though the second 
protocol is not possible yet. Even if/when Swift’s type system can handle that, 
the first protocol will still be necessary for types like `String` that cannot 
conform to the second.

Cheers,
Jaden Geller
 
> On Apr 28, 2017, at 5:06 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0174 "Change `filter` to return an associated type" begins 
> now and runs through May 3, 2017. The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0174-filter-range-replaceable.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/0174-filter-range-replaceable.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 Gregor
> 
> 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] [pitch] Comparison Reform

2017-04-26 Thread Jaden Geller via swift-evolution

> On Apr 25, 2017, at 11:50 PM, Jonathan Hull  wrote:
> 
> 
>> On Apr 25, 2017, at 9:34 PM, Jaden Geller > > wrote:
>> 
>>> 
>>> On Apr 25, 2017, at 8:28 PM, Jonathan Hull via swift-evolution 
>>> > wrote:
>>> 
>>> 
 On Apr 25, 2017, at 7:17 PM, Xiaodi Wu > wrote:
 
 I'll refer you to Steve Canon's answer on StackOverflow: 
 http://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values/1573715#1573715
  
 
>>> I get what he is saying about not being able to suddenly change C’s 
>>> definition to the opposite boolean value (even if they would have designed 
>>> it differently for modern systems).  We aren’t C though.  And nil is a 
>>> different name than NaN.  This gives us a way to make a change without 
>>> breaking conformance.
>> 
>> I really like this idea, but it’s not true to say this doesn’t break 
>> IEEE-compliance if what we expose as NaN no longer compares not equal to 
>> itself.
> 
> I would argue that we aren’t actually exposing NaN, so much as we are 
> exposing something which is different, but stays in sync with it.  NaN is 
> still there in the format under the surface, but you wouldn’t be able to 
> access it directly (only indirectly).

The problem is that the IEEE spec requires that certain operations return NaN. 
Either nil is NaN in this model, and we’re breaking the spec for equality, or 
nil is different from NaN in this model, and we’re breaking the spec for when 
NaN should be produced.

> It is a bit of a magic trick.  Whenever the value is NaN, we only let you 
> access ‘.none’ instead of the value.  So, if you were able to directly 
> compare NaN with NaN, it would be false (or unordered), but you can’t get 
> ahold of them to do that comparison.

I don’t find this argument compelling. Again, if it doesn’t act like NaN, it 
isn’t following spec. It doesn’t matter that it has the same bit representation.

> The important thing to me is binary compatibility.  Algorithms need to be 
> rewritten a bit anyway when moving them into swift, so that isn’t a big deal 
> to write it for nil instead of NaN… especially when the compiler helps you 
> due to the optional.  But data, which might contain NaN, needs to be 
> read/written in an interchangeable format.  That is why I suggest having 
> Optional do the lifting to match NaN. Anytime it crosses a boundary which 
> strips the wrapper, it will just work (as long as we import as Double?).

I think this would be a cool idea were it not that so many people are against 
breaking the spec. This trick did work well for UnsafePointer, but the 
circumstances were different.

Anyway, I would be partially in favor of this idea, but I don’t think there’s 
any way the community as a whole is going to be on-board.

 Bottom line is, whatever it's designed for, it's here to stay. I'm *not* 
 on any IEEE committee; I'm not qualified to design an alternative universe 
 of floating point types; and the Swift evolution mailing list (or even 
 Swift itself) is not the place to design one. I and others rely on Swift 
 floating point types to be IEEE-complaint, so that's where we start the 
 discussion here about Comparable.
>>> 
>>> It *is* IEEE compliant (or at least the same amount we currently are), what 
>>> is different is the way we interface with that in code.  You can think of 
>>> Swift Double as a simple (runtime-cost-free) wrapper around the compiler’s 
>>> double that limits how you can touch it (in order to provide additional 
>>> safety guarantees).  Sounds very swifty to me… we do similar things with 
>>> other C constructs using various wrappers.  We aren’t getting rid of NaN 
>>> behind the scenes, just packaging it’s use in a way which aligns with Swift 
>>> as a whole…  What changes is the programer’s mental model. The bits are 
>>> exactly the same.
>>> 
>>> If the naming is what bothers you, we could even just create a “new” Swift 
>>> type that is this wrapper, and then discourage the use of Double outside of 
>>> places where NaN is needed.  I feel like NaN is actually needed in 
>>> relatively few places though…
>>> 
  
 The programmer (mental) model would be that Swift Double just doesn’t have 
 NaN, and anywhere where you would normally return NaN, you return nil 
 instead.
 
 Look, you can already use Double? today. There is no barrier to trying it 
 out for yourself. However, `Double?.none` doesn't mean the same thing as 
 `Double.nan`. The former indicates that _there is no value_; the latter 
 indicates that there _is_ a value, it's just _not a number_. 

Re: [swift-evolution] [pitch] Comparison Reform

2017-04-25 Thread Jaden Geller via swift-evolution

> On Apr 25, 2017, at 8:28 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> 
>> On Apr 25, 2017, at 7:17 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Apr 25, 2017 at 8:38 PM, Jonathan Hull > > wrote:
>> 
>>> On Apr 25, 2017, at 5:25 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Tue, Apr 25, 2017 at 6:53 PM, Jonathan Hull >> > wrote:
>>> I just wanted to ask for more detail on why this is a non-starter (it seems 
>>> like most of my ideas are dismissed as “non-starters”, but I am rarely 
>>> given a detailed reason why).
>>> 
>>> Migration would be a renaming from ‘Double' to ‘Double?’, but it wouldn’t 
>>> be cosmetic.  It would free us to use a non-optional Double, where we can 
>>> guarantee the answer wouldn’t be NaN/nil.  We would, as you say, have 
>>> functions like ‘cos(Double?)->Double?’ which propagate the optional, but we 
>>> could also add a ‘cos(Double)->Double’ overload which guarantees an actual 
>>> result.  For something like Tan, we would only have the optional version 
>>> because the answer may actually be undefined, even when the input isn't.
>>> 
>>> Leave aside how one might implement such a system for a moment. The first 
>>> major issue is that your idea does not address the issues we're talking 
>>> about here:
>>> 
>>> We are debating, for instance, how to compare arrays with elements of type 
>>> `Double`. In your design, the question remains how we would compare arrays 
>>> with elements of type `Double?`. If the answer is that you cannot compare 
>>> arrays of type `[Double?]`, then we have a problem, because that's the type 
>>> that people will use when they ingest data that might contain NaN. Sure, 
>>> they can unwrap each element before using their data, but they can also 
>>> test each element with `isNaN` today. We are trying to *improve* on the 
>>> user experience of comparing arrays of floating point values *without* 
>>> checking if they contain NaN, not trying to take that feature away.
>> 
>> It solves the main problem we are dealing with in Comparable because 
>> defining Comparable on non-optional Double (without possibility of NaN) is 
>> fairly simple.
>> 
>> Yes, but `Double` would not the currency type for floating point work. Since 
>> any input might contain NaN, people will be working pervasively with 
>> `Double?`. Some consideration as to how the type would have to be designed 
>> (I will leave that as an exercise to the reader) would reveal that `Double` 
>> would either have trapping arithmetic operators or no arithmetic operators 
>> at all. Who would use such a type? And for what purpose? No, you've just 
>> pushed the problem from Double to Double?, but the issue is unsolved, and 
>> now we have two types where before we had one.
> 
> Any value of type ‘Double’ would be guaranteed not to contain NaN.  Some 
> things coming in from ObjC land might use ‘Double?', but that is only a 
> single ‘guard let' statement away from ‘Double’. Once you have a Double, you 
> would in most cases get a Double back out. In the event that you do receive a 
> ‘Double?’, you know that you actually do have to deal with the optional case 
> (either through chaining or bailing early in the case of nil).  It enforces 
> proper behavior which would likely be implemented in a buggy way under the 
> current system.
> 
> You would probably have trapping arithmetic for divide by zero, just like 
> Int.  The other option is to return an optional, but you and Dave have 
> previously made strong arguments for trapping.
> 
>  
>> You could compare an array of ‘Double?' in the same way you could compare an 
>> array of ‘Int?’ now.  It would work the same way optionals work everywhere 
>> else.
>> 
>> Right, but again, `Double?` would be the currency type for floating point 
>> work. And you have still not told me how arrays of `Double?` elements would 
>> work. Would two arrays of NaN compare equal? Would two NaNs compare equal? 
>> If NaN == NaN, then we've got a problem. The starting point for this 
>> discussion is that, when working with floating point types, NaN != NaN. It's 
>> required by IEEE standards, and it's relied upon by users.
> 
> ‘Double?' would only be the currency type for interfacing with external 
> (non-swift) code.  Most swift code would still just use Double… and when it 
> requires ‘Double?’, you know you need to deal with the possibility of nil.  
> Right now, NaN is just ignored for the most part… even in some standard 
> library code.
> 
> 
>> You would just test for a lack of numerical result by checking the optional 
>> in the usual Swift way: guard let, if let, etc...
>> 
>> 
>>> Your design also doesn't address the problem of how NaN should compare with 
>>> NaN. Only now, you've pushed the problem to `Optional`. By design, every 
>>> 

Re: [swift-evolution] [pitch] Comparison Reform

2017-04-25 Thread Jaden Geller via swift-evolution
Alternatively, we could introduce a new type `PotentiallyUnknown` that’s kind 
of like `Optional` but has different equality semantics. We’d probably also 
need to introduce a `PartiallyEquatable` (probably the wrong word) protocol too 
though. I don’t think this is really that feasible.

protocol PartiallyEquatable {
static func ==(lhs: Self, rhs: Self) -> Bool?
}

enum PotentiallyUnknown {
case known(T)
case unknown(T)
}

extension PotentiallyUnknown: PartiallyEquatable when T: PartiallyEquatable {
static func ==(lhs: PotentiallyUnknown, rhs: PotentiallyUnknown) -> Bool? {
guard case .known(let l) = lhs, case .known(let r) = rhs else {
return nil
}
return l == r
}
}

I think it’s a novel idea, but I don’t think it would work great in practice.

> On Apr 25, 2017, at 6:38 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> 
>> On Apr 25, 2017, at 5:25 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Apr 25, 2017 at 6:53 PM, Jonathan Hull > > wrote:
>> I just wanted to ask for more detail on why this is a non-starter (it seems 
>> like most of my ideas are dismissed as “non-starters”, but I am rarely given 
>> a detailed reason why).
>> 
>> Migration would be a renaming from ‘Double' to ‘Double?’, but it wouldn’t be 
>> cosmetic.  It would free us to use a non-optional Double, where we can 
>> guarantee the answer wouldn’t be NaN/nil.  We would, as you say, have 
>> functions like ‘cos(Double?)->Double?’ which propagate the optional, but we 
>> could also add a ‘cos(Double)->Double’ overload which guarantees an actual 
>> result.  For something like Tan, we would only have the optional version 
>> because the answer may actually be undefined, even when the input isn't.
>> 
>> Leave aside how one might implement such a system for a moment. The first 
>> major issue is that your idea does not address the issues we're talking 
>> about here:
>> 
>> We are debating, for instance, how to compare arrays with elements of type 
>> `Double`. In your design, the question remains how we would compare arrays 
>> with elements of type `Double?`. If the answer is that you cannot compare 
>> arrays of type `[Double?]`, then we have a problem, because that's the type 
>> that people will use when they ingest data that might contain NaN. Sure, 
>> they can unwrap each element before using their data, but they can also test 
>> each element with `isNaN` today. We are trying to *improve* on the user 
>> experience of comparing arrays of floating point values *without* checking 
>> if they contain NaN, not trying to take that feature away.
> 
> It solves the main problem we are dealing with in Comparable because defining 
> Comparable on non-optional Double (without possibility of NaN) is fairly 
> simple.
> 
> You could compare an array of ‘Double?' in the same way you could compare an 
> array of ‘Int?’ now.  It would work the same way optionals work everywhere 
> else.
> 
> You would just test for a lack of numerical result by checking the optional 
> in the usual Swift way: guard let, if let, etc...
> 
> 
>> Your design also doesn't address the problem of how NaN should compare with 
>> NaN. Only now, you've pushed the problem to `Optional`. By design, every 
>> `Optional.none` compares equal to every other `Optional.none` (yes, 
>> even of different types).
> Yes, the one major difference in behavior, which I mentioned in my earlier 
> email, is that we are replacing NaN != NaN with nil == nil.  Everything else 
> should behave the same.  The part that saves us here, is that Swift forces 
> you to explicitly consider the optional case.
> 
> Basically, I am taking the spirit/intent of the law over the letter of it.  
> As far as I can tell, (quiet) NaN was originally designed to provide the 
> functionality which we use optional for in Swift.  The NaN != NaN thing came 
> out of limitations of the computers in the 1980’s because you needed a way to 
> tell if something was NaN or not (and isNaN() didn’t exist yet).
> 
> The programmer (mental) model would be that Swift Double just doesn’t have 
> NaN, and anywhere where you would normally return NaN, you return nil 
> instead. However, the property of using NaN’s bits to represent nil let’s us 
> inter-op seamlessly with C and ObjC (or any other language’s) code.  They 
> just treat it as a double with NaN as normal (including NaN != NaN) and we 
> interface with it as ‘Double?'
> 
>> This did not always work correctly, if I recall, but it does now and it's an 
>> intentional part of the design. However, NaN must compare not equal to every 
>> NaN. These could not be more different properties. It seems quite absurd on 
>> its face that we might want NaN to compare equal to a value of type 
>> `Optional`.
> 
> Is there an algorithm that requires NaN != NaN that couldn’t be reasonably 
> rewritten to handle 

Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution

> On Apr 24, 2017, at 3:21 PM, Kevin Nattinger  wrote:
> 
> 
>> On Apr 24, 2017, at 3:16 PM, Jaden Geller > > wrote:
>> 
>> 
>>> On Apr 24, 2017, at 2:38 PM, Kevin Nattinger >> > wrote:
>>> 
 
 How can I improve your understanding?
 
>>> 
>>> 
>>> Given the enum I was using earlier:
>>> 
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(T)
>>> }
>>> 
>>> - Write a function that takes a thingOne or thingTwo but 
>>> nothing else.
>> 
>> This isn’t possible since generic types introduced on cases are erased in 
>> the type of `Thing`.
>> 
>> We can actually already achieve what you want by moving the generics onto 
>> the type itself, and this is already possible in Swift! No new features are 
>> necessary.
>> 
>> ```
>> enum Thing {
>> case thingOne(T1)
>> case thingTwo(T2)
>> }
>> 
>> func test(_ x: Thing) {
>> switch x {
>> case .thingOne(let s):
>> print("The string has value \(s)!")
>> case .thingTwo(let i):
>> print("The int has value \(i)!")
>> }
>> }
>> ```
> 
> Yes, that was almost exactly my original example. My understanding of the 
> proposal is that it will remove that capability, which I find completely 
> unacceptable.
> 

Hi Kevin,

If that is what is being proposed, I agree that that is entirely unacceptable. 
I however did not understand the proposal to be removing that capability, but 
instead I understood that it was simply adding another. That is, `Thing` would *still* be accepted. This feature is entirely additive.

It would be great if the original proposal author could confirm this.

Thanks,
Jaden Geller

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


Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution

> On Apr 24, 2017, at 2:38 PM, Kevin Nattinger  wrote:
> 
>> 
>> How can I improve your understanding?
>> 
> 
> 
> Given the enum I was using earlier:
> 
> enum Thing {
> case thingOne(T)
> case thingTwo(T)
> }
> 
> - Write a function that takes a thingOne or thingTwo but nothing 
> else.

This isn’t possible since generic types introduced on cases are erased in the 
type of `Thing`.

We can actually already achieve what you want by moving the generics onto the 
type itself, and this is already possible in Swift! No new features are 
necessary.

```
enum Thing {
case thingOne(T1)
case thingTwo(T2)
}

func test(_ x: Thing) {
switch x {
case .thingOne(let s):
print("The string has value \(s)!")
case .thingTwo(let i):
print("The int has value \(i)!")
}
}
```

> - Declare a variable that can hold a thingOne or thingTwo but 
> nothing else.

With our new definition, we can write:

```
var x: Thing
```

This variable can be initialized with a `thingOne` containing a `String` 
payload or a `thingTwo` containing an `Int` payload.

> Or explain why something that is widely used, trivial to write, and necessary 
> for type safety should be removed from the language.

As I just explained, what you desire is *already possible* in the language. 
This new features does not address your use case. Instead, this feature allows 
for type erasure of enum cases. This is pretty similar to storing an 
existential as a payload. I’m not even sure if it’s sufficiently different to 
justify its addition to the language.

The original non-generic definition of `Thing` with generic cases is 
essentially equivalent to storying `Any` as the case payloads. We can make this 
more useful by using protocols to constrain the payload type.

I think this proposal doesn’t really add any useful new capabilities without 
the ability to constraint the return type. For example, these are nearly 
equivalent:

```
enum Key {
case hashable(T)
case any(T)
}
```

vs.

```
enum Key {
case hashable(AnyHashable)
case any(Any)
}
```

Both of these definitions are nearly equivalent except the former introduces a 
new generic variable in scope when you match on a constrained case. Is this 
useful? I’m not sure. Is it breaking type safety? Absolutely not!! If I match 
the `hashable` case in a switch statement, it’s very similar to if I had 
written a function with the following signature:

```
func matchHashable(_ x: T) { ... }
```

Because of this, no type safety is lost in the switch statement.

—

I think a more interesting version of this proposal would be as follows: Allow 
where constraints and explicit return type annotations on case declarations. 
This is very similar to what a GADT 
 allows you to do. Check out how 
cool this example is—and 110% type-safe!

Below is an example of a data structure representing a computation. We can 
inspect is since it is just data, but we can also evaluate it to see the result.

```
enum Expression {
case value(T)
case isEqual(T, T) -> Expression where T: Equatable
case plus(T, T) -> Expression where T: Numeric
case and(Bool, Bool) -> Expression
case not(Bool) -> Expression
// etc.

func evaluate() -> T {
switch self {
case .value(let x):
return x
case .isEqual(let lhs, let rhs):
// We know that T: Equatable, so we can use `==`
return lhs == rhs
case .plus(let lhs, let rhs):
// We know that T: Numeric, so we can use `+`
return lhs + rhs
case .and(let lhs, let rhs):
return lhs && rhs
case .not(let x):
return !x
}
}
}

let x: Expression = .plus(.value(3), .value(10))
let y: Expression = .plus(.value(7), .value(6))
let z: Expression = .isEqual(x, y)

print(z.evaluate()) // -> true
```

Notice that it is impossible to construct an `Expression` of a nonsensical 
type. Try to do this with the enums we have in Swift today. You’ll have to do 
some force casting of types. Not pretty.

—

I hope I was able to clarify some things for you. Let me know if you have any 
other questions.

Cheers,
Jaden Geller

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


Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution

> On Apr 24, 2017, at 2:33 PM, Joshua Alvarado  
> wrote:
> 
> Hmmm interesting point it would be good to consider this and get to an 
> implementation that helps cover both or just implement the desired feature 
> and in the future add more resiliency. 
> 
> Alvarado, Joshua
> 
> On Apr 24, 2017, at 2:41 PM, Jaden Geller  > wrote:
> 
>> 
>>> On Apr 24, 2017, at 1:34 PM, Joshua Alvarado via swift-evolution 
>>> > wrote:
>>> 
>>> Well in your case thing one and thing two will be the same type as you are 
>>> using the same T generic type on both.
>>> 
>>> To achieve your case you can do an extension on the enum and use two 
>>> different generics:
>>> 
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(U)
>>> }
>>> 
>>> extension Thing where T == String, U == Int {
>>>func handle(thing: Thing) {
>>> switch thing {
>>> case thingOne(let s):
>>> // s is type String
>>> 
>>> case thingTwo(let i):
>>> // i is an Int
>>> }
>>>}
>>> }

I think it’s important to not that the above example (without generic 
information carried with the type) should not be able to provide an extension 
that constrains the type. The problem is that, since we don’t know what `T` and 
`U` actually are for an arbitrary instance at compile-time, we cannot ensure 
that `handle` is not called when `T` and `U` don’t match the extension. We’d 
have to require an implementation of `handle` for every possible type. I guess 
it _could_ be reasonable to allow such a constrained extension if we already 
defined `handle` for any `T` and `U`, but this implementation would probably be 
simple (and equivalent after optimization):

```
enum Thing {
case thingOne(T)
case thingTwo(U)

func handle() {
switch self {
case .thingOne(let s):
if T is String {
// s is of type String
} else {
// default case!
}
case .thingTwo(let i):
if U is Int {
// i is an Int
} else {
// default case!
}
}
}
}
```

Cheers,
Jaden Geller

>>> 
>>> This can actually be achieved in Swift 3.1, you can run this in a 
>>> playground.
>> 
>> This is not quite the same. In the original example, the type information 
>> was thrown away after an instance of type `Foo` was constructed.
>> 
>> Here’s an example that wouldn’t work in your model:
>> 
>> ```
>> enum Whatever {
>> case some(T)
>> }
>> 
>> var x: Whatever = .some(3)
>> x = .some([1, 2, 3])
>> ```
>> 
>> If `Whatever` was generic in `T`, then a variable can only store case 
>> payloads with that specific type. I guess this could be worked around by 
>> introducing a `AnyWhatever` protocol, but still, it’s not an identical 
>> feature.
>> 
>> That said, it might be true that this isn’t actually a desirable feature. We 
>> ought to definitely consider the implications of it and any alternatives. 
>> Thanks for mentioning this, it’s a decent workaround dependent on what you’d 
>> like to accomplish!
>> 
>> Cheers,
>> Jaden Geller
>> 
>>> 
>>> enum Foo {
>>> case bar(obj: T)
>>> case baz(obj: U)
>>> 
>>> func handle() {
>>> switch self {
>>> case .bar(obj: let x):
>>> break
>>> case .baz(obj: let y):
>>> break
>>> }
>>> }
>>> }
>>> 
>>> extension Foo where T == String, U == Int {
>>> func handle() {
>>> switch self {
>>> case .bar(obj: let str):
>>> print(str)
>>> case .baz(obj: let aNum):
>>> print(aNum)
>>> }
>>> }
>>> }
>>> 
>>> let foo = Foo.baz(obj: 1)
>>> foo.handle() // prints 1
>>> 
>>> 
>>> 
>>> On Mon, Apr 24, 2017 at 2:15 PM, Kevin Nattinger >> > wrote:
>>> This makes it more convenient to create them, sure, but how would you pass 
>>> them around or extract the value in a type-safe manner?
>>> 
>>> e.g. now I can write:
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(U)
>>> }
>>> 
>>> // How do I require thingOne or thingTwo?
>>> func handle(thing: Thing) {
>>> switch thing {
>>> case .thingOne(let s): print("string \(s)")
>>> case .thingTwo(let i): print("int \(i)")
>>> }
>>> }
>>> 
>>> With your proposed syntax:
>>> 
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(T)
>>> }
>>> 
>>> func handle(thing: Thing) {
>>> switch thing {
>>> case thingOne(let s):
>>> // What is the type of s?
>>> case thingTwo(let i):
>>> // is it even possible to write an exhaustive switch?
>>> }
>>> }
>>> 
>>> 
>>> 
 On Apr 24, 2017, at 6:57 AM, Joshua Alvarado via swift-evolution 
 

Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution


> On Apr 24, 2017, at 2:09 PM, Kevin Nattinger  wrote:
> 
> 
>>> On Apr 24, 2017, at 1:36 PM, Jaden Geller  wrote:
>>> 
>>> 
>>> On Apr 24, 2017, at 1:15 PM, Kevin Nattinger via swift-evolution 
>>>  wrote:
>>> 
>>> This makes it more convenient to create them, sure, but how would you pass 
>>> them around or extract the value in a type-safe manner?
>> 
>> If the case introduces a generic type, than the switching over that case 
>> introduces a generic type variable in that scope.
> 
> I don’t want a generic type, I want to be able to specify exactly what types 
> the function accepts. 

Generic cases are exactly what I understand to be proposed. Can you explain how 
what you're looking for differs?

> 
>> 
>>> 
>>> e.g. now I can write:
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(U)
>>> }
>>> 
>>> // How do I require thingOne or thingTwo?
>>> func handle(thing: Thing) {
>>> switch thing {
>>> case .thingOne(let s): print("string \(s)")
>>> case .thingTwo(let i): print("int \(i)")
>>> }
>>> }
>>> 
>>> With your proposed syntax:
>>> 
>>> enum Thing {
>>> case thingOne(T)
>>> case thingTwo(T)
>>> }
>>> 
>>> func handle(thing: Thing) {
>>> switch thing {
>>> case thingOne(let s):
>>> // What is the type of s?
>> 
>> It is some new generic variable `T`. It might be best to require that it is 
>> explicitly introduced:
>> ```
>> case thingOne(let s):
>> ```
>> You could use `s` like you could use `x` in `func (x: T) { … }`. That’s 
>> to say that you couldn’t do much with it. You could store it in an `Any`. 
>> You could dynamically check the type. You could ignore it. You could print 
>> it.
> 
> So what good is a value I can’t do anything with?

It's not particularly useful BECAUSE you didn't specify any generic 
constraints. Just like a generic function, you can only do with a value what 
it's constraints allow.

> 
>> 
>> It becomes a lot more useful when there are constraints on `T` in the 
>> original case definition of the type. For example, if `case thingOne> FloatingPoint>(T)` were written in the original enum definition, you could 
>> do anything with `s` that you could do with a `FloatingPoint`.
>> 
>>> case thingTwo(let i):
>>> // is it even possible to write an exhaustive switch?
>> 
>> Sure, but this switch isn’t yet exhaustive. You’d also have to add another 
>> case:
>> ```
>> case thingTwo(let i):
>> ```
> 
> In my original code, the function specifies exactly what it can handle, and 
> that restriction is enforced by the compiler. Do

Your switch statement wasn't exhaustive. You need to add an additional case 
that handles a T that isn't an Int (because it might not be one)! Swift cannot 
statically know the payload since it isn't part of the type. The case generics 
are erased, and you need to use case matching to bring them back.

> you really think it would be an improvement to remove compile-time type 
> restrictions? We may as well get rid of the type system and duck-type like 
> python. At least that would speed up type-inference bottlenecks.

That's entirely not what I advocated. I don't appreciate you strawmanning my 
explanation.

The model I explained is consistent with Swift's current type checking. It 
certainly does not remove any restrictions or add duck typing.

How can I improve your understanding?

> 
>> When we do come back to this proposal, it might be reasonable to leave these 
>> sorts of specializations (e.g. `case thingTwo`) out of the initial 
>> design since they might significantly complicate the model and they are 
>> entirely additive. I’m not sure though, I’m not familiar with the 
>> implementation.
>> 
>>> }
>>> }
>>> 
>> 
>> I’d really love to see GADTs in Swift, even if in a more limited form! 
>> Another GADT feature that would be nice to add (though probably would 
>> deserve a separate, later proposal) would be specialized generic return 
>> types for each case:
>> 
>> ```
>> enum Expr {
>> case value(T) -> Expr
>> case plus(Expr, Expr) -> Expr
>> case and(Expr, Expr) -> Expr
>> case equals(Expr, Expr) -> Expr where T: Equatable
>> }
>> ```
>> 
>> But ya, I realize this is a very major complication of the model… Would be 
>> so cool though!
>> 
>> This is all definitely out of scope for Swift 4, and likely out of scope for 
>> Swift 5 even… I guess we’ll find out once we get there. Still fun to think 
>> about!
>> 
>> Cheers,
>> Jaden Geller
>> 
>>> 
>>> 
 On Apr 24, 2017, at 6:57 AM, Joshua Alvarado via swift-evolution 
  wrote:
 
 Here is my pitch on adding generics to enum cases and not to the enum type 
 itself. Let me know if you have an improvements or modifications lets open 
 it to discussion thank you swiftys! :)
 
 Enum with generic cases
 
 Proposal: SE-
 Authors: Joshua Alvarado

Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution

> On Apr 24, 2017, at 1:34 PM, Joshua Alvarado via swift-evolution 
>  wrote:
> 
> Well in your case thing one and thing two will be the same type as you are 
> using the same T generic type on both.
> 
> To achieve your case you can do an extension on the enum and use two 
> different generics:
> 
> enum Thing {
> case thingOne(T)
> case thingTwo(U)
> }
> 
> extension Thing where T == String, U == Int {
>func handle(thing: Thing) {
> switch thing {
> case thingOne(let s):
> // s is type String
> 
> case thingTwo(let i):
> // i is an Int
> }
>}
> }
> 
> This can actually be achieved in Swift 3.1, you can run this in a playground.

This is not quite the same. In the original example, the type information was 
thrown away after an instance of type `Foo` was constructed.

Here’s an example that wouldn’t work in your model:

```
enum Whatever {
case some(T)
}

var x: Whatever = .some(3)
x = .some([1, 2, 3])
```

If `Whatever` was generic in `T`, then a variable can only store case payloads 
with that specific type. I guess this could be worked around by introducing a 
`AnyWhatever` protocol, but still, it’s not an identical feature.

That said, it might be true that this isn’t actually a desirable feature. We 
ought to definitely consider the implications of it and any alternatives. 
Thanks for mentioning this, it’s a decent workaround dependent on what you’d 
like to accomplish!

Cheers,
Jaden Geller

> 
> enum Foo {
> case bar(obj: T)
> case baz(obj: U)
> 
> func handle() {
> switch self {
> case .bar(obj: let x):
> break
> case .baz(obj: let y):
> break
> }
> }
> }
> 
> extension Foo where T == String, U == Int {
> func handle() {
> switch self {
> case .bar(obj: let str):
> print(str)
> case .baz(obj: let aNum):
> print(aNum)
> }
> }
> }
> 
> let foo = Foo.baz(obj: 1)
> foo.handle() // prints 1
> 
> 
> 
> On Mon, Apr 24, 2017 at 2:15 PM, Kevin Nattinger  > wrote:
> This makes it more convenient to create them, sure, but how would you pass 
> them around or extract the value in a type-safe manner?
> 
> e.g. now I can write:
> enum Thing {
> case thingOne(T)
> case thingTwo(U)
> }
> 
> // How do I require thingOne or thingTwo?
> func handle(thing: Thing) {
> switch thing {
> case .thingOne(let s): print("string \(s)")
> case .thingTwo(let i): print("int \(i)")
> }
> }
> 
> With your proposed syntax:
> 
> enum Thing {
> case thingOne(T)
> case thingTwo(T)
> }
> 
> func handle(thing: Thing) {
> switch thing {
> case thingOne(let s):
> // What is the type of s?
> case thingTwo(let i):
> // is it even possible to write an exhaustive switch?
> }
> }
> 
> 
> 
>> On Apr 24, 2017, at 6:57 AM, Joshua Alvarado via swift-evolution 
>> > wrote:
>> 
>> Here is my pitch on adding generics to enum cases and not to the enum type 
>> itself. Let me know if you have an improvements or modifications lets open 
>> it to discussion thank you swiftys! :)
>> 
>> Enum with generic cases
>> 
>> Proposal: SE- 
>> 
>> Authors: Joshua Alvarado 
>> Review Manager: TBD
>> Status: PITCH
>> During the review process, add the following fields as needed:
>> 
>> Decision Notes: Rationale 
>> , Additional Commentary 
>> 
>> Bugs: SR- , SR- 
>> 
>> Previous Revision: 1 
>> 
>> Previous Proposal: SE- 
>> 
>>  
>> Introduction
>> 
>> This proposal adds a change to the enumeration type that allows an enum case 
>> to cast a generic on its associated value.
>> 
>> Swift-evolution thread: Discussion thread topic for that proposal 
>> 
>>  
>> Motivation
>> 
>> Enums currently support generics, but they are added onto the type itself. 
>> This can cause adverse syntax when implementing generics for associated 
>> values to be stored along each case. The enum case holds the associated 
>> value (not the enum type itself) so should create its own value constraints.
>> 
>>  
>> 

Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution

> On Apr 24, 2017, at 1:15 PM, Kevin Nattinger via swift-evolution 
>  wrote:
> 
> This makes it more convenient to create them, sure, but how would you pass 
> them around or extract the value in a type-safe manner?

If the case introduces a generic type, than the switching over that case 
introduces a generic type variable in that scope.

> 
> e.g. now I can write:
> enum Thing {
> case thingOne(T)
> case thingTwo(U)
> }
> 
> // How do I require thingOne or thingTwo?
> func handle(thing: Thing) {
> switch thing {
> case .thingOne(let s): print("string \(s)")
> case .thingTwo(let i): print("int \(i)")
> }
> }
> 
> With your proposed syntax:
> 
> enum Thing {
> case thingOne(T)
> case thingTwo(T)
> }
> 
> func handle(thing: Thing) {
> switch thing {
> case thingOne(let s):
> // What is the type of s?

It is some new generic variable `T`. It might be best to require that it is 
explicitly introduced:
```
case thingOne(let s):
```
You could use `s` like you could use `x` in `func (x: T) { … }`. That’s to 
say that you couldn’t do much with it. You could store it in an `Any`. You 
could dynamically check the type. You could ignore it. You could print it.

It becomes a lot more useful when there are constraints on `T` in the original 
case definition of the type. For example, if `case thingOne(T)` were written in the original enum definition, you could do 
anything with `s` that you could do with a `FloatingPoint`.

> case thingTwo(let i):
> // is it even possible to write an exhaustive switch?

Sure, but this switch isn’t yet exhaustive. You’d also have to add another case:
```
case thingTwo(let i):
```
When we do come back to this proposal, it might be reasonable to leave these 
sorts of specializations (e.g. `case thingTwo`) out of the initial design 
since they might significantly complicate the model and they are entirely 
additive. I’m not sure though, I’m not familiar with the implementation.

> }
> }
> 

I’d really love to see GADTs in Swift, even if in a more limited form! Another 
GADT feature that would be nice to add (though probably would deserve a 
separate, later proposal) would be specialized generic return types for each 
case:

```
enum Expr {
case value(T) -> Expr
case plus(Expr, Expr) -> Expr
case and(Expr, Expr) -> Expr
case equals(Expr, Expr) -> Expr where T: Equatable
}
```

But ya, I realize this is a very major complication of the model… Would be so 
cool though!

This is all definitely out of scope for Swift 4, and likely out of scope for 
Swift 5 even… I guess we’ll find out once we get there. Still fun to think 
about!

Cheers,
Jaden Geller

> 
> 
>> On Apr 24, 2017, at 6:57 AM, Joshua Alvarado via swift-evolution 
>> > wrote:
>> 
>> Here is my pitch on adding generics to enum cases and not to the enum type 
>> itself. Let me know if you have an improvements or modifications lets open 
>> it to discussion thank you swiftys! :)
>> 
>> Enum with generic cases
>> 
>> Proposal: SE- 
>> 
>> Authors: Joshua Alvarado 
>> Review Manager: TBD
>> Status: PITCH
>> During the review process, add the following fields as needed:
>> 
>> Decision Notes: Rationale 
>> , Additional Commentary 
>> 
>> Bugs: SR- , SR- 
>> 
>> Previous Revision: 1 
>> 
>> Previous Proposal: SE- 
>> 
>>  
>> Introduction
>> 
>> This proposal adds a change to the enumeration type that allows an enum case 
>> to cast a generic on its associated value.
>> 
>> Swift-evolution thread: Discussion thread topic for that proposal 
>> 
>>  
>> Motivation
>> 
>> Enums currently support generics, but they are added onto the type itself. 
>> This can cause adverse syntax when implementing generics for associated 
>> values to be stored along each case. The enum case holds the associated 
>> value (not the enum type itself) so should create its own value constraints.
>> 
>>  
>> Proposed
>>  solution
>> 
>> The generic is to be casted on the case of the enum and not on the enum 
>> itself.
>> 
>>  
>> 

Re: [swift-evolution] [Pitch] Enum with generic cases

2017-04-24 Thread Jaden Geller via swift-evolution
I think the pattern match would have to introduce a new generic type variable 
within the match scope. Definitely not a simple feature, but GADTs would be so 
cool!

> On Apr 24, 2017, at 7:57 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> This is somehow similar to 
> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generic-constants.
> 
> Question, will pattern matching still work fine with that? I kinda fear that 
> this won’t work in a different scopes, but feel free to prove me being wrong.
> 
> enum Foo {
> case bar(obj: T)
> case baz(obj: U)
> }
> 
> struct Test {
>  
> var foo: Foo = .bar(obj: "swift")
>  
> func test() {
>  
> switch self.foo {
> case /* Check for `bar` and String */: …
> case /* How to pattern match against `baz`? What is `U`? */: …
>  
> // Do we need `default` everytime?
> }
> }
> }
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 24. April 2017 um 15:57:33, Joshua Alvarado via swift-evolution 
> (swift-evolution@swift.org) schrieb:
> 
>> Here is my pitch on adding generics to enum cases and not to the enum type 
>> itself. Let me know if you have an improvements or modifications lets open 
>> it to discussion thank you swiftys! :)
>> Enum with generic cases
>> Proposal: SE-
>> Authors: Joshua Alvarado
>> Review Manager: TBD
>> Status: PITCH
>> During the review process, add the following fields as needed:
>> 
>> Decision Notes: Rationale, Additional Commentary
>> Bugs: SR-, SR-
>> Previous Revision: 1
>> Previous Proposal: SE-
>> Introduction
>> 
>> This proposal adds a change to the enumeration type that allows an enum case 
>> to cast a generic on its associated value.
>> 
>> Swift-evolution thread: Discussion thread topic for that proposal
>> 
>> Motivation
>> 
>> Enums currently support generics, but they are added onto the type itself. 
>> This can cause adverse syntax when implementing generics for associated 
>> values to be stored along each case. The enum case holds the associated 
>> value (not the enum type itself) so should create its own value constraints.
>> 
>> Proposed solution
>> 
>> The generic is to be casted on the case of the enum and not on the enum 
>> itself.
>> 
>> Detailed design
>> 
>> Current implementation:
>> 
>> // enum with two generic types
>> enum Foo {
>> case bar(obj: T)
>> case baz(obj: U)
>> }
>> 
>> // U is to be casted but it is not even used
>> let foo: Foo = .bar(obj: "hash")
>> 
>> // Creating an optional enum, the generics have to be casted without a value 
>> set
>> // The casting is really not needed as the values should be casted not the 
>> enum
>> var foo1: Foo?
>> 
>> // Collections don’t look great either
>> var foos = [Foo]()
>> foos.append(.bar(obj:"hash"))
>> Proposed solution
>> 
>> enum Foo {
>> case bar(obj: T)
>> case baz(obj: U)
>> }
>> 
>> // generic type inferred on T
>> var foo: Foo = .bar(obj: "hash")  
>> 
>> // doesn’t need to cast the generic on the optional enum
>> // the associated value will hold the cast
>> var foo1: Foo?  
>> 
>> // This also gives better syntax with collections of enums with associated 
>> types
>> var foos = [Foo]()
>> foos.append(.bar(obj: "hey")
>> Source compatibility
>> 
>> This may cause subtle breaking changes for areas in code with generic enum 
>> cases. The compiler could help with the change by finding the associated 
>> generic and updating the case with the new syntax.
>> 
>> Alternatives considered
>> 
>> An alternative would be to extend the associatedtype keyword to the enum 
>> type.
>> 
>> enum Foo {
>> associatedtype T = Hashable
>> case bar(obj: T)
>> }
>> 
>> Copy of proposal can be found here Swift proposal on github
>> 
>> --
>> Joshua Alvarado
>> alvaradojosh...@gmail.com
>> ___
>> 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] SE-0171: Reduce with inout

2017-04-17 Thread Jaden Geller via swift-evolution

> On Apr 17, 2017, at 2:37 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Apr 16, 2017, at 12:47 AM, Dave Abrahams via swift-evolution 
>> > wrote:
>> 
>> 
>> on Fri Apr 14 2017, Matthew Johnson > > wrote:
>> 
 On Apr 14, 2017, at 9:05 PM, David Sweeris > wrote:
 
 
> On Apr 14, 2017, at 15:33, Matthew Johnson via swift-evolution 
> > wrote:
> 
> 
>>  • What is your evaluation of the proposal?
> 
> +0.5 because this is a half solution.  I would also like to see a
> variant which accepts an inout argument for the reduction to
> accumulate into.
 
 Out of curiosity, do you have any particular use case in mind, or do
 you just think that'd nicely "round out" the reduce functions (which
 would be fine with me).
>>> 
>>> This would be useful in any use case that involves reducing data that
>>> isn’t all available at the same time for one reason or another
>>> (batches arrive periodically, data is processed in chunks to avoid
>>> loading everything into memory, etc).
>>> 
>>> IMO the most fundamental variation of `reduce` Swift could offer is
>>> the one that takes and `inout` accumulator.  The others can easily be
>>> defined in terms of that.
>> 
>> It should work to do this:
>> 
>>  existingAccumulator = reduce(into: existingAccumulator) { ... }
>> 
>> If reduce is inlined, ARC is doing its job right, and the closure isn't
>> throwing, it shouldn't even cost a copy of existingAccumulator.
>> 
>> If you have a heaviweight accumulator with value semantics and ARC
>> isn't cutting it for you, you can do this ugly thing instead.
>> 
>>  extension Optional {
>>mutating func release() -> Wrapped {
>>  defer { self = nil }
>>  return self!
>>}
>>  }
>> 
>>  var accumulator: AccumulatorType? = AccumulatorType()
>>  accumulator = reduce(into: accumulator.release()) { ... }
>> 
>> but then you lose the accumulator if the closure throws.  So, I guess
>> I'm agreeing with you that the version with the inout accumulator is
>> more fundamental.
> 
> Even if this would work I don’t think it’s a great option.  Accepting an 
> inout accumulator is a far more straightforward programming model with clear 
> performance semantics that don’t require detailed implementation knowledge.
> 
>> 
>> But that's not the only criterion.  Is it as useful and commonly
>> convenient?  
> 
> I would say it is commonly useful.  When it is required it is as convenient 
> as possible.  When an inout accumulator is not required it is admittedly 
> somewhat less convenient.
> 
> Whether it is *as* useful and convenient as the proposed variation probably 
> depends on the domain.  Each has their strength with the proposed version 
> probably being a bit more frequently desired.
> 
>> If we were to have both versions, how would you name them?
> 
> This is a tough question.  The proposed `into:` label makes sense for both 
> the inout accumulator and the proposed variation but I’ll assume overloading 
> won’t be considered for the reasons stated in the proposal.  `intoCopyOf:` 
> would make sense for the proposed copying variation but would penalize it 
> with verbosity and doesn’t copy reference types despite implying that. 

It seems to me that it isn’t problematic to overload with an `inout` variant. 
It is always clear to the compiler which to choose based on the presence or 
lack of a `&` character.

> The `mutating:` label described in the alternatives considered section of the 
> proposal might might be the best option.  One downside would be if the 
> difference between `into:` and `mutating:` isn't sufficiently clear.  Given 
> that both the types *and* the labels distinct I think it’s probably ok.  The 
> second potential source of confusion would be if using `mutating:` as a label 
> might cause some confusion with mutating methods.  Again, a quick glance at 
> the types reveals that the method is not mutating and the accumulator 
> argument is taken as inout.
> 
> What is your thought on using the `into` for the proposed variation and 
> `mutating` for the variation with an inout accumulator?
> 
>> 
>> -- 
>> -Dave
>> 
>> ___
>> 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

Cheers,
Jaden Geller

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [Proposal] Nested extensions

2017-04-14 Thread Jaden Geller via swift-evolution
This proposal definitely needs to be more detailed, but I think I would be +1 
on the idea.

---

Use cases:

1) Extending nested types

// currently possible:
extension Foo.Bar {
  // must qualify some names with Foo
}

// could be possible:
extension Foo {
  extension Bar {
// everything in Foo is in scope
  }
}

2) Anonymous extensions

// stretch feature:
func foo() {
  extension Array {
// helpers used inside function
  }
}

---

Cheers,
Jaden Geller

> On Apr 14, 2017, at 2:40 AM, Tino Heth via swift-evolution 
>  wrote:
> 
> 
> 
>  
> Introduction
> 
> By removing the restriction that extensions can only be used as top-level 
> declarations, this important feature of Swift could become more powerful and 
> solve issues some users have with access control.
> 
> Swift-evolution thread: Enhancing access levels without breaking changes 
> 
>  
> Motivation
> 
> Currently, access control is a very hot topic for Swift, and all of the 
> options discussed so far had strong resistance from different parts of the 
> community.
> 
> This concept tries to avoid all objections that were raised against the 
> various modells (of course, it triggers fresh ones at the same time ;-), and 
> because it is purely additive, it removes the pressure to address the current 
> issues in Swift 4. Although it wasn't a motivation, the proposal also offers 
> an answer to the question if (and how) properties should be allowed in 
> extensions.
> 
> SE-0169 would render major parts of this idea useless, so I think it's 
> qualified to be discussed in this stage.
> 
> 
>  
> Proposed
>  solution
> 
> Simply remove the restriction that extensions can only be declared on 
> top-level of a file.
> 
> 
>  
> Detailed
>  design
> 
> There isn't much to add here: Extensions should be allowed in type 
> declarations and other extensions (I'm skipping methods in this draft - I see 
> neither big problems associated with extensions declared inside methods, nor 
> convincing use cases for them).
> 
> The rules should be the same as for nested types, so marking a member of an 
> extension private would restrict its visiblity to the scope of this extension.
> 
> The goals of SE-0169 could be achieved in this model by simply putting an 
> extension inside a type declaration, while keeping private members protected.
> 
> Nested extensions should also be allowed to contain stored properties of the 
> enclosing class, thus enabling better visibility management for those as well:
> 
> Stored properties in extensions have been requested before, but this approach 
> enables them quite naturally, as the rule that you can only declare stored 
> properties inside the declaration of a type is respected.
> 
> It would also be possible to levearage the "default access level" feature of 
> extensions to group properties that should have the same visibility.
> 
> Because there is no natural limit of nesting extensions, this feature enables 
> developers to design more sophisticated systems of access rights, without 
> increasing Swifts complexity for users that are happy with 
> "puplic-internal-private" and don't see the need for additional keywords or 
> other changes in the language.
> 
> 
>  
> Future
>  enhancements
> 
> For extensions of an enclosing type, that type could be easily inferred, so 
> some repetition could be eliminated easily.
> 
> 
>  
> Source
>  compatibility
> 
> Purely additive
> 
> 
>  
> Effect
>  on ABI stability
> 
> There are some pitfalls associated with ABI, but I don't think its stability 
> would be affected.
> 
> 
>  
> Effect
>  on API resilience
> 
> Nono known
> 
> 
>  
> Alternatives
>  considered
> 
> SE-0169, SE-0159, renaming "fileprivate" and/or "private"
> 
> All of those possibilities have their own strengths and weaknesses, and there 
> is a huge dissent which of those are important: No matter which would be 
> choosen, at least one group of Swift users is punished.
> 
> 

Re: [swift-evolution] [pitch] Comparison Reform

2017-04-13 Thread Jaden Geller via swift-evolution
Oh, I definitely overlooked that part. Thanks for that clarification! I had 
assumed the compiler changes were only necessary for allowing circular default 
implementations while still requiring at least one requirement be implemented.

That said, it’s possible to implement something very, very similar without 
compiler changes:
https://gist.github.com/JadenGeller/7566b3b64b5597ee57e8a509f6fc4bb3#file-context-swift-L43
 


Cheers,
Jaden Geller

> On Apr 13, 2017, at 5:58 PM, Xiaodi Wu  wrote:
> 
> Jaden, the proposal literally says that a compiler feature named 
> "@_implements" is necessary for the proposed design to work. You can see WIP 
> for that feature in the apple/swift repo.
> 
> 
> On Thu, Apr 13, 2017 at 19:55 Jaden Geller  > wrote:
> 
>> On Apr 13, 2017, at 5:18 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> Actually, the fact that this behavior cannot even be achieved without 
>> currently non-existent compiler features means that it is not possible to 
>> understand what's truly going on without reading *this document*, after 
>> mastering *both* IEEE floating point *and* Swift 
>> generics/protocols/extensions/static vs. dynamic dispatch. All to use `==` 
>> correctly. Which is to say, most people will simply not even know if they 
>> happen to be using the `==` they did not intend to use.
>> 
> 
> If I understand correctly, I think you’re mistaken. The compiler already 
> selects overloads based on generic context. If `T: FloatingPoint`, then it’ll 
> choose the `==` with signature ` (T, T) -> Bool`. If `T: 
> Equatable`, then it’ll choose the `==` with signature ` (T, T) 
> -> Bool`. No new compiler features are necessary for this specific behavior.
> 
> Cheers,
> Jaden Geller

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


Re: [swift-evolution] [pitch] Comparison Reform

2017-04-13 Thread Jaden Geller via swift-evolution
> 
> On Apr 13, 2017, at 3:23 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Apr 13, 2017, at 4:17 PM, Ben Cohen via swift-evolution 
>> > wrote:
>> ComparisonResult Conveniences
>> 
>> There are a few conveniences we could consider providing to make 
>> ComparisonResult more ergonomic to manipulate. Such as:
>> 
>> // A way to combine orderings
>> func ComparisonResult.breakingTiesWith(_ order: () -> ComparisonResult) -> 
>> ComparisonResult
>> 
>> array.sort {
>>   $0.x.compare($0.y)
>>   .breakingTiesWith { $0.y.compare($1.y) }
>>   == .orderedAscending 
>> }
> 
> The really nice thing about compare being an operator is that you can very 
> nicely combine it with an operator here and get a much more light-weight 
> syntax for chained comparisons, e.g.:
> 
> struct MyPoint : Comparable {
>   var x, y, z: Double
>   func compare(_ other: MyPointer) -> ComparisonResult {
> return self.x <=> other.x || self.y <=> other.y || self.z <=> other.z

Wow, this is elegant!

>   }
> }
> 
> as opposed to, I guess,
>   return self.x.compare(other.x).breakingTiesWith { 
> self.y.compare(other.y).breakingTiesWith { self.z.compare(other.z) } }
> 
> But this is mostly useful for defining custom comparisons, so perhaps it's 
> not worth having to paint a bikeshed for <=> and whatever the combining 
> operator is.

For the record, I would strongly prefer `<=>` to an instance `compare` method. 
That said, I’d also prefer a static `compare` function to the asymmetric 
instance method if the spelling `compare` were absolutely desired.

It’s probably worth noting somewhere that an instance `compare` method performs 
dynamic dispatch on the left-hand argument while a static function (as well as 
the current operators `==` and `<`) perform static dispatch. I realize NSObject 
set a precedent with `isEqual:` and `compare:` instance methods, but I’m not 
convinced that’s necessarily the best design. If dynamic dispatch is desired, 
an implementation can always delegate to such a method.

> 
> Also, in this example:
>> // A way to combine orderings
>> func ComparisonResult.breakingTiesWith(_ order: () -> ComparisonResult) -> 
>> ComparisonResult
>> 
>> array.sort {
>>   $0.x.compare($0.y)
>>   .breakingTiesWith { $0.y.compare($1.y) }
>>   == .orderedAscending 
>> }
> Requiring this last "== .orderedAscending" seems like a tragic failure of 
> ergonomics.  I understand that sorting doesn't actually require a tri-valued 
> comparison, but is it really worth maintaining two currencies of comparison 
> result over that?  Are there any types that can answer '<' substantially more 
> efficiently than they can answer 'compare'?  And I assume this is related to 
> why you've kept < in the protocol.

I would strongly support replacing (T, T) -> Bool with (T, T) -> 
ComparisonResult variants.

The areInIncreasingOrder variant is confusing at the call-site since the 
definition must be consulted to determine which order the comparison expects.
The areInIncreasingOrder implementation is very dirty when an == result is 
desired. This is especially bad if we expect other authors to mirror this API:
if !areInIncreasingOrder(a, b) && !areInIncreasingOrder(b, a) {
  // equal!
}
Not only is this unintuitive, but it is also less performant in many cases.

> 
> John.
> ___
> 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] Comparison Reform

2017-04-13 Thread Jaden Geller via swift-evolution

> On Apr 13, 2017, at 5:18 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Actually, the fact that this behavior cannot even be achieved without 
> currently non-existent compiler features means that it is not possible to 
> understand what's truly going on without reading *this document*, after 
> mastering *both* IEEE floating point *and* Swift 
> generics/protocols/extensions/static vs. dynamic dispatch. All to use `==` 
> correctly. Which is to say, most people will simply not even know if they 
> happen to be using the `==` they did not intend to use.
> 

If I understand correctly, I think you’re mistaken. The compiler already 
selects overloads based on generic context. If `T: FloatingPoint`, then it’ll 
choose the `==` with signature ` (T, T) -> Bool`. If `T: 
Equatable`, then it’ll choose the `==` with signature ` (T, T) -> 
Bool`. No new compiler features are necessary for this specific behavior.

Cheers,
Jaden Geller___
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-11 Thread Jaden Geller via swift-evolution

> On Apr 7, 2017, at 4:07 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 07.04.2017 10:21, 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?
> 
> Although it seems like only an implementation-side problem(i.e. "let's just 
> improve implementation"), I see a benefits to require type for stored 
> property *if* it is not obvious what the type is for *reader*. I.e. if we 
> have something like this, I don't think we should require a type:
> struct S {
>  var x = 0
> }

I think there is value in requiring a type annotation there. For example, this 
bug would be avoided: https://twitter.com/benjaminencz/status/851892622213783552

> 
> but I do think it will be better to require a type in such cases :
> 
> struct S{
>  var x = something(SomeType(), 123, "123") // can be generic func
> }
> 
> 
> 
>> 
>> 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 
> 
___
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 Jaden Geller via swift-evolution
This will not always work, particularly when both symbols already have an 
identical type. 

> On Mar 26, 2017, at 1:29 AM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> I think this is where some special behavior in the migrator is called for. 
> Where an overload ambiguity appears, it will need to insert an "as T" to 
> disambiguate.
> 
> Carl's standard can be strictly met by a migrator that compares all uses of 
> private facilities under the new and old meaning of private, ensuring that no 
> uses emerge or disappear after rollback.
>> On Sun, Mar 26, 2017 at 03:23 Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> 
>> On Mar 25, 2017, at 10:54 PM, John McCall via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>>>> On Mar 25, 2017, at 2:11 AM, Carl Brown1 via swift-evolution 
>>>> <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.
>> 
>> What about overloads that become ambiguous? I admit this is a fringe case.
>> 
>>> 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.
>>> 
>>> 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 <xiaodi...@gmail.com>
>>>> To: Carl Brown1/US/IBM@IBM
>>>> Cc: Drew Crawford <d...@sealedabstract.com>, Jonathan Hull 
>>>> <jh...@gbis.com>, swift-evolution <swift-evolution@swift.org>
>>>> 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 <carl.bro...@ibm.com> 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 <carl.bro...@ibm.com> wrote: > Maybe this is the core
>>>> 
>>>> From: Xiaodi Wu <xiaodi...@gmail.com>
>>>> To: Carl Brown1/US/IBM@IBM
>>>> Cc: Drew Crawford <d...@sealedabstract.com>, Jonathan Hull 
>>>> <jh...@gbis.com>, swift-evolution <swift-evolution@swift.org>
>>>> 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 <carl.bro...@ibm.com> wrote:
>>>> My point is that, in rolling back the specific portion of SE-0025, 
>>>> case-sensitive find-and-replace will be the trickiest thing in most 
>>>> codebases, save those that result in invalid redeclarations. The behavior 
>>>> of the resultant code is, unless I'm mistaken, provably unchanged.
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> ___
>>>> 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] [Review] SE-0159: Fix Private Access Levels

2017-03-26 Thread Jaden Geller via swift-evolution


> On Mar 25, 2017, at 10:54 PM, 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.

What about overloads that become ambiguous? I admit this is a fringe case.

> 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.
> 
> 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 portion of SE-0025, 
>> case-sensitive find-and-replace will be the trickiest thing in most 
>> codebases, save those that result in invalid redeclarations. The behavior of 
>> the resultant code is, unless I'm mistaken, provably unchanged.
>> 
>> 
>> 
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Smart KeyPaths

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

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


Re: [swift-evolution] Smart KeyPaths

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

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

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


Re: [swift-evolution] Revisiting 'T != Type' in where clause

2017-03-16 Thread Jaden Geller via swift-evolution

> On Mar 16, 2017, at 8:27 PM, Slava Pestov <spes...@apple.com> wrote:
> 
> Overload resolution has a lot of heuristics, but it’s not magic. It simply 
> doesn’t know how to handle this case.
> 
> I’d be in favor of consolidating and simplifying the overload resolution 
> rules, with the goal of disambiguating common cases that are currently 
> ambiguous. We might even be able to do that without breaking too much user 
> code, since a lot of the rules there were put in place to handle specific 
> situations that came up in the standard library.

Do you think there’s a simplification of the rules that would also better 
handle most cases? I definitely found overload resolution to be confusing topic 
when I first learned Swift (and still today tbh).

> 
> However adding more heuristics to handle specific examples is a -1 from me. 
> :-)
> 
> Slava
> 
>> On Mar 16, 2017, at 7:38 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> I would’ve expected overload resolution to pick the “more specific” one in 
>> this case without needing any additional constraints… 樂
>> 
>>> On Mar 16, 2017, at 6:40 PM, Robert Bennett via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> Hello,
>>> 
>>> This discussion sort of fizzled out when the topic was first introduced. 
>>> Joe Groff had asked the following:
>>> 
>>>> Do you have a concrete example where you need this? It'd be good to know 
>>>> whether the types are ambiguous due to type checker bugs, or whether 
>>>> there's a principle by which they could be naturally ordered.
>>> 
>>> There is an example of this ordering that I stumbled upon recently. Suppose 
>>> I wish to extend `Array` with a `uniques()` function that returns an array 
>>> containing the unique elements of `self`. For performance reasons, I would 
>>> first write a method for arrays with Hashable elements, so that I could 
>>> check for uniqueness in constant time per element.
>>> 
>>> extension Array where Element: Hashable {
>>> func uniques() -> [Element] {
>>> var seen: Set = []
>>> var uniq: [Element] = []
>>> 
>>> for e in self {
>>> if !seen.contains(e) {
>>> seen.insert(e)
>>> uniq.append(e)
>>> }
>>> }
>>> 
>>> return uniq
>>> }
>>> }
>>> 
>>> However I would still like to have a `uniques()` method for arrays whose 
>>> elements are merely Equatable, and I'm willing to take the performance cost 
>>> of O(n) lookup per element.
>>> 
>>> extension Array where Element: Equatable {
>>> func uniques() -> [Element] {
>>> var uniq: [Element] = []
>>> 
>>> for e in self {
>>> if !uniq.contains(e) {
>>> uniq.append(e)
>>> }
>>> }
>>> 
>>> return uniq
>>> }
>>> }
>>> 
>>> However, there is a problem, which is that elements that are Hashable are 
>>> also Equatable, and so there is ambiguity when calling this method:
>>> 
>>> // error: ambiguous use of 'uniques()'
>>> print([1,2,3,1,2,4,5,1,2,3,4,5].uniques())
>>> 
>>> 
>>> If I could add `Element != Hashable` to the second extension, there would 
>>> be no ambiguity.
>>> 
>>> FWIW replacing Array with Collection and Element with Iterator.Element 
>>> fixes the error. The first extension (the one for Hashables) is called. I'm 
>>> not sure why it is ambiguous in one case and not the other.
>>> 
>>> ___
>>> 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] Revisiting 'T != Type' in where clause

2017-03-16 Thread Jaden Geller via swift-evolution
I would’ve expected overload resolution to pick the “more specific” one in this 
case without needing any additional constraints… 樂

> On Mar 16, 2017, at 6:40 PM, Robert Bennett via swift-evolution 
>  wrote:
> 
> Hello,
> 
> This discussion sort of fizzled out when the topic was first introduced. Joe 
> Groff had asked the following:
> 
>> Do you have a concrete example where you need this? It'd be good to know 
>> whether the types are ambiguous due to type checker bugs, or whether there's 
>> a principle by which they could be naturally ordered.
> 
> There is an example of this ordering that I stumbled upon recently. Suppose I 
> wish to extend `Array` with a `uniques()` function that returns an array 
> containing the unique elements of `self`. For performance reasons, I would 
> first write a method for arrays with Hashable elements, so that I could check 
> for uniqueness in constant time per element.
> 
> extension Array where Element: Hashable {
>   func uniques() -> [Element] {
>   var seen: Set = []
>   var uniq: [Element] = []
>   
>   for e in self {
>   if !seen.contains(e) {
>   seen.insert(e)
>   uniq.append(e)
>   }
>   }
>   
>   return uniq
>   }
> }
> 
> However I would still like to have a `uniques()` method for arrays whose 
> elements are merely Equatable, and I'm willing to take the performance cost 
> of O(n) lookup per element.
> 
> extension Array where Element: Equatable {
>   func uniques() -> [Element] {
>   var uniq: [Element] = []
>   
>   for e in self {
>   if !uniq.contains(e) {
>   uniq.append(e)
>   }
>   }
>   
>   return uniq
>   }
> }
> 
> However, there is a problem, which is that elements that are Hashable are 
> also Equatable, and so there is ambiguity when calling this method:
> 
> // error: ambiguous use of 'uniques()'
> print([1,2,3,1,2,4,5,1,2,3,4,5].uniques())
> 
> 
> If I could add `Element != Hashable` to the second extension, there would be 
> no ambiguity.
> 
> FWIW replacing Array with Collection and Element with Iterator.Element fixes 
> the error. The first extension (the one for Hashables) is called. I'm not 
> sure why it is ambiguous in one case and not the other.
> 
> ___
> 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] [draft] Add `clamped(to:)` to the stdlib

2017-03-15 Thread Jaden Geller via swift-evolution

> On Mar 15, 2017, at 8:21 PM, Nicholas Maccharoli  
> wrote:
> 
> Jaden,
> 
> Yes that error message is not so great.
> As for the use of guard  `if someCondition { fatalError(...)}` seems to be a 
> common way of phrasing fatal errors 
> in the standard library but guard works just as well.

I’d guess that’s because most of the standard library predates the existence of 
`guard`, but I’m not sure! Either spelling is probably fine (and more the topic 
of a pull request than a SE review ).

> 
> I updated the proposal to have the following definition:
> 
> extension Strideable where Stride: Integer {
> func clamped(to range: Range) -> Self {
> guard !range.isEmpty { fatalError("Can not clamp to an empty range.") 
> }
> return clamped(to: range.lowerBound...(range.upperBound - 1))
> }
> }
> 
> - Nick 
> 
> On Thu, Mar 16, 2017 at 11:57 AM, Jaden Geller  > wrote:
> 
>> On Mar 15, 2017, at 7:33 PM, Nicholas Maccharoli > > wrote:
>> 
>> Right, there were a few things missing!
>> Thanks so much for pointing them out everyone.
>> 
>> Dave - Great idea! I have updated the motivation section section as you 
>> suggested!
>> 
>> Neil - Yes I also think the wording could be a bit better but since the word 
>> `clamped` is already being used 
>>   I thought I would keep it consistent. 
>> 
>> Sean - Looks as if its a term of art to me as well. 
>> 
>> Nate,
>> 
>> Good catch! Yes I also thing clamping on an empty range should be a fatal 
>> error as well.
>> An empty range is impossible to create with `ClosedRange` so I left the 
>> implementation 
>> of that alone, but it is possible with `Range` so I updated the extension on 
>> `Strideable` like so:
>> 
>> extension Strideable where Stride: Integer {
>> func clamped(to range: Range) -> Self {
>> if range.isEmpty { fatalError("Can't form Range with upperBound < 
>> lowerBound") }
>> return clamped(to: range.lowerBound...(range.upperBound - 1))
>> }
>> }
>> 
>> 
>> 
>> Jaden,
>> 
>> Yeah I think a simple `if` check would work as well.
> 
> I would suggest using guard. It is more idiomatic Swift for something that 
> “fails out”.
> 
> Also, I think this is a bad error message. The `Range` was already created! 
> There was no problem forming it. It was passed as the argument, no problem at 
> all. The problem is trying to *clamp* to an empty range, not forming an empty 
> range. I would rephrase it to say something like "Cannot clamp to an empty 
> range”. No reason to redefine what an empty range is by mentioning 
> `upperBound < lowerBound`.
> 
> Cheers,
> Jaden Geller
> 

Cheers,
Jaden Geller___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [draft] Add `clamped(to:)` to the stdlib

2017-03-15 Thread Jaden Geller via swift-evolution

> On Mar 15, 2017, at 7:33 PM, Nicholas Maccharoli  
> wrote:
> 
> Right, there were a few things missing!
> Thanks so much for pointing them out everyone.
> 
> Dave - Great idea! I have updated the motivation section section as you 
> suggested!
> 
> Neil - Yes I also think the wording could be a bit better but since the word 
> `clamped` is already being used 
>   I thought I would keep it consistent. 
> 
> Sean - Looks as if its a term of art to me as well. 
> 
> Nate,
> 
> Good catch! Yes I also thing clamping on an empty range should be a fatal 
> error as well.
> An empty range is impossible to create with `ClosedRange` so I left the 
> implementation 
> of that alone, but it is possible with `Range` so I updated the extension on 
> `Strideable` like so:
> 
> extension Strideable where Stride: Integer {
> func clamped(to range: Range) -> Self {
> if range.isEmpty { fatalError("Can't form Range with upperBound < 
> lowerBound") }
> return clamped(to: range.lowerBound...(range.upperBound - 1))
> }
> }
> 
> 
> 
> Jaden,
> 
> Yeah I think a simple `if` check would work as well.

I would suggest using guard. It is more idiomatic Swift for something that 
“fails out”.

Also, I think this is a bad error message. The `Range` was already created! 
There was no problem forming it. It was passed as the argument, no problem at 
all. The problem is trying to *clamp* to an empty range, not forming an empty 
range. I would rephrase it to say something like "Cannot clamp to an empty 
range”. No reason to redefine what an empty range is by mentioning `upperBound 
< lowerBound`.

Cheers,
Jaden Geller___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Code blocks and trailing closures

2017-03-15 Thread Jaden Geller via swift-evolution

> On Mar 15, 2017, at 5:17 AM, Rien  wrote:
> 
> 
>> On 15 Mar 2017, at 13:04, Jaden Geller  wrote:
>> 
>> It seems like your complaint is that control-flow statements, specifically 
>> `return`, act different inside closures than inside other braced statements.
> 
> Yes.
> break and continue also come to mind.
> 
> For example if you have some nested loops and you see a “break” statement, 
> you must inspect the code between the loop start and the “break" to check if 
> the break is inside a closure or not.
> 
> 
>> I too dislike this inconsistency, but I don’t think that the syntactic 
>> change you suggested makes it much more clear.
> 
> Agree.
> 
> As is probably clear from Adrian’s reaction, I am not sure if this really is 
> a problem.
> I don’t like it, but the current situation is workable even though it might 
> be confusing to newbies.

Yeah, either way, I don’t think this is a particularly pressing issue for Swift 
to address in the next few versions.

Just for fun though, check out Ruby! It allows for both lambdas and anonymous 
procedures, that latter of which don’t “capture” control-flow keywords. If you 
say `return` inside a procedure, it’ll return from the function that that 
called the procedure, not the procedure (aka, if/for/while behavior in Swift)!

> 
>> I’d rather find a solution that’d allow trailing closure functions (like 
>> `forEach`) to support keywords like `return`, though I imagine this would 
>> require some sort of macro system.
>> 
>> Cheers,
>> Jaden Geller
>> 
>>> On Mar 15, 2017, at 4:56 AM, Rien via swift-evolution 
>>>  wrote:
>>> 
>>> Sorry, it seems we are talking past each other, let me try again:
>>> 
>>> I left the “if” out on purpose. To show that even though the snippet was 
>>> “valid” code, it was in fact ambiguous.
>>> 
>>> With closures (and autoclosures) it becomes possible -to some extent- to 
>>> “enhance” the language.
>>> 
>>> Consider:
>>> 
>>> guard let c = somefunc() else { showError(); return }
>>> myguard( let c = somefunc()) { showError(); return }
>>> 
>>> In this simple example it is clear that the second return behaves quite 
>>> differently from the first.
>>> It gets more difficult if the code in the block cq closure gets very large.
>>> Also, I would expect that beginners would have problems understanding this 
>>> (subtile but important) difference.
>>> 
>>> Regards,
>>> Rien
>>> 
>>> Site: http://balancingrock.nl
>>> Blog: http://swiftrien.blogspot.com
>>> Github: http://github.com/Balancingrock
>>> Project: http://swiftfire.nl
>>> 
>>> 
>>> 
>>> 
>>> 
 On 15 Mar 2017, at 12:19, Adrian Zubarev  
 wrote:
 
 There is no if … on my screen nor there is one here 
 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon–20170313/033888.html.
  May be a typo?
 
 In that case it cannot be a trailing closure because trailing closures are 
 banned in such scenarios. 
 https://github.com/apple/swift-evolution/blob/master/proposals/0056-trailing-closures-in-guard.md
 
 As for the lazy variables you’ve mentioned in the original posts, the 
 closure there is invoked lately but only once and it cannot be reused at 
 all.
 
 Let me know if I understood your gist now.
 
 if someFunction { …; return } // someFunction cannot have a trailing 
 closure here!
 
 
 
 
 -- 
 Adrian Zubarev
 Sent with Airmail
 
 Am 15. März 2017 um 12:08:19, Rien (r...@balancingrock.nl) schrieb:
 
> If I wrote this: 
> 
> if serverCert.write(to: certificateUrl) { showErrorInKeyWindow(message); 
> return } 
> 
> then the meaning of return would have been different. 
> 
> Imo it is a problem that two pieces of code impact the understanding of 
> each other and that those two pieces of code could potentially be very 
> far apart. 
> 
> I do agree that the parenthesis are not a perfect solution, it was just 
> the first thing that I could think of and that has some level of 
> similarity in meaning. 
> 
> Regards, 
> Rien 
> 
> Site: http://balancingrock.nl 
> Blog: http://swiftrien.blogspot.com 
> Github: http://github.com/Balancingrock 
> Project: http://swiftfire.nl 
> 
> 
> 
> 
> 
>> On 15 Mar 2017, at 12:00, Adrian Zubarev 
>>  wrote: 
>> 
>> I’m slightly confused by this. How is a trailing closure different from 
>> a code block in Swift? It’s basically the same thing with some extra 
>> syntax sugar because it happens to be the last parameter of your 
>> function. 
>> 
>> You can simply write this if you wanted to: 
>> 
>> myFucntion(someLabel: abc, closureLabel: { …; return }) 
>> 
>> Parentheses are indicating that your closure is immediately invoked. 

Re: [swift-evolution] Infer types of default function parameters

2017-03-14 Thread Jaden Geller via swift-evolution

> On Mar 14, 2017, at 9:40 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> -1.
> 
> We already have a related feature for stored properties in structs and 
> classes, and it causes a performance problem when compiling multi-file 
> modules in non-WMO mode. Suppose you have:
> 
> — a.swift —
> 
> struct Box {
>   var x =  generics>
> }
> 
> — b.swift —
> 
> func takesABox(_: Box) {}
> 
> — c.swift —
> 
> func returnsABox() -> Box { return Box(x: …) }
> 
> When you run ‘swiftc a.swift b.swift c.swift’, we actually invoke the 
> compiler three times:
> 
> swiftc -frontend -primary-file a.swift b.swift c.swift
> swiftc -frontend a.swift -primary-file b.swift c.swift
> swiftc -frontend a.swift b.swift -primary-file c.swift
> 
> In the first invocation, we’re emitting the declaration of ‘struct Box’ 
> itself, so we have to type check its members, and infer the type of ‘x’. In 
> the second invocation, we end up type checking takesABox(), which references 
> the ‘Box’ type in its parameter list, so again we have to type check the 
> members of ‘Box’ so that we know the ABI for ‘takesABox()’. And the third 
> time, we’re type checking ‘returnsABox()’, which has ‘Box’ in its return 
> type, so again, it has to be type checked so that we know its layout. This 
> means the complex expression will be type checked a total of three times.
> 
> Now if you change a.swift to
> 
> struct Box {
>   var x: Int = 
> }
> 
> Then the expression only has to be type checked when compiling a.swift, so 
> that we can emit the initializer for Box, but b.swift and c.swift immediately 
> know the layout of Box without type checking the initializer (because the 
> property type is declared explicitly).
> 
> If we allowed default argument types to be omitted, you would introduce the 
> potential for similar compile time slowdowns. It would also create 
> interesting circularity issues:
> 
> func foo(a = bar())
> func bar(a = foo())
> 

To be fair, the compiler is currently able to handle a similar situation:

struct Foo {
static let foo = Bar.bar
}

struct Bar {
static let bar = Foo.foo
}

error: 'foo' used within its own type
static let foo = Bar.bar
   ^
error: could not infer type for 'foo'
static let foo = Bar.bar
   ^

I definitely understand wanting to reduce inference along these boundaries, but 
type inference for struct members can be extremely useful.

> Here, you’d have recursion between the declaration checker and recursion 
> checker when you go to type check either one of the two functions.
> 
> While neither of these challenges are insurmountable — we definitely plan on 
> doing more to speed up the expression type checker, and circularity issues in 
> declaration checking are also something we’ve been chipping away at in recent 
> months — I would be against introducing any language features which make 
> things worse in this regard.
> 
> Going back to the my original example here, Jordan Rose once suggested that 
> stored properties inside types should always require a declared type — this 
> might be too drastic for many people’s tastes, but I would definitely be in 
> favor of that from an implementor's perspective ;-)
> 
> Slava
> 
> 
>> On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution 
>> > wrote:
>> 
>> Hi all,
>> 
>> I sent the message below to swift-users@ ~a day ago, but this might be a 
>> better place to ask and gather some discussion. It is a rather minor 
>> suggestion and I'm just looking for some opinions.
>> 
>> Declaring a function that has default parameters currently looks like this:
>> 
>> func foo(bar: String = "baz") {
>> print(bar)
>> }
>> 
>> Now I'm wondering if there would be any problems if it were possible to omit 
>> the type annotation for default params and let Swift's type inference handle 
>> that. 
>> 
>> func foo(bar = "baz") {
>> print(bar)
>> }
>> 
>> It feels to be equivalent to omitting type annotations with variable 
>> declarations. Obviously more complex types would still require annotations 
>> being specified. Off the top of my head I can't think of any negative 
>> ramifications this might bring, be it in simple function/method declarations 
>> or protocol extensions and elsewhere. 
>> Any further input or examples for situations where this might cause issues 
>> would be much appreciated :)
>> 
>> Cheers,
>> Kilian
>> ___
>> 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

Re: [swift-evolution] [Draft] Hasher & HashVisitable

2017-03-14 Thread Jaden Geller via swift-evolution
If this were desired, an associated type would not be sufficient. Perhaps 
`Dictionary` only supports keys where `Hash == Int`. Then any type that might 
key a dictionary must use `Int` as it’s hash type. It wouldn’t be possible to 
define a second implementation with `Int128` or any other types as the hash 
type since each type can only conform to a protocol once.

Now, if we had generic protocols, this would be possible…

extension Foo: Hashable { … }
extension Foo: Hashable { … }

I’m not sure if that would even be a reasonable design though; I’m just 
pointing out that the associated type would be problematic.

Cheers,
Jaden Geller

> On Mar 14, 2017, at 4:45 PM, David Waite via swift-evolution 
>  wrote:
> 
> It would be possible for a Hasher to return varying types, but then people 
> might want the interface to support cryptographic hashing as well as variable 
> length hashes (for things like HAMT)
> 
> -DW
> 
>> On Mar 14, 2017, at 4:56 PM, Greg Parker via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Mar 14, 2017, at 12:01 PM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> Are we committed to having `hashValue` always be an `Int`, or could it be 
>>> an associated type like  `(Int, Int, Int, Int)`? Seems like especially for 
>>> something like a BigNum type or an Array, there might simple not be a 
>>> reasonably efficient way to uniquely-ish represent 1024 bits with just 64 
>>> bits.
>>> 
>>> (This kinda feels like one of those questions where the answer starts out 
>>> with a variation on “you’re missing the point”)
>> 
>> This would lead to an implementation nightmare for hashing containers. 
>> Consider what the implementation of Dictionary would look like 
>> if any of its keys could have incompatible hash outputs.
>> 
>> 
>> -- 
>> Greg Parker gpar...@apple.com  Runtime 
>> Wrangler
>> 
>> 
>> ___
>> 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] Property Selectors

2017-03-14 Thread Jaden Geller via swift-evolution


> On Mar 14, 2017, at 1:42 AM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> 
> 
> Sent from my iPhone
>> On Mar 14, 2017, at 01:02, Andrew Thompson via swift-evolution 
>>  wrote:
>> 
>> Hello Swift Evolution Community,
>> 
>> I’ve been thinking about a new language feature that would allow properties 
>> to be first class citizens. The basic idea is as follows:
>> 
>>   let x: PropertySelector = #property(UIView.frame.origin.x)
>>   let view: UIView = …
>>   view.frame.origin.x = 20
>>   x.read(view) // returns 20
>>   x.write(view, value: 9091)
>>   view.frame.origin.x // now 9091
>> 
>> This is a trivial example, but now we can do more interesting things in our 
>> code. For example, we can animate any property on a view (that is documented 
>> to be animatable of course):
>> 
>>   func animate(view: UIView, property: PropertySelector, 
>> amount: Int) {
>>   let originalValue = property.read(view)
>>   func generateKeyFrames() {
>>   let step = 1.0 / Double(amount)
>>   for i in 0..>   let newValue = originalValue + CGFloat(i)
>>   let time = Double(i) / Double(amount)
>>   UIView.addKeyframe(withRelativeStartTime: time,
>> relativeDuration: step,
>> animations: { property.write(view, value: 
>> newValue) }
>>   )
>>   }
>>   }
>> 
>>   UIView.animateKeyframes(withDuration: 1.0,
>>  delay: 0,
>>  options: [],
>>  animations: generateKeyFrames,
>>  completion: nil)
>>   }
>> 
>>   let myView: UIView = …
>>   myView.frame = CGRect(x: 20, y: 100, width: 99, height: 120)
>> 
>>   // once this completes, myView.frame.origin.x == 120
>>   animate(view: myView, property: #property(UIView.frame.origin.x), amount: 
>> 100)
>> 
>>   // once this completes, myView.frame.size.width == 198
>>   animate(view: myView, property: #property(UIView.frame.size.width), 
>> amount: 99)
>> 
>> I think this would be a pretty neat feature to have, what do you think?
> 
> I think you can already do that with `UnsafeMutablePointer`. I think. I'm 
> really tired, so maybe if I look at it again in the morning I'll immediately 
> see a difference. Apart from the syntax, of course, which is nice.

You definitely shouldn't try to replicate this with a pointer. At least one 
place that will break down is computed properties (as well as `didSet` and 
friends), but I imagine there are more. Also, this sort of operation should not 
require dropping down to an unsafe construct!

It's worth noting this is sort of equivalent to defining a type that stores 
functions that, given a type, will get or set a certain property. It would need 
to be initialized with 2 lambdas though.

> 
> -Dave Sweeris
> 
> ___
> 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] Inconsistencies in recursive types

2017-03-14 Thread Jaden Geller via swift-evolution

> On Mar 14, 2017, at 2:13 AM, Dimitri Racordon  
> wrote:
> 
> Thanks a lot for your very detailed explanations!
> 
> So my only issue regarding #1 #2 and #3 is the error message, which really 
> doesn't suggest the actual underlying problem.
> 
> Regarding #5 and #6, I still feel like the compiler should complain about it. 
> I disagree on the fact that it shouldn't be it's role to disallow 
> uninitializable code, unless using unsafe techniques. This imho isn't 
> consistent with some other errors the compiler does emit for ill-defined 
> types.

That’s the thing though, they aren’t ill-defined. Just because a type cannot be 
initialized does not mean it is not useful.

1. Namespacing

I admit this is a kind of hacky use, but there’s not better way right now.

enum Geometry {
struct Point {
var x: Int
var y: Int
}
}

let p = Geometry.Point(x: 0, y: 0)


2. Uninhabited Types

Swift uses `Never` as the return types of functions that can never return (e.g. 
`fatalError`). Since `never` is an enum with no cases, it is not possible to 
construct one. This indicates to the type system that the function will not 
return.

func runloop() -> Never {
while true {
print("Hello again!")
}
}

let result: Never = runloop()
// Since a `Never` type cannot be constructed,
// we will not pass this line.


3. Phantom Types

Sometimes an uninhabited type is useful for providing information in the type 
system without creating an instance of the type itself. These tags can be used 
to provide additional behavior to the type or to provide additional type 
safety. Here’s another example 
 and some reading 
.

enum Unvalidated { }
enum Validated { }

struct User {
private(set) var name: String
private(set) var age: Int
}

extension User where V == Unvalidated {
init(name: String, age: Int) {
self.name = name
self.age = age
}

func validated() -> User? {
guard age > 18 else { return nil }
return User(name: name, age: age)
}
}

func register(_ user: User) {
print("\(user.name) is registered!")
}

if let me = User(name: "Jaden Geller", age: 21).validated() {
register(me)
}

Cheers,
Jaden Geller

> On 13 Mar 2017, at 22:20, Jaden Geller  > wrote:
> 
>> Comments inline:
>> 
>>> On Mar 13, 2017, at 6:38 AM, Dimitri Racordon via swift-evolution 
>>> > wrote:
>>> 
>>> Hello swift-evolution,
>>> 
>>> I noticed there’s some inconsistencies with recursive types and how the 
>>> compiler handles them. Consider the following cases:
>>> 
>>> 
>>> 1. Swift is right to refuse compiling this, since there’s no way to 
>>> initialise an instance of `First `:
>>> 
>>> struct First {
>>> let item: First
>>> }
>>> // Error: Value type 'First' cannot have a stored property that references 
>>> itself
>>> 
>>> However, the message suggests more a compiler limitation rather than the 
>>> actual impossibility to initialize the declared type.
>>> 
>> 
>> This is a compiler limitation that isn’t going to go away. Structs are value 
>> types whose size is equal to the sum of their property sizes. Here, we have 
>> a circular dependency, so it is impossible to compute the size.
>> 
>> This is not an arbitrary restriction. Consider:
>> 
>> struct List {
>> var head: T
>> var tail: List?
>> }
>> 
>> The size of `List` is infinite! Every `Optional` must be big enough to 
>> store the type `T` in case the value is not `nil`. Thus, `List` must be big 
>> enough to store a `T` AND another list (of the same size):
>> 
>> size(of: List) = size(of: T) + size(of: List)
>> 
>> It’s easy to see that, assuming `size(of: T)` is non-zero, it is impossible 
>> to satisfy this constraint. Yes, Swift could special case the case where 
>> there are no other members, but this would be entirely useless (you can’t 
>> store state) and would considerably muck up the semantics.
>> 
>> Note that enums allow members to be marked `indirect`. This would be a 
>> reasonable feature for Swift to eventually support for structs as well. In 
>> this case, the indirect member would be the size of a pointer, so the size 
>> would be statically known and satisfied.
>> 
>>> 
>>> 2. Swift is also right not to compile this, but the error messages are even 
>>> less insightful:
>>> 
>>> struct First {
>>> let item: Second
>>> }
>>> // Error: Value type 'First' cannot have a stored property that references 
>>> itself
>>> 
>>> 
>>> struct Second {
>>> let item: First
>>> }
>>> // Error: Value type 'Second' cannot have a stored property that references 
>>> itself
>>> 
>>> The problem isn’t that the value types reference themselves. Instead, the 
>>> problem is that there’s a cyclic dependency between `First` and `Second` 
>>> that 

Re: [swift-evolution] Group "typedef" language feature

2017-03-13 Thread Jaden Geller via swift-evolution
Swift already supports equivalent semantics to what you’re looking for, though 
conditional conformances are required for this to work with dictionaries and 
arrays too.

protocol JSONValueType { }
extension String: JSONValueType { }
extension Double: JSONValueType { }
extension Int: JSONValueType { }
extension Dictionary: JSONValueType where Key == String, Value: JSONValueType { 
}
extension Array: JSONValueType where Element: JSONValueType { }
extension Bool: JSONValueType { }

let data = [String : JSONValueType]()
data[key] = "value"

let b: String? = nil
let a: JSONValueType = b // error: value of optional type 'Optional' 
not unwrapped

Cheers,
Jaden Geller

> On Mar 12, 2017, at 7:52 PM, Elijah Johnson via swift-evolution 
>  wrote:
> 
> I don’t know if this feature has yet existed in any languague, but its pretty 
> simple.
> 
> Let say you are preparing data for a JSON encoder. Right now, you would add 
> to an Dictionary or Array like this one:
> 
> let data = [String:Any]();
> 
> but what one is really saying is that “Any” is from a number of distinct 
> types:
> 
> group typedef JSONValueType : String, Double, Int, [String:JSONValueType], 
> [JSONValueType], Bool
> 
> So from the compiler’s point of view, this group typedef would be just like 
> the “Any” type, only it would refuse to compile unless the proper type was 
> passed. So the result would be, as an example, that there could be created an 
> (almost) fail-safe JSON encoder:
> 
> let data = [String:JSONValueType]();
> data[“key] = “value”;
> 
> I’m sure this has plenty of uses outside of JSON encoding and would be pretty 
> simple to do. One problem that it would solve it the fact that in Swift, 
> everything is included by Any, including optionals, ex:
> 
> let b : String? = nil;
> let a : Any = b; // result is warning: “Expression implicitly coerced from 
> String? to Any"
> 
> and so there is no way to include value types and objects without also 
> including optionals, though this “Any” (like Object and void* in Java/C) 
> syntax makes for poorly documented code when the type isn’t really “Any”, but 
> a collection of known types.
> 
> There already exist protocols, but they are not useful for types that one has 
> not defined (like the basic system types), or for mixing particular values, 
> structs, and classes.
> ___
> 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] Inconsistencies in recursive types

2017-03-13 Thread Jaden Geller via swift-evolution
Comments inline:

> On Mar 13, 2017, at 6:38 AM, Dimitri Racordon via swift-evolution 
>  wrote:
> 
> Hello swift-evolution,
> 
> I noticed there’s some inconsistencies with recursive types and how the 
> compiler handles them. Consider the following cases:
> 
> 
> 1. Swift is right to refuse compiling this, since there’s no way to 
> initialise an instance of `First `:
> 
> struct First {
> let item: First
> }
> // Error: Value type 'First' cannot have a stored property that references 
> itself
> 
> However, the message suggests more a compiler limitation rather than the 
> actual impossibility to initialize the declared type.
> 

This is a compiler limitation that isn’t going to go away. Structs are value 
types whose size is equal to the sum of their property sizes. Here, we have a 
circular dependency, so it is impossible to compute the size.

This is not an arbitrary restriction. Consider:

struct List {
var head: T
var tail: List?
}

The size of `List` is infinite! Every `Optional` must be big enough to store 
the type `T` in case the value is not `nil`. Thus, `List` must be big enough to 
store a `T` AND another list (of the same size):

size(of: List) = size(of: T) + size(of: List)

It’s easy to see that, assuming `size(of: T)` is non-zero, it is impossible to 
satisfy this constraint. Yes, Swift could special case the case where there are 
no other members, but this would be entirely useless (you can’t store state) 
and would considerably muck up the semantics.

Note that enums allow members to be marked `indirect`. This would be a 
reasonable feature for Swift to eventually support for structs as well. In this 
case, the indirect member would be the size of a pointer, so the size would be 
statically known and satisfied.

> 
> 2. Swift is also right not to compile this, but the error messages are even 
> less insightful:
> 
> struct First {
> let item: Second
> }
> // Error: Value type 'First' cannot have a stored property that references 
> itself
> 
> 
> struct Second {
> let item: First
> }
> // Error: Value type 'Second' cannot have a stored property that references 
> itself
> 
> The problem isn’t that the value types reference themselves. Instead, the 
> problem is that there’s a cyclic dependency between `First` and `Second` that 
> makes it impossible for neither of these structures to be instantiated.
> 

This is an identical problem to #1. The error message could probably be 
improved. This isn’t a “reference” in the sense of a pointer, but in the sense 
that there is literally a dependency. 

> 
> 3. Swift should let me do that:
> 
> struct First {
> let item: First?
> }
> 
> The compiler prevents me to declare the above struct, even if there actually 
> is a way to initialise an instance of `First` (e.g. `First(item: nil)`). The 
> message is identical to that of case #1 (maybe it actually is a compiler 
> limitation after all?)
> 

This is an identical problem to #1. An option does *not* introduce any 
indirection. Swift will however allow the following:

struct First {
let item: [First]
}

This is because `Array`—if you look at its declaration—does not *directly* 
store any type `T`. Instead, it stores a pointer to a buffer holding `T`s, 
allocated at runtime. These semantics may be a big confusing at first, but this 
is the tradeoff for the better performance value types can sometimes bring.

> 
> 4. Swift shouldn’t compile this:
> 
> class First {
> let item: First
> init(item: First) {
> self.item = item
> }
> }
> 
> Like in case #1, there’s no way to instantiate `First`. The fact that it’s a 
> reference rather than a value doesn’t change the problem.
> 

This is not a bug IMO. It is not the compiler’s job to prevent you from 
compiling code that includes a type that cannot be instantiated.

Unlike the previous cases, the compiler actually *can* generate code for these 
types. You _could_ even unsafely instantiate these types. In the previous 
cases, the compiler could not compute the size of the types.

> 
> 5. Similarly to case #4, Swift shouldn’t compile this:
> 
> indirect enum First {
> case item(First)
> }
> 

Ditto #4.

> 
> 6. Cases #4 #5 could be written like case #2, and should also raise 
> compilation errors.
> 

Ditto #4.

> 
> Does someone know if these issues have already been discussed and/or 
> addressed?
> 
> Thanks,
> Dimitri Racordon
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


I hope I was able to clear up your confusion. Let me know if you have any other 
questions.

Cheers,
Jaden Geller

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


Re: [swift-evolution] [draft] Add `clamped(to:)` to the stdlib

2017-03-12 Thread Jaden Geller via swift-evolution
You definitely ought to add “do nothing” to the alternative considered section. 
Also, any reason you didn’t implement `clamped` in terms of `min` and `max`?

> On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution 
>  wrote:
> 
> ​Swift-Evolution.
> 
> This is a draft of a proposal adding `clamped(to:)` as an extension on 
> `Comparable`.
> For now I have only included a version of the `clamped(to:)` function that 
> accepts `ClosedRange` but if the community decided that it is feasible to add 
> a version that takes half open ranges I would also love to include that as 
> well in this proposal. 
> 
> That you so much for the feedback so far and I am looking forward 
> to the community's feedback on this draft. 
> 
> - Nick 
> 
> 
> Add clamp​ed​(to:) to the stdlib
> 
> Proposal: SE- 
> 
> Authors: Nicholas Maccharoli 
> Review Manager: TBD
> Status: Awaiting review
> During the review process, add the following fields as needed:
> 
> Decision Notes: Rationale 
> , Additional Commentary 
> 
> Bugs: SR- , SR- 
> 
> Previous Revision: 1 
> 
> Previous Proposal: SE- 
> 
>  
> Introduction
> 
> This proposal aims to add functionality to the standard library for clamping 
> a value to a ClosedRange. The proposed function would allow the user to 
> specify a range to clamp a value to where if the value fell within the range, 
> the value would be returned as is, if the value being clamped exceeded the 
> upper or lower bound in value the value of the boundary the value exceeded 
> would be returned.
> 
> Swift-evolution thread: Add a clamp function to Algorithm.swift 
> 
>  
> Motivation
> 
> There have been quite a few times in my professional and personal programming 
> life where I reached for a clampedfunction and was disappointed it was not 
> part of the standard library.
> 
> Having functionality like clamped(to:) added to Comparable as a protocol 
> extension would benefit users of the Swift language who wish to guarantee 
> that a value is kept within bounds.
> 
>  
> Proposed
>  solution
> 
> The solution proposed is simply that there be a clamped(to:) function added 
> to the Swift Standard Library. The function would behave much like its name 
> describes.
> 
> Given a clamped(to:) function existed it could be called in the following 
> way, yielding the results in the adjacent comments:
> 
> var foo = 100
> foo.clamp(to: 0...50) // 50
> foo.clamp(to: 200...300) // 200
> foo.clamp(to: 0...150) // 100
>  
> Detailed
>  design
> 
> The implementation for clamped(to:) as an extension to Comparable accepting a 
> range of type ClosedRangewould look like the following:
> 
> extension Comparable {
> func clamped(to range: ClosedRange) -> Self {
> if self > range.upperBound {
> return range.upperBound
> } else if self < range.lowerBound {
> return range.lowerBound
> } else {
> return self
> }
> }
> }
>  
> Source
>  compatibility
> 
> This feature is purely additive; it has no effect on source compatibility.
> 
>  
> Effect
>  on ABI stability
> 
> This feature is purely additive; it has no effect on ABI stability.
> 
>  
> Effect
>  on API resilience
> 
> The proposed function would become part of the API but purely additive.
> 
>  
> Alternatives
>  considered
> 
> clamped(to:) could be made a global function like min and max but a protocol 
> extension seems like a better choice.​
> 

Re: [swift-evolution] [draft] Add `clamped(to:)` to the stdlib

2017-03-12 Thread Jaden Geller via swift-evolution
+1

I think `clamp` is a very reasonable function to include in the standard 
library. The semantics are clear, and it is definitely much easier to read than 
the alternative.

I think we should also include an open range variant. Note that this is only 
defined on types with integer strides since the semantics only make sense when 
values of the type are discrete.

extension Strideable where Stride: Integer {
func clamped(to range: Range) -> Self {
return clamped(to: range.lowerBound...(range.upperBound - 1))
}
}

Cheers,
Jaden Geller

> On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution 
>  wrote:
> 
> ​Swift-Evolution.
> 
> This is a draft of a proposal adding `clamped(to:)` as an extension on 
> `Comparable`.
> For now I have only included a version of the `clamped(to:)` function that 
> accepts `ClosedRange` but if the community decided that it is feasible to add 
> a version that takes half open ranges I would also love to include that as 
> well in this proposal. 
> 
> That you so much for the feedback so far and I am looking forward 
> to the community's feedback on this draft. 
> 
> - Nick 
> 
> 
> Add clamp​ed​(to:) to the stdlib
> 
> Proposal: SE- 
> 
> Authors: Nicholas Maccharoli 
> Review Manager: TBD
> Status: Awaiting review
> During the review process, add the following fields as needed:
> 
> Decision Notes: Rationale 
> , Additional Commentary 
> 
> Bugs: SR- , SR- 
> 
> Previous Revision: 1 
> 
> Previous Proposal: SE- 
> 
>  
> Introduction
> 
> This proposal aims to add functionality to the standard library for clamping 
> a value to a ClosedRange. The proposed function would allow the user to 
> specify a range to clamp a value to where if the value fell within the range, 
> the value would be returned as is, if the value being clamped exceeded the 
> upper or lower bound in value the value of the boundary the value exceeded 
> would be returned.
> 
> Swift-evolution thread: Add a clamp function to Algorithm.swift 
> 
>  
> Motivation
> 
> There have been quite a few times in my professional and personal programming 
> life where I reached for a clampedfunction and was disappointed it was not 
> part of the standard library.
> 
> Having functionality like clamped(to:) added to Comparable as a protocol 
> extension would benefit users of the Swift language who wish to guarantee 
> that a value is kept within bounds.
> 
>  
> Proposed
>  solution
> 
> The solution proposed is simply that there be a clamped(to:) function added 
> to the Swift Standard Library. The function would behave much like its name 
> describes.
> 
> Given a clamped(to:) function existed it could be called in the following 
> way, yielding the results in the adjacent comments:
> 
> var foo = 100
> foo.clamp(to: 0...50) // 50
> foo.clamp(to: 200...300) // 200
> foo.clamp(to: 0...150) // 100
>  
> Detailed
>  design
> 
> The implementation for clamped(to:) as an extension to Comparable accepting a 
> range of type ClosedRangewould look like the following:
> 
> extension Comparable {
> func clamped(to range: ClosedRange) -> Self {
> if self > range.upperBound {
> return range.upperBound
> } else if self < range.lowerBound {
> return range.lowerBound
> } else {
> return self
> }
> }
> }
>  
> Source
>  compatibility
> 
> This feature is purely additive; it has no effect on source compatibility.
> 
>  
> Effect
>  on ABI stability
> 
> This feature is purely additive; it has no effect on ABI stability.
> 
>  
> 

Re: [swift-evolution] Infer types of default function parameters

2017-03-11 Thread Jaden Geller via swift-evolution
Ahh, misunderstanding then. I had thought they were suggesting this was the 
default value of the typealias.

Thanks for clearing that up,
Jaden Geller

> On Mar 11, 2017, at 5:08 PM, Robert Widmann <devteam.cod...@gmail.com> wrote:
> 
> You may be missing/misspelling the typealias declaration.  This has been in 
> Policy.swift for a while now, and I can reproduce this as far back as 2.2 in 
> the Bluemix sandbox.
> 
> ~Robert Widmann
> 
>> On Mar 11, 2017, at 7:41 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Mar 11, 2017, at 3:22 PM, Ben Cohen <ben_co...@apple.com 
>>> <mailto:ben_co...@apple.com>> wrote:
>>> 
>>>> 
>>>> On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> 
>>>> 
>>>> On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> 
>>>>>> On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> -1
>>>>>> 
>>>>>> It would be inconsistent to allow it for deterministic literals (String) 
>>>>>> and not for non deterministic literal (int which can be either a Int, 
>>>>>> Uint, Float, …)
>>>>> 
>>>>> If I’m not mistaken, even with `bar = “baz”`, `String` is merely the 
>>>>> default inferred type. It could be anything that conforms to 
>>>>> `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a 
>>>>> way to make a function implicitly generic:
>>>>> func foo(bar = "baz") {…}
>>>>> becomes:
>>>>> func foo(bar: T = "baz") {…}
>>>>> 
>>>> 
>>>> As I understood it, omitting the type would work identically to `let` 
>>>> declarations. A string literal without a type defaults to `String`. 
>>>> Treating it as a generic function is a bad idea IMO.
>>>> 
>>> 
>>> More specifically, a string literal without a type defaults to the 
>>> StringLiteralType typealias:
>>> 
>>> typealias StringLiteralType = StaticString
>>> let s = "abc"
>>> print(type(of: s))
>>> // prints StaticString
>> 
>> What version of the Swift compiler are you using? I don’t observe this 
>> behavior. That code prints `String` for me.
>> 
>>> 
>>>> I don't think this sugar is worth any amount of added complexity. Most 
>>>> function arguments will have not have default values and this have to 
>>>> continue to declare the type, so this would only be more concise in very 
>>>> few cases. I'd prefer the consistency of always having to explicitly 
>>>> declare the argument type at a function boundary.
>>>> 
>>>> To call a function, you need to know what type to pass in. This becomes 
>>>> more difficult when not make explicit, particularly when a more 
>>>> complicated expression is used as a default. -1
>>>> 
>>>>> Is there anything we can do with a variable, if all we know of it is that 
>>>>> it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… 
>>>>> If we had a way to get back the literal string which the variable was 
>>>>> initialized with, we could initialize other values with that, but the 
>>>>> protocol doesn’t require us to store it. Come to think of it, is there 
>>>>> even a way to store a literal value in its “untyped” form? You can 
>>>>> declare a variable to of type `IntegerLiteralType`, but the type system 
>>>>> then treats it as an `Int`.
>>>>> 
>>>>> So while it looks nice (to me, anyway) I’m not sure you could actually do 
>>>>> anything with it. Or am I looking at this wrong?
>>>>> 
>>>>> - Dave Sweeris
>>>>> ___
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> ___
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto: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] Infer types of default function parameters

2017-03-11 Thread Jaden Geller via swift-evolution

> On Mar 11, 2017, at 3:22 PM, Ben Cohen <ben_co...@apple.com> wrote:
> 
>> 
>> On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>> On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>>> On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> -1
>>>> 
>>>> It would be inconsistent to allow it for deterministic literals (String) 
>>>> and not for non deterministic literal (int which can be either a Int, 
>>>> Uint, Float, …)
>>> 
>>> If I’m not mistaken, even with `bar = “baz”`, `String` is merely the 
>>> default inferred type. It could be anything that conforms to 
>>> `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a 
>>> way to make a function implicitly generic:
>>> func foo(bar = "baz") {…}
>>> becomes:
>>> func foo(bar: T = "baz") {…}
>>> 
>> 
>> As I understood it, omitting the type would work identically to `let` 
>> declarations. A string literal without a type defaults to `String`. Treating 
>> it as a generic function is a bad idea IMO.
>> 
> 
> More specifically, a string literal without a type defaults to the 
> StringLiteralType typealias:
> 
> typealias StringLiteralType = StaticString
> let s = "abc"
> print(type(of: s))
> // prints StaticString

What version of the Swift compiler are you using? I don’t observe this 
behavior. That code prints `String` for me.

> 
>> I don't think this sugar is worth any amount of added complexity. Most 
>> function arguments will have not have default values and this have to 
>> continue to declare the type, so this would only be more concise in very few 
>> cases. I'd prefer the consistency of always having to explicitly declare the 
>> argument type at a function boundary.
>> 
>> To call a function, you need to know what type to pass in. This becomes more 
>> difficult when not make explicit, particularly when a more complicated 
>> expression is used as a default. -1
>> 
>>> Is there anything we can do with a variable, if all we know of it is that 
>>> it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If 
>>> we had a way to get back the literal string which the variable was 
>>> initialized with, we could initialize other values with that, but the 
>>> protocol doesn’t require us to store it. Come to think of it, is there even 
>>> a way to store a literal value in its “untyped” form? You can declare a 
>>> variable to of type `IntegerLiteralType`, but the type system then treats 
>>> it as an `Int`.
>>> 
>>> So while it looks nice (to me, anyway) I’m not sure you could actually do 
>>> anything with it. Or am I looking at this wrong?
>>> 
>>> - Dave Sweeris
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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] Infer types of default function parameters

2017-03-11 Thread Jaden Geller via swift-evolution


On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution 
> wrote:

> 
>> On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution 
>> > wrote:
>> 
>> -1
>> 
>> It would be inconsistent to allow it for deterministic literals (String) and 
>> not for non deterministic literal (int which can be either a Int, Uint, 
>> Float, …)
> 
> If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default 
> inferred type. It could be anything that conforms to 
> `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way 
> to make a function implicitly generic:
> func foo(bar = "baz") {…}
> becomes:
> func foo(bar: T = "baz") {…}
> 

As I understood it, omitting the type would work identically to `let` 
declarations. A string literal without a type defaults to `String`. Treating it 
as a generic function is a bad idea IMO.

I don't think this sugar is worth any amount of added complexity. Most function 
arguments will have not have default values and this have to continue to 
declare the type, so this would only be more concise in very few cases. I'd 
prefer the consistency of always having to explicitly declare the argument type 
at a function boundary.

To call a function, you need to know what type to pass in. This becomes more 
difficult when not make explicit, particularly when a more complicated 
expression is used as a default. -1

> Is there anything we can do with a variable, if all we know of it is that it 
> conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we 
> had a way to get back the literal string which the variable was initialized 
> with, we could initialize other values with that, but the protocol doesn’t 
> require us to store it. Come to think of it, is there even a way to store a 
> literal value in its “untyped” form? You can declare a variable to of type 
> `IntegerLiteralType`, but the type system then treats it as an `Int`.
> 
> So while it looks nice (to me, anyway) I’m not sure you could actually do 
> anything with it. Or am I looking at this wrong?
> 
> - Dave Sweeris
> ___
> 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] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Jaden Geller via swift-evolution

> On Mar 10, 2017, at 8:04 PM, Robert Bennett via swift-evolution 
>  wrote:
> 
> I really like this proposal, and think that it does have a place in Swift 4. 
> Two quick notes in light of the discussion: first, I think it should be 
> called clamped, not clamp; second, I think it should only take ClosedRange. 
> More on those later, but first I'll respond to the six questions raised by 
> Xiaodi.
> 
>> 1. Is it truly a frequent operation?
> I think so. I've certainly wished for it on an occasion or two. I settle for 
> min(upper, max(lower, value)).
> 
>> 2. Is the helper more readable? Is the composed equivalent obvious at a 
>> glance?
> Definitely (or I imagine it will be once we get the details figured out). 
> There are two equivalent forms of the min-max version, the other being 
> max(lower, min(upper, value)), not to mention the commutativity of the 
> arguments themselves. I am under the impression that Swift is not a big fan 
> of having multiple equivalent ways to do the same thing — that was part of 
> the reason ++ was nixed. value.clamp(to: closedRange) is clear and is not 
> interchangeable with any one thing in the language.
> 
>> 3. Does the helper have the flexibility to cover all common cases?
> I see three cases: value < lower, lower <= value <= upper, and upper < value. 
> All are covered.
> 
>> 4. Is there a correctness trap with the composed equivalent? Is there a 
>> correctness trap with the helper?
> I don't think so, if we limit to ClosedRange.
> 
>> 5. Is there a performance trap with the composed equivalent? Or with the 
>> helper?
> I don't know, is there a significant cost associated to constructing a 
> ClosedRange solely for the purpose of using its bounds? I would imagine not, 
> but someone who knows more about Swift can answer.
> 
>> 6. Does the helper actually encourage misuse?
> I don't see how, if we limit its argument to ClosedRange.
> 
> 
> Going back to my earlier points — I think that to keep things in line with 
> Swift's naming conventions, this function should be called clamped, as it 
> returns a modified version of the calling object. Alternatively, we could 
> follow the standard set by other numeric types and provide the non-mutating 
> clamped and the mutating clamp, like multiplied/multiply for Double.
> 
> Finally, I don't think it makes mathematical sense to clamp to a non-closed 
> range. Refer back to the original definition proposed, `min(upperBound, 
> max(lowerBound, value))`. ClosedRange was proposed as a convenience for 
> providing those bounds. This makes sense because a ClosedRange contains its 
> bounds. Since (mathematical) non-closed ranges don't contain their bounds, it 
> doesn't make sense to use a non-closed range to provide those bounds.

I think open ranges should be supported, but not for all `Comparable` types. It 
would however be reasonable to support it for types with discrete ordered 
values, all `Integer` types for example. I think we might be able to provide it 
for `T: Strideable where T.Stride: Integer` even. We definitely cannot provide 
it for all types though; it’s nonsensical to clamp a real value to a closed 
range.

> 
> Also, the above notwithstanding, I have a hard time figuring out when you 
> would actually want to constrain a number to be strictly less than an upper 
> bound, violating Question 1 above. If this behavior were really desired, 
> better to be explicit and subtract the appropriate delta — 1 for Int, 
> Double.epsilon (or whatever it's called) for Double. I definitely foresee a 
> correctness trap with the non-closed Range.
> 
> Another reason not to allow half-open ranges is because of their asymmetry. 
> Half open ranges are only open at their upper end, so you would have the 
> ability to open-clamp from above but not from below. Seems arbitrary (see 
> Question 3).

We already have this asymmetry. Adding a clamp function doesn’t worsen it. 
Besides, we have half-open [above] ranges because they are useful for indices:

`arr[idx.clamped(to: arr.startIndex.. 
> ___
> 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] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Jaden Geller via swift-evolution

> On Mar 10, 2017, at 1:13 AM, David Sweeris <daveswee...@mac.com> wrote:
> 
> 
>> On Mar 10, 2017, at 12:22 AM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Mar 9, 2017, at 11:20 PM, Nicholas Maccharoli via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Nevin,
>>> 
>>> Yeah I think this works well as an extension on `Comparable`,  
>>> `foo.clamped(to: 1...100)` seems pretty natural.
>>> 
>>> Why not go one step further and move the versions of min, max that take two 
>>> arguments on over to `Comparable` as a protocol extension?
>> 
>> I think that a symmetric operation like `min` or `max` ought to treat both 
>> arguments in a symmetric way. `3.max(with: 9)` not only reads badly, but 
>> privileges one argument over the other syntactically. I’d very much like to 
>> avoid this.
> 
> Agreed.
> 
>> I would be okay with removing top-level min and max if `Array` min and max 
>> could generate equivalent code given an array literal. This seems possible.
> 
> Yeah, it seems like it’d be technically possible, but not without either a 
> lot of compiler magic (not only in somehow optimizing away the overhead of 
> creating an Array, but `[1, 2].max()` returns an `Int?` instead of an `Int`) 
> , or maybe a sufficiently sophisticated macro… The 1st is something we’re 
> trying to avoid, and IIRC the 2nd is out-of-scope for Swift 4. Also, I’m wary 
> of not having the normal “math.h” functions, simply because they’re so 
> universal.

I suspect the compiler magic wouldn’t be too difficult if the array were a 
literal, but I don’t know. I forgot that it returns an optional though, that’s 
definitely problematic and probably a deal-breaker. Perhaps if we ever get 
vectors (with the size known by the type-system) we could do this (as the 
result would be non-optional), but I don’t know how it would choose this 
overload since Array is preferred…

*leaves lid on Pandora’s box and backs away*

> 
> - Dave Sweeris
> 

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


Re: [swift-evolution] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Jaden Geller via swift-evolution

> On Mar 9, 2017, at 11:20 PM, Nicholas Maccharoli via swift-evolution 
>  wrote:
> 
> Nevin,
> 
> Yeah I think this works well as an extension on `Comparable`,  
> `foo.clamped(to: 1...100)` seems pretty natural.
> 
> Why not go one step further and move the versions of min, max that take two 
> arguments on over to `Comparable` as a protocol extension?

I think that a symmetric operation like `min` or `max` ought to treat both 
arguments in a symmetric way. `3.max(with: 9)` not only reads badly, but 
privileges one argument over the other syntactically. I’d very much like to 
avoid this.

I would be okay with removing top-level min and max if `Array` min and max 
could generate equivalent code given an array literal. This seems possible.

> 
> Perhaps something like this?
> 
> extension Comparable {
> 
> func max(with value: Self) -> Self {
> if value > self {
> return value
> }
> return self
> }
> 
> func min(with value: Self) -> Self {
> if value < self {
> return value
> }
> return self
> }
> 
> func clamped(to range: ClosedRange) -> Self {
> let selfUpperMin = range.upperBound.min(with: self)
> return range.lowerBound.max(with: selfUpperMin)
> }
> }
> 
> - Nick
> 
> 
> On Fri, Mar 10, 2017 at 1:41 PM, Nevin Brackett-Rozinsky via swift-evolution 
> > wrote:
> I’d be on board with an extension of Comparable so you could write 
> “16.clamped(to: 0...10)”. Something along the lines of:
> 
> extension Comparable {
> func clamped(to range: ClosedRange) -> Self {
> return max(range.lowerBound, min(self, range.upperBound))
> }
> }
> 
> Nevin
> 
> ___
> 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] [Pitch] Introducing `Unwrappable` protocol

2017-03-07 Thread Jaden Geller via swift-evolution

> On Mar 7, 2017, at 8:59 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Mar 7, 2017, at 12:14 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> Because of that, I'm going to start over here, hopefully pulling in all the 
>> details
>> and allowing the community to provide feedback and direction. The following 
>> gist is an amalgam of work I was discussing with Xiaodi Wu, Chris Lattner, 
>> and
>> David Goodine.
>> 
>> https://gist.github.com/erica/aea6a1c55e9e92f843f92e2b16879b0f
> 
> Treating the things separately:
> 
> 1. Introduce an `unwrap` keyword
> 
> I'm really not convinced this pulls its own weight. Without the `let`, it 
> doesn't make the fact that it's shadowing the original (and thus that you 
> cannot modify it) clear; with the `let`, it introduces a new keyword people 
> need to learn for the sake of eliding a repeated variable name.

If Swift supported `if inout x = x { … }`, then `unwrap` could have much more 
reasonable semantics.

> 
> In the document, you state that `unwrap` "simplifies the status quo and 
> eleminates unintended shadows", but that's not true, because the existing 
> syntax will continue to exist and be supported. Unless we warn about *any* 
> shadowing in an `if let` or `if case`, it will still be possible to 
> accidentally shadow variables using these declarations.
> 
> 2. Introduce an `Unwrappable` protocol
> 
> I like the idea, but I would use a slightly different design which offers 
> more features and lifts this from "bag of syntax" territory into representing 
> a discrete semantic. This particular design includes several elements which 
> depend on other proposed features:
> 
>   /// Conforming types wrap another type, creating a supertype which may 
> or may not 
>   /// contain the `Wrapped` type.
>   /// 
>   /// `Wrapper` types may use the `!` operator to unconditionally access 
> the wrapped 
>   /// value or the `if let` and `guard let` statements to conditionally 
> access it. Additionally, 
>   /// `Wrapped` values will be automatically converted to the 
> `Wrapper`-conforming type 
>   /// as needed, and the `is`, `as`, `as?`, and `as!` operators will 
> treat the `Wrapped` type 
>   /// as a subtype of the `Wrapper`-conforming type.
>   protocol Wrapper {
>   /// The type that this value wraps.
>   associatedtype Wrapped
>   
>   /// The type of error, if any, thrown when a non-wrapped value 
> is unwrapped.
>   associatedtype UnwrappingError: Error = Never
>   
>   /// Creates an instance of `Self` which wraps the `Wrapped` 
> value.
>   /// 
>   /// You can call this initializer explicitly, but Swift will 
> also insert implicit calls when 
>   /// upcasting from `Wrapped` to `Self`.
>   init(_ wrapped: Wrapped)
>   
>   /// Returns `true` if `Self` contains an instance of `Wrapped` 
> which can be accessed 
>   /// by calling `unwrapped`.
>   var isWrapped: Bool { get }
>   
>   /// Accesses the `Wrapped` value within this instance.
>   /// 
>   /// If `isWrapped` is `true`, this property will always return 
> an instance. If it is `false`, this property 
>   /// will throw an instance of `UnwrappingError`, or trap if 
> `UnwrappingError` is `Never`.
>   var unwrapped: Wrapped { get throws }
>   
>   /// Accesses the `Wrapped` value within this instance, possibly 
> skipping safety checks.
>   /// 
>   /// - Precondition: `isWrapped` is `true`.
>   var unsafelyUnwrapped: Wrapped { get }
>   }
>   
>   extension Wrapper {
>   // Default implementation of `unsafelyUnwrapped` just calls 
> `unwrapped`.
>   var unsafelyUnwrapped: Wrapped {
>   return try! unwrapped
>   }
>   }
> 
> The defaulting of `WrappingError` to `Never` means the error-emitting aspects 
> of this design are additive and can be introduced later, once the necessary 
> supporting features are introduced. The use of separate `isWrapped` and 
> `unwrapped` properties means that `unwrapped` can implement an appropriate 
> behavior on unwrapping failure, instead of being forced to return `nil`.
> 
> (An alternative design would have `wrapped: Wrapped? { get }` and `unwrapped: 
> Wrapped { get throws }` properties, instead of `isWrapped` 
> and `unwrapped`.)
> 
> In this model, your example of:
> 
>   let value = try unwrap myResult // throws on `failure`
> 
> Would instead be:
> 
>   let value = try myResult! // throws on `failure`
> 
> (Actually, I'm not sure why you said this would be `unwrap`—it's not 
> shadowing `myResult`, is it?)
> 
> Theoretically, this exact design—or something 

Re: [swift-evolution] [Pitch] Introducing `Unwrappable` protocol

2017-03-07 Thread Jaden Geller via swift-evolution
It’s worth mentioning that the normal let binding can be used for pattern 
matching:
  let (a, b, c) = foo()

This nicely parallels the existing case syntax:
  if case let .blah(a, b, c) = bar() { … }
It would feel inconsistent if the order switched when in a conditional binding.

I would prefer that `case` was removed to best mirror the normal syntax, 
requiring `?` or `.some` to be used for optionals
  if let .blah(a, b, c) = bar() { … }
  if let unwrapped? = wrapped { … }
  if let .some(unwrapped) = wrapped { … }
but I realize this is source-breaking, so I’m happy with the existing syntax.

Unrelated: I feel like a single case [closed] enum shouldn’t require an `if` to 
match, similar to tuples:
  let .onlyCase(a) = baz()
I’m not sure this is particularly useful, but it seems consistent; if a pattern 
is irrefutable, a conditional binding is unnecessary.

Anyway, I’m definitely -1 on the idea as a whole. It doesn’t clearly seem 
cleaner to me, and it is majorly source breaking. I’m +1 for a warning to avoid 
accidental shadowing—why doesn’t it give an unused variable warning already? 
Seems odd…

> On Mar 7, 2017, at 12:14 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> I have been involved in several separate related draft proposals for 
> discussions 
> that were cut off about 4 months ago. I believe they meet the criteria for 
> Stage 2,
> but I'm doing a poor job presenting them coherently on-list.
> 
> Because of that, I'm going to start over here, hopefully pulling in all the 
> details
> and allowing the community to provide feedback and direction. The following 
> gist is an amalgam of work I was discussing with Xiaodi Wu, Chris Lattner, and
> David Goodine.
> 
> https://gist.github.com/erica/aea6a1c55e9e92f843f92e2b16879b0f 
> 
> 
> I've decided to link to the gist rather than paste the entire proposal as 
> that never seems to 
> really work here.
> 
> 
> In a nutshell:
> 
> Unwrapping values is one of the most common Swift tasks and it is 
> unnecessarily complex. 
> 
> Consider the following solutions:
> 
> Introduce an unwrap keyword for Optional values
> Introduce an Unwrappable protocol for associated-value enumerations.
> Apply unwrap to non-Optional values.
> Extend for and switch.
> Fix pattern match binding issues.
> Simplify complex binding.
>  
> Motivation
> 
> Unwrapping with conditional binding and pattern matching is unnecessarily 
> complex and dangerous:
> 
> Using "foo = foo" fails DRY principles 
> . 
> Using case let .some(foo) = foo or case .some(let foo) = foo fails KISS 
> principles .
> Using the = operator fails the Principle of Least Astonishment 
> .
> Allowing user-provided names may shadow existing variables without compiler 
> warnings.
> The complexity and freedom of let and var placement can introduce bugs in 
> edge cases.
> -- E
> ___
> 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] [Manifesto] Ownership

2017-03-07 Thread Jaden Geller via swift-evolution


> On Mar 7, 2017, at 10:02 AM, John McCall via swift-evolution 
>  wrote:
> 
>>> On Mar 7, 2017, at 11:47 AM, plx via swift-evolution 
>>>  wrote:
 On Feb 27, 2017, at 11:08 AM, John McCall  wrote:
 
 On Feb 25, 2017, at 11:41 AM, plx via swift-evolution 
  wrote:
 1: Collection Composition
 
 As much as the high-level picture is focused on safety, I’d just like to 
 request a strong focus on making sure the eventual ownership system 
 addresses the common issues like avoiding copies when mutating through 
 optionals, or when nesting collections, and so on.
>>> 
>>> Avoiding copies is basically the entire core of the proposal.  The 
>>> interaction with safety is that sometimes copies are necessary to avoid 
>>> memory unsafety, and this proposal recommends an approach that minimizes 
>>> that.
>> 
>> Thanks for the extend reply and sorry for my own belated reply.
>> 
>> What motivated me to ask for more focus on the common cases was that it was 
>> unclear from reading the proposal whether the `inout` binding--as used in 
>> `for inout`--could be used with `if`: in other words, we currently have `if 
>> let` and `if var`, but will we have `if inout` under this proposal?
>> 
>> I am embarassed to admit I honestly couldn't tell if the proposal didn't 
>> contain any examples of `if inout` due to (a) the capability following 
>> trivially from the rest of the proposal or (b) the capability falling 
>> outside the scope of the proposal.
> 
> I just didn't think about it.  "if inout" is quite supportable under the 
> basic model.
> 
>>> The technical obstacle to this is just that, so far, we've tried to make 
>>> language features like for-loops use formal protocols.
>>> 
>>> An iteration protocol is going to have requirements like this:
>>>   generator iterate() -> Element
>>>   mutating generator iterateMutable() -> inout Element
>>> But there's no valid substitution that makes '(Key, inout Value)' equal 
>>> either 'Element' or 'inout Element'.  So we'd have to do some special to 
>>> make this work.
>>> 
>>> That said, no, there's no intrinsic technical reason this can't be made to 
>>> work.
>> 
>> The explanation of wanting to stick to formal protocols makes perfect sense. 
>> I don’t think this should be a show-stopper, but I do think it’ll be a 
>> common request for a subsequent enhancement. 
>> 
>> Even in the interim it seems quite feasible to emulate the capability in any 
>> concrete case with enough willingness to crank out boilerplate; thus e.g. if 
>> someone truly needs `for (index, inout value) in collection.enumerated()` or 
>> `for (a, inout b) in zip(as,bs)` it isn’t as if they’re entirely stuck.
> 
> I actually spent some more time thinking about it after I wrote it, and there 
> are some nice things that come out of abandoning formal protocols here.  You 
> could allow generators to be overloaded, not by name, but by the 
> "inout-shape" of their return value, so that something like
>   for (a, inout b) in ...
> would specifically look for a generator like:
>   generator() -> (T, inout U)
> etc.

Would it be valid write:
```
var iter = foo.makeIterator()
inout x = iter.next()
```

If not, are special case `inout` returns really the right way to model this 
feature? It seems that a inout-map interface would be better as it doesn't 
require any special case language features.

Or am I misunderstanding, and `inout` reruns in the general case are supported 
by this proposal? If so, `inout` seems like a poor name.

> 
 3: Mutable Views
>>> 
>>> It's not sensible to have a type that conditionally conforms to a protocol 
>>> based on context. 
>> 
>> That did indeed seem like a big ask!
>> 
>> I’ll put in an early request to consider 
>> 
>>   @moveonly {
>> struct File { } 
>>   }
>> 
>> …(or @scope(moveonly) or @context(moveonly) or @dialect(moveonly), etc.).
>> 
>> It’s confusing that `moveonly` essentially applies “inward”—it flags the 
>> code *within* a scope as using different assumptions, etc.—in contrast to 
>> most of the modifiers like `open`, `final`, `mutating`, etc., apply 
>> “outward” (by e.g. describing how visible the code in the scope is from 
>> other scopes, etc.).
> 
> An interesting idea.
> 
>>>  However, the requirements of MutableCollection are all 'mutating', so you 
>>> can't actually use them unless you have a mutable value.  So the way to fit 
>>> what you're asking for into the ownership proposal is to make sure that 
>>> clients of your view type only have a mutable value when the base was 
>>> mutable, and the easiest way of getting that is to have the view be vended 
>>> as storage rather than a return value.  If you think about it, a mutable 
>>> view can't be an independent value anyway, because if code like this could 
>>> work:
>>> 
>>>   var grid = ... // note that this is mutable
>>>   var view = 

Re: [swift-evolution] [Pitch] SE-0083 revisited: removing bridging behavior from `as`/`is`/`as?` casts

2017-03-04 Thread Jaden Geller via swift-evolution
I think you’re misunderstanding it. The goal is to only provide bridging at the 
language boundary (via the importer). The keyword `as` would no longer invoke 
bridging behavior, but would simply provide extra static type information to 
help with inference.

Cheers,
Jaden Geller

> On Mar 4, 2017, at 4:33 PM, Kenny Leung via swift-evolution 
>  wrote:
> 
> So this proposal would not only change the meaning of “as”, but would require 
> changing all bridged Objective-C API to remove any implicit conversions?
> 
> -Kenny
> 
> 
>> On Mar 4, 2017, at 3:45 PM, Charles Srstka > > wrote:
>> 
>>> On Mar 4, 2017, at 5:12 PM, Kenny Leung via swift-evolution 
>>> > wrote:
>>> 
>>> Speaking from a position of total ignorance here, but I’ll do it anyway :-)
>>> 
>>> How is the implicit dynamic bridging any different from implicit static 
>>> bridging? If I have an Objective-C method like
>>> 
>>> - (NSArray)getAllSuctionBalls
>>> 
>>> It would get translated into
>>> 
>>> func getAllSuctionBalls() -> [SuctionBall]
>>> 
>>> Where an NSArray is being implicitly bridged to a Swift array. Since such 
>>> an implicit conversion exists anyway, what’s the harm in it happening when 
>>> you do 
>>> 
>>> let swiftSuctionBalls = getSomething() as [SuctionBall]
>> 
>> 1. The bridging described above is necessary, because you’re calling an API 
>> in another language. Some kind of bridging has to be involved for that to 
>> work at all, and we all understand that.
>> 
>> 2. The bridging above doesn’t abuse a language construct that typically has 
>> a completely different meaning (“as” as compile-time type coercion, with no 
>> runtime effects).
>> 
>> 3. If we fix “as” so that it only means type coercion, we could finally have 
>> a way to avoid the bridging behavior above; i.e. ‘getAllSuctionBalls() as 
>> NSArray’ to leave the returned value in its original form as an NSArray, 
>> rather than bridging it to Swift and then back. This would be really useful 
>> for certain situations like NSURL’s -fileReferenceURL which gets mangled by 
>> the bridge, and it could also provide a potential performance optimization 
>> when getting values that are just going to get passed to other Objective-C 
>> APIs afterward.
>> 
>> 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] [Pitch] SE-0083 revisited: removing bridging behavior from `as`/`is`/`as?` casts

2017-03-02 Thread Jaden Geller via swift-evolution

> On Mar 2, 2017, at 4:24 PM, Joe Groff  wrote:
> 
> 
>> On Mar 2, 2017, at 3:09 PM, Jaden Geller > > wrote:
>> 
>> +1. I’ve always found the bridging casting behavior confusing. Definitely 
>> would agree with removing it—especially given the interop problems—but only 
>> if a good solution was found for imported APIs.
>> 
>> With `NSNumber`-involving APIs, I think it might be reasonable to add an 
>> Objective-C annotation to specify what numeric type ought to be used 
>> (instead of Any). For example, `-(NSNumber *) foo` is a straw-man 
>> syntax for specifying that a number should be imported as `UInt32` in Swift.
> 
> That might be a nice ObjC addition, but I think we could pursue that 
> independently.
> 
>> What other APIs involve this dynamic through-`Any` bridging behavior? It 
>> might make sense to make a comprehensive list. Another I can think of is 
>> `NSJSONSerialization`. It would be much more difficult to remove bridging 
>> behavior here without new language features… Additionally, NSNumber is still 
>> problematic—what should be the numeric type of a JSON number? If only we had 
>> integer and floating point existentials…
> 
> In general, anywhere you get an `id` behavior—return values, block callback 
> inputs, and yeah, untyped NSArrays and NSDictionarys. In the case of JSON, 
> you might be able to use Double, but for the full range of types plists 
> support, IMO you arguably ought to work directly with the NSNumber interface. 
> That's likely the only implementation that'd make sense in corelibs 
> foundation, for instance. (Maybe with the new integer protocols we could 
> introduce an `AnyNumeric` type-erased container…)
> 
>> Perhaps Objective-C APIs that return `id`, when called from Swift, ought to 
>> eagerly perform bridging for the boxed value into the respective Swift type? 
>> Then `as` would no longer perform this weird behavior; it would just happen 
>> by default for all values return from Objective-C APIs. No need to store an 
>> extra bit on the existential and introduce inconsistent behavior… 
> 
> The problem is that we can't know, without further input from the compiler, 
> what bridging is needed, if any. The interface may intend to provide an 
> NSNumber, or an NSString backed by NSTextStorage or Core Data, or something 
> like that, for which you wouldn't want to go through the bridge.

Ah, that is problematic… Thanks for the explanation.

Do you anticipate that Swift will ever support arbitrary subtype relationships 
(like `Int8` as a subtype of `Int`, for example). If so, then would the current 
bridging behavior be that odd? All the numeric types could be declared to be a 
subtype of `NSNumber` by some Foundation overlay, etc., and the behavior would 
be the same as it is today.

> 
>> There obviously ought to be a way to opt out of this if you want the 
>> original type. Perhaps the compiler could detect conversions back to 
>> Objective-C types are optimize away the round-trip? For example, `try! 
>> JSONSerialization.jsonObject(with: data)` would be implicitly converting to 
>> a Swift type (wrapped in an `Any`) while `NSString(try! 
>> JSONSerialization.jsonObject(with: data) as! String)` would skip the 
>> roundtrip conversion via the optimizer.
> 
> The compiler already does some of this. If you pass a value type as an `Any` 
> parameter, it will bridge directly to the parameter's bridged object type 
> instead of going through Any and dynamically bridging first.

That’s super cool! 

> 
> -Joe

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


Re: [swift-evolution] [Discussion] What is the future of tuples in Swift?

2017-03-02 Thread Jaden Geller via swift-evolution
I’m not OP, but I imagine you can pattern match on the type. I don’t think 
that’s a compelling reason to add this feature though. I’d rather have 
active-patterns 

 for structs.

> On Mar 2, 2017, at 3:13 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
>> 
>> On Mar 2, 2017, at 3:24 AM, Anton Zhilin via swift-evolution 
>> > wrote:
>> 
>> I think that tuples should remain what they are now. Static-length vectors 
>> should be types on their own and interact with tuples, with structs and with 
>> Array<…> in the same way.
>> 
>> newtype should be what enables extension of tuples:
>> 
>> 
> Does newtype add any new capability that’s not already covered by defining a 
> struct?
> 
> Slava
> 
>> newtype Money = (Int, Int)
>> 
>> extension Money: CustomStringConvertible {
>> var description: String {
>> return String(format: "$%d.%02d", arguments: [getSelfFirst, 
>> getSelfSecond])
>> }
>> }
>> 
>> let x = (0, 42)
>> let y = x as Money  // error
>> print(x.description)  // error
>> 
>> let z = Money(0, 42)
>> print(z.description)  //=> $0.42
>> Here, getSelfFirst and getSelfSecond are placeholders for some syntax to 
>> access the underlying type.
>> 
>> ___
>> 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] [Pitch] SE-0083 revisited: removing bridging behavior from `as`/`is`/`as?` casts

2017-03-02 Thread Jaden Geller via swift-evolution
+1. I’ve always found the bridging casting behavior confusing. Definitely would 
agree with removing it—especially given the interop problems—but only if a good 
solution was found for imported APIs.

With `NSNumber`-involving APIs, I think it might be reasonable to add an 
Objective-C annotation to specify what numeric type ought to be used (instead 
of Any). For example, `-(NSNumber *) foo` is a straw-man syntax for 
specifying that a number should be imported as `UInt32` in Swift.

What other APIs involve this dynamic through-`Any` bridging behavior? It might 
make sense to make a comprehensive list. Another I can think of is 
`NSJSONSerialization`. It would be much more difficult to remove bridging 
behavior here without new language features… Additionally, NSNumber is still 
problematic—what should be the numeric type of a JSON number? If only we had 
integer and floating point existentials…

Perhaps Objective-C APIs that return `id`, when called from Swift, ought to 
eagerly perform bridging for the boxed value into the respective Swift type? 
Then `as` would no longer perform this weird behavior; it would just happen by 
default for all values return from Objective-C APIs. No need to store an extra 
bit on the existential and introduce inconsistent behavior… 

There obviously ought to be a way to opt out of this if you want the original 
type. Perhaps the compiler could detect conversions back to Objective-C types 
are optimize away the round-trip? For example, `try! 
JSONSerialization.jsonObject(with: data)` would be implicitly converting to a 
Swift type (wrapped in an `Any`) while `NSString(try! 
JSONSerialization.jsonObject(with: data) as! String)` would skip the roundtrip 
conversion via the optimizer.

Sorry for the stream of consciousness, but hopefully I was able to contribute 
some useful ideas :)

Cheers,
Jaden Geller

> On Mar 1, 2017, at 8:11 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> I’d like to investigate separating Objective-C bridging from the behavior of 
> the as/as?/is operator family again for Swift 4. Last year, I proposed 
> SE–0083 
> ,
>  but we deferred the proposal for lack of time to evaluate its impact. As 
> complicating factors, we now have source compatibility with Swift 3 as a 
> requirement, and the id-as-Any work from SE–0116 
> 
>  more or less requires bridging dynamic casts to work. I think we can 
> nonetheless make important improvements in this area in order to simplify the 
> core language and provide more portable behavior across platforms with and 
> without ObjC interop. In retrospect, submitting SE–0083 as an omnibus “fix 
> casting” proposal was a mistake. We can separate out a few smaller 
> subproblems from the overall concept:
> 
> Replacing as for bridging coercion
> 
> Swift 0 shipped with implicit conversions between standard library value 
> types and their bridged Cocoa classes in both directions, and as we’ve eased 
> off of the implicit conversions, we still left the as operator with the 
> ability to force the conversions. This complicates the meaning of as: 
> normally, it just provides type context, but it also has the power to force 
> bridging conversions. These meanings are often at odds:
> 
> // `NSNumber` is `ExpressibleByIntegerLiteral`, so this gives type context to 
> the literal 0
> // and is equivalent to `NSNumber(integerLiteral: 0)`
> 0 as NSNumber
> 
> // `x` already has type `Int`, so this forces the bridging conversion and is 
> equivalent to
> // `_bridgeToObjectiveC(x)` (and thereby gives you a different kind of 
> `NSNumber`!)
> let x: Int = 0
> x as NSNumber
> Aside from the complexity and non-portability of this behavior, this is also 
> inconsistent with the Swift naming conventions, which recommend that 
> conversions between related types be presented as initializers. Additionally, 
> the bridging conversions often have specialized behavior for performance or 
> semantic reasons that aren’t intended to be exposed in the normal API of 
> either type (for example, bridging a Swift number type to NSNumber produces a 
> “type-preserving” instance of NSNumber so that the bridge doesn’t lose type 
> information, even though NSNumber’s own API presents a type-agnostic numeric 
> object). Therefore, I propose that we remove the bridging behavior from as, 
> and provide APIs for conversion where they don’t yet exist. as is purely a 
> compile-time construct with no runtime interaction, so the Swift 3 
> compatibility and ABI issues are much simpler than they are when runtime 
> casting behavior becomes involved.
> 
> Warning on is/as?/as! casts that statically induce bridging
> 
> Without changing the runtime behavior of casting, we could still discourage 
> users from using dynamic casting to perform 

Re: [swift-evolution] [Discussion] Simplifying case syntax

2017-02-28 Thread Jaden Geller via swift-evolution
I suggest you split this into 2 separate proposals. The second part seems much, 
much more controversial than the first.

Cheers,
Jaden Geller

> On Feb 28, 2017, at 11:01 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> The following draft proposal addresses one matter of substance (eliminating 
> edge case errors by adopting at-site conditional binding) and one of style 
> (using the pattern match operator consistently). Its discussion was deferred 
> from Phase 1 and remains in a fairly early stage. Your feedback will help me 
> decide whether this is a proposal I want to keep developing or one that I 
> should set aside and focus on other matters. Thank you. -- E
> 
> The work-in-progress gist is here:  
> https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c 
>  
> 
> Simplifying case syntax
> 
> Proposal: TBD
> Author: Erica Sadun 
> Status: TBD
> Review manager: TBD
>  
> Introduction
> 
> This proposal re-architects case syntax grammar to reduce potential errors 
> and simplify unwrapping enumerations. 
> 
> Swift-evolution thread: [Pitch] Reimagining guard case/if case 
> 
>  
> Motivation
> 
> In its current design, Swift case binding suffers from two weaknesses.
> 
> Mixed external and internal let/var binding may introduce errors from 
> uncommon edge cases.
> Real-world users may not consider the parallel construction between if 
> case/guard case with switchstatements or naturally connect the two layouts.
>  
> Internal
>  Case Binding
> 
> When pattern matching, it's common to bind a variable or constant. It's 
> uncommon but legal to use a bound value as an argument. Adopting an "always 
> explicit, always within the parentheses" rule adds consistency and safety to 
> Swift. 
> 
> Consider the following enumeration and values:
> 
> // An enum with one, two, or three associated values
> enum Value { case one(T), two(T, T), three(T, T, T) }
> 
> // An example with two associated values
> let example2: Value = .two("a", "b")
> 
> // A bound symbol
> let oldValue = "x"
> This code's goal is to conditionally bind newValue and pattern match the 
> value stored in the oldValue symbol. The first example succeeds. The second 
> example compiles and runs but does not match the coder's intent. Using an 
> external letcreates a new oldValue shadow instead of pattern matching 
> oldValue's stored value.
> 
> // Safe
> if case .two(let newValue, oldValue) = example2 { 
> ... 
> }
> 
> // Syntactically legal but incorrect
> if case let .two(newValue, oldValue) = example2 { 
> ... 
> }
> In-parenthesis binding avoids accidental shadowing. It eliminates this class 
> of error by adding let and var key words to each use point. This creates 
> longer call sites but enumerations rarely contain more than three or four 
> associated items.
> 
> Adopting point-of-use binding enhances clarity and readability. Both if case 
> let and if case var (plus case varand case let) may look like single compound 
> keywords rather than a combination of two distinct actions to developers 
> unfamiliar with this syntax.
> 
>  
> Pattern
>  Matching with Conditional Binding
> 
> Swift's guard case and if case align statement design with the switch 
> statement, moving the matched value to the right of an equal sign.
> 
> switch value {
> case .enumeration(let embedded): ...
> }
> 
> if case .enumeration(let embedded) = value
> The status quo for the = operator is iteratively built up in this fashion:
> 
> = performs assignment
> let x = performs binding
> if let x = performs conditional binding on optionals
> if case .foo(let x) = performs conditional binding on enumerations and 
> applies pattern matching
> Using if case/guard case in the absense of conditional binding duplicates 
> basic pattern matching with less obvious meaning. These two statements are 
> functionally identical:
> 
> if range ~= myValue { ... } // simpler
> if case range = myValue { ... } // confusing
> Issues with the current design include:
> 
> guard case and if case look like standard non-conditional assignment 
> statements but they are not assignment statements. Using the assignment 
> operator violates the principle of least astonishment 
> .
> In switch, a case is followed by a colon, not an assignment operator.
> Swift has a pattern matching operator (~=) but does not use it here.
> case syntax is wordy. The statement includes 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Jaden Geller via swift-evolution

> On Feb 21, 2017, at 5:00 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>>  wrote:
>> 
>> The semantics of some existing access control modifiers shall also be 
>> extended to support module declarations:
>> 
>>  • open and public declarations are exported by a module for consumption 
>> by clients of the module.
>>  • internal declarations scope over the entire module and any derived 
>> submodules.
> 
> If I'm reading this correctly, you're proposing that the `internal` APIs in a 
> submodule should *not* be accessible to enclosing modules. I also don't see 
> any indication that you can control who is allowed to import a particular 
> submodule.
> 
> That means that, if you use a submodule to encapsulate internal state, the 
> APIs that are available to the parent module are *also* available to any 
> rando who feels like importing your submodule. I don't think that's going to 
> be a tenable design.

It might be reasonable to allow access control modifiers to be used with 
modules.

— `private` module declarations can only be imported in the scope in which they 
were defined
— `fileprivate` module declarations can only be imported in the file in which 
they were defined
— `internal` module declarations can be imported anywhere in the outermost (?) 
module
— `public` module declaration are exported to consumers of the outermost module

Definitely more thought needs to go into this, but it might address this desire.

> 
> (I have a couple other objections—I think the keyword ought to be `submodule` 
> if you don't need a top-level `module` declaration, I think there's a lot to 
> be said for a single declaration covering the entire file, and I'm pretty 
> iffy on this entire approach anyway—but this seems like the most serious 
> problem of the bunch.)

I think using `submodule` as a keyword is both reasonable and a good idea. It 
does become problematic if/when we eventually want to allow entire files to be 
part of a submodule though…

> 
> -- 
> 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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Jaden Geller via swift-evolution

> On Feb 21, 2017, at 4:44 AM, Alex Blewitt <alb...@apple.com> wrote:
> 
> 
>> On 21 Feb 2017, at 07:00, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> We avoid forcing users to organize code in such an opinionated manner just 
>> to please the compiler. Perhaps some submodules deserve a separate file, but 
>> I think that choice should not be forced by the language. I don’t have data 
>> on the popularity, but I personally very much dislike the similar 
>> restriction Java places on public classes and files.
> 
> On the other hand, having such standardisation means that you know exactly 
> where a type is based on its module membership. One of the outcomes of 
> Scala's move away from enforcing a relationship between files and their 
> module structure means that it is almost impossible to find where a type is 
> defined using the filesystem, and you resort to using 'git grep' or other 
> tools to find out where the implementation is located.
> 
>> Given that we want Swift to be a fantastic scripting language, I feel we 
>> ought not place artificial restrictions on code organization. Many scripts 
>> are a single file (for convenience) but may still benefit from the 
>> organization modules offer.
> 
> Is there a reason why a script should need to be in any module, as opposed to 
> a top-level/unnamed module?
> 

Submodules within a script provide encapsulation that can be useful for code 
organization. They likely would use an implicit (unnamed) outer module.

> Alex

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
It’s probably best we explain this motivation under “Alternatives Considered”. 
I forked and updated the gist—feel free to “pull” in the changes… copy 
and paste the document

https://gist.github.com/JadenGeller/c18b1be8e7b9fa3023e98b84fca423ca#multiple-declarations-instead-of-extensions
 
<https://gist.github.com/JadenGeller/c18b1be8e7b9fa3023e98b84fca423ca#multiple-declarations-instead-of-extensions>

Cheers,
Jaden Geller

> On Feb 20, 2017, at 10:57 PM, Robert Widmann <devteam.cod...@gmail.com> wrote:
> 
> This was syntax I initially considered, but Jaden swayed me with the idea 
> that we already have an `extension` keyword so we may as well use it to match 
> the rest of the language.  Repeating the `module` declaration also lends 
> itself more to C++-style namespaces, which these are not.  I’m not saying 
> it’s out of the question, far from it. It is an alternative we will keep in 
> mind.
> 
> ~Robert Widmann
> 
>> On Feb 21, 2017, at 1:53 AM, Psycho Hedgehog via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> The one thing i don't understand is the point of using extensions to extend 
>> modules across multiple files, why not just allow declaring the submodule in 
>> multiple files?
>> 
>>> Le 20 févr. 2017 à 22:48, Jaden Geller via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> Oh, I see. You’re questioning the motivation of having scope-granularity 
>>> submodules at all! My misunderstanding.
>>> 
>>> I actually hadn’t considered this as added complexity. In my mind, a scoped 
>>> module declaration seems more Swifty than a file module declaration. It 
>>> builds on the existing syntax in Swift for defining other sorts of scopes, 
>>> e.g. types.
>>> 
>>> Cheers,
>>> Jaden Geller
>>> 
>>>> On Feb 20, 2017, at 10:41 PM, Jonathan Hull via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> I think my question is: Why do we want to allow submodules that are 
>>>> smaller than a file?  What does that give us to offset the added 
>>>> complexity?
>>>> 
>>>> Thanks,
>>>> Jon
>>>> 
>>>>> On Feb 20, 2017, at 6:44 PM, Robert Widmann <devteam.cod...@gmail.com 
>>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>>> 
>>>>> 
>>>>>> On Feb 20, 2017, at 9:36 PM, Jonathan Hull <jh...@gbis.com 
>>>>>> <mailto:jh...@gbis.com>> wrote:
>>>>>> 
>>>>>> What is the rational for having modules covering only part of a file?  
>>>>>> Wouldn’t it be less clutter to have an annotation which worked for the 
>>>>>> whole file.  At the very least it would be nice to have an option to 
>>>>>> spell it in a way that applies to the whole file.  Otherwise, everything 
>>>>>> will be indented another level.
>>>>> 
>>>>> That is a valid spelling (Rust, IIRC, allows that spelling), but one that 
>>>>> is easy to miss sitting in a file and makes it confusing to introduce 
>>>>> submodules.  If you include the annotation then define a submodule later 
>>>>> down in the file, suddenly you have to remember whether you annotated the 
>>>>> file or whether the submodule you’ve just written is going into the 
>>>>> top-level module.  See:
>>>>> 
>>>>> // -module-name=Foo
>>>>> // module Foo {
>>>>> module Bar; // Shorthand for “This file defines Foo.Bar”
>>>>> 
>>>>> /* Code */
>>>>> 
>>>>> // This defines “Foo.Bar.Baz”, but would you know that if it appeared 
>>>>> below the fold?
>>>>> module Baz {}
>>>>> //}
>>>>> 
>>>>> If anything, this can be added later if evolution converges on it.
>>>>> 
>>>>>> 
>>>>>> I would honestly love to see something which just maps modules to 
>>>>>> folders/groups for simplicity sake.
>>>>>> 
>>>>> 
>>>>> There is nothing about this scheme that prevents you from organizing your 
>>>>> code this way.  However, modulo that particular method of organization, 
>>>>> you don’t really gain much as a user of the language by imp

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
We avoid forcing users to organize code in such an opinionated manner just to 
please the compiler. Perhaps some submodules deserve a separate file, but I 
think that choice should not be forced by the language. I don’t have data on 
the popularity, but I personally very much dislike the similar restriction Java 
places on public classes and files.

Given that we want Swift to be a fantastic scripting language, I feel we ought 
not place artificial restrictions on code organization. Many scripts are a 
single file (for convenience) but may still benefit from the organization 
modules offer.

Best,
Jaden Geller  

> On Feb 20, 2017, at 10:51 PM, Jonathan Hull  wrote:
> 
> Part of it.  My concern is that the brackets will push everything in the file 
> to the right.
> 
> My question is: What do we get in return for that? (as opposed to a system 
> which acted on the whole file)
> 
> Thanks,
> Jon
> 
> 
>> On Feb 20, 2017, at 10:45 PM, Jaden Geller > > wrote:
>> 
>> Oh, you’re referring to the fact that a submodule under this proposal must 
>> be contained within braces? It would be purely additive to, in the future, 
>> annotate that the outer scope of a file is part of some given submodule.
>> 
>> Consider the following the following straw-man syntax that might be 
>> equivalent to `module Bar { func foo() { } }`:
>> ```
>> module Bar follows // <- at top of file, indicating rest of file is submodule
>> 
>> func foo() { }
>> ```
>> 
>> Does this address your question?
>> 
>> Thanks,
>> Jaden Geller
>> 
>>> On Feb 20, 2017, at 10:39 PM, Jonathan Hull >> > wrote:
>>> 
>>> 
 On Feb 20, 2017, at 6:42 PM, Jaden Geller > wrote:
 
 Jon,
 
 I think we might have miscommunicated. It is intended that outermost 
 module is implicit; no `module` declaration is required to wrap every 
 file. We tried to show this in the first code snippet.
 
 What do you mean “covering only part of a file”?
>>> 
>>> I am assuming that the ModuleName { … }  only affects things within the 
>>> brackets.  Thus it is possible for only part of a file to be within a 
>>> module.  What are the benefits of allowing this, and are they worth the 
>>> added complexity?
>>> 
>>> Thanks,
>>> Jon
>>> 
>>> 
 Cheers,
 Jaden Geller
 
> On Feb 20, 2017, at 6:36 PM, Jonathan Hull via swift-evolution 
> > wrote:
> 
> What is the rational for having modules covering only part of a file?  
> Wouldn’t it be less clutter to have an annotation which worked for the 
> whole file.  At the very least it would be nice to have an option to 
> spell it in a way that applies to the whole file.  Otherwise, everything 
> will be indented another level.
> 
> I would honestly love to see something which just maps modules to 
> folders/groups for simplicity sake.
> 
> I haven’t thought about it too much yet, so I could easily be missing 
> something obvious...
> 
> Thanks,
> Jon
>>> 
>> 
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
Oh, I see. You’re questioning the motivation of having scope-granularity 
submodules at all! My misunderstanding.

I actually hadn’t considered this as added complexity. In my mind, a scoped 
module declaration seems more Swifty than a file module declaration. It builds 
on the existing syntax in Swift for defining other sorts of scopes, e.g. types.

Cheers,
Jaden Geller

> On Feb 20, 2017, at 10:41 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I think my question is: Why do we want to allow submodules that are smaller 
> than a file?  What does that give us to offset the added complexity?
> 
> Thanks,
> Jon
> 
>> On Feb 20, 2017, at 6:44 PM, Robert Widmann > > wrote:
>> 
>> 
>>> On Feb 20, 2017, at 9:36 PM, Jonathan Hull >> > wrote:
>>> 
>>> What is the rational for having modules covering only part of a file?  
>>> Wouldn’t it be less clutter to have an annotation which worked for the 
>>> whole file.  At the very least it would be nice to have an option to spell 
>>> it in a way that applies to the whole file.  Otherwise, everything will be 
>>> indented another level.
>> 
>> That is a valid spelling (Rust, IIRC, allows that spelling), but one that is 
>> easy to miss sitting in a file and makes it confusing to introduce 
>> submodules.  If you include the annotation then define a submodule later 
>> down in the file, suddenly you have to remember whether you annotated the 
>> file or whether the submodule you’ve just written is going into the 
>> top-level module.  See:
>> 
>> // -module-name=Foo
>> // module Foo {
>> module Bar; // Shorthand for “This file defines Foo.Bar”
>> 
>> /* Code */
>> 
>> // This defines “Foo.Bar.Baz”, but would you know that if it appeared below 
>> the fold?
>> module Baz {}
>> //}
>> 
>> If anything, this can be added later if evolution converges on it.
>> 
>>> 
>>> I would honestly love to see something which just maps modules to 
>>> folders/groups for simplicity sake.
>>> 
>> 
>> There is nothing about this scheme that prevents you from organizing your 
>> code this way.  However, modulo that particular method of organization, you 
>> don’t really gain much as a user of the language by imposing this 
>> restriction.
>> 
>>> I haven’t thought about it too much yet, so I could easily be missing 
>>> something obvious...
>>> 
>>> Thanks,
>>> Jon
>>> 
>>> 
 On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
 > wrote:
 
 Good Evening All,
 
 Jaden Geller and I have been considering a (sub)module system for Swift 
 that would complement the existing language but also provide sorely needed 
 modularity.  A draft of the proposal is attached to this email, but it can 
 also be read as a gist 
  if you 
 desire.
 
 Cheers,
 
 ~Robert Widmann
 
 Modular Swift
 
 Proposal: SE- 
 Authors: Robert Widmann , Jaden Geller 
 
 Review Manager: TBD
 Status: Awaiting review
  
 Introduction
 
 Almost every major programming language supports some form of modular 
 programming through constructs like (sub)modules, packages, or interfaces. 
 Swift, though it provides top-level modules to organize code under, does 
 not provide a complete implementation of any of these concepts, which has 
 led instead to the proliferation of access control levels. This has not 
 proven an effective way to decompose programs into manageable parts, and 
 exposes the need for a real system of modules to solve this modularity 
 problem once and for all.
 
 Separation of code into distinct islands of functionality should be a 
 first-class construct in the language, not dependent on external files and 
 tools or filesystems. To that end, we propose the introduction of a 
 lightweight module system for Swift.
 
 Swift-evolution thread 
 
  
 Motivation
 
 Swift has reached a point in its evolution where rich libraries and large 
 projects that take on many dependencies have matured significantly. To 
 accomodate the information-hiding and semantics-signalling needs of these 
 users at the time, Swift began its access control story with just three 
 access modifiers: public, private, and internal then grew fileprivate and 
 open as the need to express locality of implementation and 
 "subclassability" arose respectively. In doing so, Swift's access control 
 scheme has 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
Oh, you’re referring to the fact that a submodule under this proposal must be 
contained within braces? It would be purely additive to, in the future, 
annotate that the outer scope of a file is part of some given submodule.

Consider the following the following straw-man syntax that might be equivalent 
to `module Bar { func foo() { } }`:
```
module Bar follows // <- at top of file, indicating rest of file is submodule

func foo() { }
```

Does this address your question?

Thanks,
Jaden Geller

> On Feb 20, 2017, at 10:39 PM, Jonathan Hull  wrote:
> 
> 
>> On Feb 20, 2017, at 6:42 PM, Jaden Geller > > wrote:
>> 
>> Jon,
>> 
>> I think we might have miscommunicated. It is intended that outermost module 
>> is implicit; no `module` declaration is required to wrap every file. We 
>> tried to show this in the first code snippet.
>> 
>> What do you mean “covering only part of a file”?
> 
> I am assuming that the ModuleName { … }  only affects things within the 
> brackets.  Thus it is possible for only part of a file to be within a module. 
>  What are the benefits of allowing this, and are they worth the added 
> complexity?
> 
> Thanks,
> Jon
> 
> 
>> Cheers,
>> Jaden Geller
>> 
>>> On Feb 20, 2017, at 6:36 PM, Jonathan Hull via swift-evolution 
>>> > wrote:
>>> 
>>> What is the rational for having modules covering only part of a file?  
>>> Wouldn’t it be less clutter to have an annotation which worked for the 
>>> whole file.  At the very least it would be nice to have an option to spell 
>>> it in a way that applies to the whole file.  Otherwise, everything will be 
>>> indented another level.
>>> 
>>> I would honestly love to see something which just maps modules to 
>>> folders/groups for simplicity sake.
>>> 
>>> I haven’t thought about it too much yet, so I could easily be missing 
>>> something obvious...
>>> 
>>> Thanks,
>>> Jon
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
To further clarify—I think it would be accurate to say that this proposal 
introduces 2 things:

1) submodules, without changing the existing module system
2) `public` keyword for re-exporting modules

It is both unnecessary and not allowed to name the outermost module in the 
file. The `module` keyword simply introduces submodules. Notice that this works 
well with the notion of progress disclosure.

> On Feb 20, 2017, at 6:42 PM, Jaden Geller  wrote:
> 
> Jon,
> 
> I think we might have miscommunicated. It is intended that outermost module 
> is implicit; no `module` declaration is required to wrap every file. We tried 
> to show this in the first code snippet.
> 
> What do you mean “covering only part of a file”?
> 
> Cheers,
> Jaden Geller
> 
>> On Feb 20, 2017, at 6:36 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>> What is the rational for having modules covering only part of a file?  
>> Wouldn’t it be less clutter to have an annotation which worked for the whole 
>> file.  At the very least it would be nice to have an option to spell it in a 
>> way that applies to the whole file.  Otherwise, everything will be indented 
>> another level.
>> 
>> I would honestly love to see something which just maps modules to 
>> folders/groups for simplicity sake.
>> 
>> I haven’t thought about it too much yet, so I could easily be missing 
>> something obvious...
>> 
>> Thanks,
>> Jon
>> 
>> 
>>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>>> > wrote:
>>> 
>>> Good Evening All,
>>> 
>>> Jaden Geller and I have been considering a (sub)module system for Swift 
>>> that would complement the existing language but also provide sorely needed 
>>> modularity.  A draft of the proposal is attached to this email, but it can 
>>> also be read as a gist 
>>>  if you 
>>> desire.
>>> 
>>> Cheers,
>>> 
>>> ~Robert Widmann
>>> 
>>> Modular Swift
>>> 
>>> Proposal: SE- 
>>> Authors: Robert Widmann , Jaden Geller 
>>> 
>>> Review Manager: TBD
>>> Status: Awaiting review
>>>  
>>> Introduction
>>> 
>>> Almost every major programming language supports some form of modular 
>>> programming through constructs like (sub)modules, packages, or interfaces. 
>>> Swift, though it provides top-level modules to organize code under, does 
>>> not provide a complete implementation of any of these concepts, which has 
>>> led instead to the proliferation of access control levels. This has not 
>>> proven an effective way to decompose programs into manageable parts, and 
>>> exposes the need for a real system of modules to solve this modularity 
>>> problem once and for all.
>>> 
>>> Separation of code into distinct islands of functionality should be a 
>>> first-class construct in the language, not dependent on external files and 
>>> tools or filesystems. To that end, we propose the introduction of a 
>>> lightweight module system for Swift.
>>> 
>>> Swift-evolution thread 
>>>  
>>> Motivation
>>> 
>>> Swift has reached a point in its evolution where rich libraries and large 
>>> projects that take on many dependencies have matured significantly. To 
>>> accomodate the information-hiding and semantics-signalling needs of these 
>>> users at the time, Swift began its access control story with just three 
>>> access modifiers: public, private, and internal then grew fileprivate and 
>>> open as the need to express locality of implementation and 
>>> "subclassability" arose respectively. In doing so, Swift's access control 
>>> scheme has become anti-modular.
>>> 
>>>  
>>> Proposed
>>>  solution
>>> 
>>> We propose the introduction of a lightweight module system for Swift. More 
>>> than simply namspaces, a module declaration interacts with Swift's access 
>>> control to provide an API boundary that allows better control over an 
>>> interface's design.
>>> 
>>>  
>>> Detailed
>>>  design
>>> 
>>>  
>>> Syntax
>>> 
>>> A module is a named region that introduces a lexical scope into which 
>>> declarations may be nested. The name of the module can be used to access 
>>> these member declarations. A module, like other aggregate structures in 
>>> Swift, may be extended with new declarations over one or more translation 
>>> units (files).
>>> 
>>> We propose a new declaration kind, module-decl be added to the 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Jaden Geller via swift-evolution
Jon,

I think we might have miscommunicated. It is intended that outermost module is 
implicit; no `module` declaration is required to wrap every file. We tried to 
show this in the first code snippet.

What do you mean “covering only part of a file”?

Cheers,
Jaden Geller

> On Feb 20, 2017, at 6:36 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> What is the rational for having modules covering only part of a file?  
> Wouldn’t it be less clutter to have an annotation which worked for the whole 
> file.  At the very least it would be nice to have an option to spell it in a 
> way that applies to the whole file.  Otherwise, everything will be indented 
> another level.
> 
> I would honestly love to see something which just maps modules to 
> folders/groups for simplicity sake.
> 
> I haven’t thought about it too much yet, so I could easily be missing 
> something obvious...
> 
> Thanks,
> Jon
> 
> 
>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>> > wrote:
>> 
>> Good Evening All,
>> 
>> Jaden Geller and I have been considering a (sub)module system for Swift that 
>> would complement the existing language but also provide sorely needed 
>> modularity.  A draft of the proposal is attached to this email, but it can 
>> also be read as a gist 
>>  if you 
>> desire.
>> 
>> Cheers,
>> 
>> ~Robert Widmann
>> 
>> Modular Swift
>> 
>> Proposal: SE- 
>> Authors: Robert Widmann , Jaden Geller 
>> 
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> Introduction
>> 
>> Almost every major programming language supports some form of modular 
>> programming through constructs like (sub)modules, packages, or interfaces. 
>> Swift, though it provides top-level modules to organize code under, does not 
>> provide a complete implementation of any of these concepts, which has led 
>> instead to the proliferation of access control levels. This has not proven 
>> an effective way to decompose programs into manageable parts, and exposes 
>> the need for a real system of modules to solve this modularity problem once 
>> and for all.
>> 
>> Separation of code into distinct islands of functionality should be a 
>> first-class construct in the language, not dependent on external files and 
>> tools or filesystems. To that end, we propose the introduction of a 
>> lightweight module system for Swift.
>> 
>> Swift-evolution thread 
>>  
>> Motivation
>> 
>> Swift has reached a point in its evolution where rich libraries and large 
>> projects that take on many dependencies have matured significantly. To 
>> accomodate the information-hiding and semantics-signalling needs of these 
>> users at the time, Swift began its access control story with just three 
>> access modifiers: public, private, and internal then grew fileprivate and 
>> open as the need to express locality of implementation and "subclassability" 
>> arose respectively. In doing so, Swift's access control scheme has become 
>> anti-modular.
>> 
>>  
>> Proposed
>>  solution
>> 
>> We propose the introduction of a lightweight module system for Swift. More 
>> than simply namspaces, a module declaration interacts with Swift's access 
>> control to provide an API boundary that allows better control over an 
>> interface's design.
>> 
>>  
>> Detailed
>>  design
>> 
>>  
>> Syntax
>> 
>> A module is a named region that introduces a lexical scope into which 
>> declarations may be nested. The name of the module can be used to access 
>> these member declarations. A module, like other aggregate structures in 
>> Swift, may be extended with new declarations over one or more translation 
>> units (files).
>> 
>> We propose a new declaration kind, module-decl be added to the language. A 
>> proposed grammar using the new modulekeyword is given below:
>> 
>> GRAMMAR OF A MODULE DECLARATION
>> 
>> module-declaration -> `module` module-identifier module-body
>> module-name -> identifier
>> module-body -> { module-members(opt) }
>> module-members -> module-member module-members(opt)
>> module-member -> declaration | compiler-control-statement
>> GRAMMAR OF A DECLARATION
>> 
>> + declaration -> module-declaration
>>  
>> General
>>  Semantics
>> 
>> Syntax and semantics for imports, as it already supports referencing 
>> 

Re: [swift-evolution] Subclass Existentials

2017-02-02 Thread Jaden Geller via swift-evolution
It's pretty bizarre that conforming to `protocol P: Q {}` requires an explicit 
conformance to Q when Q is a class but not when Q is a protocol. It's the same 
syntax, but conformance is only "inherited" for protocols.

> On Feb 1, 2017, at 3:47 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Feb 1, 2017, at 5:11 PM, David Sweeris via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Feb 1, 2017, at 3:01 PM, David Hart via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> On 1 Feb 2017, at 22:54, Douglas Gregor  wrote:
>>> 
 
> On Jan 29, 2017, at 8:44 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> This is a nice generalization of the existing protocol composition 
> syntax. Implementation might get a little tricky — this touches a lot of 
> things, such as inheritance clauses, constraints in generic signatures, 
> and casts. It would require thorough testing.
> 
> There are also a few odd corner cases to sort out:
> 
> typealias T = SomeClass & SomeProtocol
> 
> class C : T { // should we allow this? probably yes
> }
> 
> protocol P : T { // should we allow this? probably no
> }
 
 IIRC, we already allow the latter where T is a typealias for SomeProtocol1 
 & SomeProtocol2. Why not allow it generally?
>>> 
>>> Well what would it mean? A protocol can't inherit or conform to a class.
>> 
>> That anything which conforms to that protocol must subclass SomeClass?
> 
> Yes, this is exactly what I would expect.  I was calling it a supertype 
> requirement earlier in the thread.
> 
>> 
>> - Dave Sweeris
>> ___
>> 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] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:20 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Jan 31, 2017 at 6:15 PM, Jaden Geller <jaden.gel...@gmail.com 
> <mailto:jaden.gel...@gmail.com>> wrote:
> 
>> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris <daveswee...@mac.com 
>>> <mailto:daveswee...@mac.com>> wrote:
>>> 
>>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>> 
>>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> I think that is perfectly reasonable, but then it seems weird to be able 
>>>>> to iterate over it (with no upper bound) independently of a collection). 
>>>>> It would surprise me if
>>>>> ```
>>>>> for x in arr[arr.startIndex…] { print(x) }
>>>>> ```
>>>>> yielded different results than
>>>>> ```
>>>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>>>> ```
>>>>> which it does under this model.
>>>> 
>>>> (I think this how it works... semantically, anyway) Since the upper bound 
>>>> isn't specified, it's inferred from the context.
>>>> 
>>>> In the first case, the context is as an index into an array, so the upper 
>>>> bound is inferred to be the last valid index.
>>>> 
>>>> In the second case, there is no context, so it goes to Int.max. Then, 
>>>> after the "wrong" context has been established, you try to index an array 
>>>> with numbers from the too-large range.
>>>> 
>>>> Semantically speaking, they're pretty different operations. Why is it 
>>>> surprising that they have different results?
>>>> 
>>>> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
>>>> Jaden and others have pointed out a real semantic issue.
>>>> 
>>>> A range is, to put it simply, the "stuff" between two end points. A "range 
>>>> with no upper bound" _has to be_ one that continues forever. The upper 
>>>> bound _must_ be infinity.
>>> 
>>> Depends… Swift doesn’t allow partial initializations, and neither the 
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. 
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>>> without getting into undefined behavior territory.
>>> 
>>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>>> bracket, that’s kind of a meaningless statement. I would argue that if 
>>> we’re going to represent that “infinite” range, the closest Swift spelling 
>>> would be “x..<“. That leaves the mathematically undefined notation of “[x, 
>>> ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by 
>>> similar reasoning can’t mean "(∞, x]”) return one of these:
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>> which we could then pass to the subscript function of a collection to 
>>> create the actual Range like this:
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>>> case .upperValue(let upper): returnself[self.startIndex ..< upper]
>>> }
>>> }
>>> }
>>> 
>>> I understand that you can do this from a technical perspective. But I'm 
>>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>>> number.
>> 
>> It’s not any more devoid of semantics

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:15 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> We don't have partially applied functions doubling as function calls with 
> default arguments.

I think this best summarizes my problem with simultaneously treating `0…` as a 
partially specified range (waiting for another “argument” from the collection) 
and as an infinite range (defaulting that argument to Int.max).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris <daveswee...@mac.com 
>> <mailto:daveswee...@mac.com>> wrote:
>> 
>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>> <mailto:xiaodi...@gmail.com>> wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> I think that is perfectly reasonable, but then it seems weird to be able 
>>>> to iterate over it (with no upper bound) independently of a collection). 
>>>> It would surprise me if
>>>> ```
>>>> for x in arr[arr.startIndex…] { print(x) }
>>>> ```
>>>> yielded different results than
>>>> ```
>>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>>> ```
>>>> which it does under this model.
>>> 
>>> (I think this how it works... semantically, anyway) Since the upper bound 
>>> isn't specified, it's inferred from the context.
>>> 
>>> In the first case, the context is as an index into an array, so the upper 
>>> bound is inferred to be the last valid index.
>>> 
>>> In the second case, there is no context, so it goes to Int.max. Then, after 
>>> the "wrong" context has been established, you try to index an array with 
>>> numbers from the too-large range.
>>> 
>>> Semantically speaking, they're pretty different operations. Why is it 
>>> surprising that they have different results?
>>> 
>>> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
>>> Jaden and others have pointed out a real semantic issue.
>>> 
>>> A range is, to put it simply, the "stuff" between two end points. A "range 
>>> with no upper bound" _has to be_ one that continues forever. The upper 
>>> bound _must_ be infinity.
>> 
>> Depends… Swift doesn’t allow partial initializations, and neither the 
>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. From 
>> a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>> without getting into undefined behavior territory.
>> 
>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>> bracket, that’s kind of a meaningless statement. I would argue that if we’re 
>> going to represent that “infinite” range, the closest Swift spelling would 
>> be “x..<“. That leaves the mathematically undefined notation of “[x, ∞]”, 
>> spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by similar 
>> reasoning can’t mean "(∞, x]”) return one of these:
>> enum IncompleteRange {
>> case upperValue(T)
>> case lowerValue(T)
>> }
>> which we could then pass to the subscript function of a collection to create 
>> the actual Range like this:
>> extension Collection {
>> subscript(_ ir: IncompleteRange) -> SubSequence {
>> switch ir {
>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>> case .upperValue(let upper): return self[self.startIndex ..< upper]
>> }
>> }
>> }
>> 
>> I understand that you can do this from a technical perspective. But I'm 
>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>> number.
> 
> It’s not any more devoid of semantics than a partially applied function.  It 
> is a number or index with added semantics that it provides a lower (or upper) 
> bound on the possible value specified by its type.

If we treat it as such, we shouldn’t allow users to iterate over it directly:
```
for x in 0… { // <- doesn’t make sense; only partially specified
  print(“hi”)
}
```

We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`, 
providing an overload that constructs each. It would never be ambiguous because 
`InfiniteRange ` would be the only `Sequence` and `IncompleteRange` would be 
the only one 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 11:26 AM, Dave Abrahams  wrote:
> 
> 
> on Mon Jan 30 2017, Jaden Geller  wrote:
> 
>>> On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> Why should that be out-of-bounds?  Whether it is out-of-bounds would
>>> depend on what items is.  If it's an array, that should be equivalent to
>>> 
>>>  let x = items[items.startIndex..> 
>> It seems to me that `items[0…]` would be equivalent to
>> `items[0…Int.max]` if we’re going to treat `0…` as an “infinite"
>> range, no? Otherwise, we’re either giving subscript of InfiniteRange
>> types special behavior or we’re making subscript ignore past-the-end
>> indices; `”hello”.characters[0…10]` would need to return the same as
>> “hello”.characters[0…4]` to be consistent.
> 
> What is it they say about “a foolish consistency?” ;-)
> 
> More seriously, I think you may be viewing these ranges the wrong way
> around.
> 
>0...
> 
> is not a range with an upper bound of infinity (which is, after all, not
> a number!); it's a range with *no* upper bound.  When you use the range
> for slicing, the collection substitutes its own upper bound.
> 
> HTH,
> 
> -- 
> -Dave

I think that is perfectly reasonable, but then it seems weird to be able to 
iterate over it (with no upper bound) independently of a collection). It would 
surprise me if
```
for x in arr[arr.startIndex…] { print(x) }
```
yielded different results than
```
for i in arr.startIndex… { print(arr[i]) } // CRASH
```
which it does under this model.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Why doesn't Swift allow a variable and a function with the same name?

2017-01-30 Thread Jaden Geller via swift-evolution
Not quite—you can already shadow function names:
```
func f() { print("hi") }
do {
let f = { print("bye") }
f()
}
```

You can refer to shadowed variables within their initial value—function or 
not—within a guard let or if let:
```
func f() -> (() -> ())? { return { print("hi")} }
do {
guard let f = f() else { fatalError() }
f()
}
```

BUT, you cannot refer to shadowed variables within their initial value 
otherwise:
```
func f() { print("hi") }
do {
let f = { f(); f() } // ERROR!!!
f()
}
```

This is inconsistent IMO.

> On Jan 30, 2017, at 5:17 PM, Derrick Ho <wh1pch...@gmail.com> wrote:
> 
> The answer is simple, it becomes ambiguous about whether it should get the 
> var or the function pointer
> 
> Suppose we could do this
> 
> let r = 5
> func r() {}
> 
> If we call r, should we get 5 or should we get ()->()
> 
> 
> On Mon, Jan 30, 2017 at 4:21 PM Sean Heber via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> I used to believe this was a problem, but once I internalized the idea that 
> this ugliness was a signal to choose better variable and property names, it 
> has ceased to be an issue for me and in fact, IMO, has become an asset of the 
> language.
> 
> l8r
> Sean
> 
> 
> > On Jan 30, 2017, at 3:17 PM, Jaden Geller via swift-evolution 
> > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> >
> > I personally find it kind of weird that `let x = 0; do { let x = x + 1 }` 
> > is disallowed but `let x: Int? = 0; if let x = x { }` is allowed. The 
> > former case requires you first rename the variable you plan to shadow, 
> > inconveniently:
> >
> > ```
> > let x = 0
> > do {
> >   let tempX = x // ew
> >   let x = tempX + 1
> > }
> > ```
> >
> >> On Jan 30, 2017, at 11:56 AM, Robert Widmann via swift-evolution 
> >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> >>
> >> This seems like it’s running through the same check that disallows 
> >> defining and calling a closure
> >>
> >> let randomFunc : () -> () = randomFunc()
> >>
> >>> On Jan 30, 2017, at 2:37 PM, Michael Gubik via swift-evolution 
> >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> >>>
> >>> Example that does not compile:
> >>>
> >>>let randomArray = randomArray(withCapacity: 4096)
> >>>
> >>> Compiler error: “Variable used within its own initial value”
> >>> The variable name unfortunately clashes with the function name.
> >>>
> >>> This problem forces the developer to think about an alternative name.
> >>> IMHO that’s suboptimal since many times the most canonical naming would 
> >>> be one where these two go by the same name.
> >>>
> >>> It’s not a big problem in practice but I wonder if there are plans to 
> >>> change this?
> >>>
> >>>
> >>> Thanks,
> >>> Michael Gubik
> >>>
> >>> ___
> >>> swift-evolution mailing list
> >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> >>> https://lists.swift.org/mailman/listinfo/swift-evolution 
> >>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> >>
> >> ___
> >> swift-evolution mailing list
> >> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> >> https://lists.swift.org/mailman/listinfo/swift-evolution 
> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> >
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> > https://lists.swift.org/mailman/listinfo/swift-evolution 
> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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] Strings in Swift 4

2017-01-30 Thread Jaden Geller via swift-evolution

> On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> Why should that be out-of-bounds?  Whether it is out-of-bounds would
> depend on what items is.  If it's an array, that should be equivalent to
> 
>   let x = items[items.startIndex..

Re: [swift-evolution] Initializers

2017-01-30 Thread Jaden Geller via swift-evolution
It seems to me that A should provide an `init(x: Int = 1) { self.x = x }` 
initializer in such case so B may call `super.init(x: 2)`. This initializer 
could even be made internal if necessary, but it honestly seems weird for a 
superclass to default initialize to a certain value and a subclass to default 
initialize to another.

Regardless, I definitely don’t think introducing unsafely is the right choice. 
If anything, there ought to be a compiler optimization (if there isn’t one 
already) that’ll eliminate these duplicate assignments—and I would bet there is 
if `super.init()` can be inlined.

> On Jan 28, 2017, at 10:07 AM, Victor Petrescu via swift-evolution 
>  wrote:
> 
> Hello,
> 
> My name is Victor, been a developer (C, delphi, php, java, js) for the last 
> 10 years or so and lately I had the chance to try swift. I have a 
> suggestion/question regarding initializers.
> 
> Sidenote: If this is not the correct mailing list for this can you please 
> redirect me to the right place?
> 
> Consider the following 2 classes and code:
> 
> class A {
>  var x:Int
> 
>  init() {
>  x = 1
>  }
> }
> 
> class B : A {
> override init() {
>  super.init() // Swift FORCES this call
>  x = 2
> }
> }
> 
> var a:B
> for i in 0... {
> a = B()  // Whatever... some code that inits B.
> }
> 
> This results in  x = 1 then  x = 2... the x = 1 being totally 
> useless in this particular case.
> 
> In this case, if you don't make the super init you get a compile error.
> 
> Now... I see the use of this. It ensure that all members are initialized. For 
> example if A had a private variable (another strange choice here with what 
> private means in swift but I haven't thought on it yet so... maybe is a cool 
> choice), the B init could not initialize it. I also understand that the cases 
> when you need this minor performance gain are rather rare (but they do still 
> exist). So I guess the choice for the super.init() had that reasoning.
> 
> Still... my suggestion would be to give a warning, maybe force a key word 
> before the init (like iKnowWhatImDoing init() {}), THEN in case vars are 
> still not inited give a runtime error (afaik Objective C for example gives a 
> warning). That ensures everything is ok and also allows programmers that have 
> strange cases to treat them accordingly.
> 
> Anyway... that would be my suggestion. Maybe this was discussed before 
> also... If this was discussed before can you please point me to the 
> discussion? I like to understand the choices for the tools I use.
> 
> 
> P.S. Please excuse any grammatical errors... English is not my first language.
> 
> Thank you for your time and have a great day,
> Petrescu Victor
> ___
> 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] Why doesn't Swift allow a variable and a function with the same name?

2017-01-30 Thread Jaden Geller via swift-evolution
I personally find it kind of weird that `let x = 0; do { let x = x + 1 }` is 
disallowed but `let x: Int? = 0; if let x = x { }` is allowed. The former case 
requires you first rename the variable you plan to shadow, inconveniently:

```
let x = 0
do {
  let tempX = x // ew
  let x = tempX + 1
}
```

> On Jan 30, 2017, at 11:56 AM, Robert Widmann via swift-evolution 
>  wrote:
> 
> This seems like it’s running through the same check that disallows defining 
> and calling a closure 
> 
> let randomFunc : () -> () = randomFunc()
> 
>> On Jan 30, 2017, at 2:37 PM, Michael Gubik via swift-evolution 
>> > wrote:
>> 
>> Example that does not compile:
>> 
>>let randomArray = randomArray(withCapacity: 4096)
>> 
>> Compiler error: “Variable used within its own initial value”
>> The variable name unfortunately clashes with the function name.
>> 
>> This problem forces the developer to think about an alternative name.
>> IMHO that’s suboptimal since many times the most canonical naming would be 
>> one where these two go by the same name.
>> 
>> It’s not a big problem in practice but I wonder if there are plans to change 
>> this?
>> 
>> 
>> Thanks,
>> Michael Gubik
>> 
>> ___
>> 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] Strings in Swift 4

2017-01-20 Thread Jaden Geller via swift-evolution

> On Jan 20, 2017, at 2:57 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
>> The “Empty Subscript”
>> 
>> Empty subscript seems weird. IMO, it’s because of the asymmetry
>> between subscripts and computed properties. I would favour a model
>> which unifies computed properties and subscripts (e.g. computed
>> properties could return “addressors” for in-place mutation).
>> Maybe this could be an “entireCollection”/“entireSlice" computed
>> property?
> 
> It could, but x.entireSlice is syntactically heavyweight compared to
> x[], and x[] lives on a continuum with x[a...], x[..

Re: [swift-evolution] [Review] SE-0140: Bridge Optional As Its Payload Or NSNull

2016-09-07 Thread Jaden Geller via swift-evolution
* What is your evaluation of the proposal?

I support this proposal. I work on a framework, and I was actually able to 
track down a user-reported crash to the lack of this sort of bridging. An 
engineer overlooked that an `Optional` value passed into an `Any` parameter, 
would be forwarded to the Objective-C API as an opaque object. Since we had not 
tested that particular type, we were unable to detect this issue. Adding this 
sort of bridging behavior (explicitly in the implementation of our function) is 
how we were able to fix this issue since the Objective-C API did accept 
`NSNull`.

Others on the mailing list have brought up concerns that this sort of bridging 
will defer the detection of API misuse in the case of `NSArray`. I think that, 
while that is a fair concern, it ignores other cases where this sort of 
bridging will actually fix crashes that would otherwise occur. Further, I think 
these concerns forget that fact that `Any` is only used for dynamic APIs. If 
you'd like a strongly typed `NSArray`, you would use Objective-C lightweight 
generics. I would actually argue that dynamically bridging `NSNull` to `nil` is 
most consistent with the current behavior of Swift.

For example, the following cast succeeds since `Int?` is [kinda sorta] a 
subtype of `Int`.
```
Optional.Some(3) as Any as! Int
```
Thus, in Swift you can treat an `Optional` stored inside an `Any` as if it 
were simply a `T`. In Objective-C though, this is not the case since there's no 
equivalent to this sort of dynamic `as!` cast. As such, it would be reasonable 
to bridge `Optional` to `T | NSNull` such that we can similarly treat `T?` 
as if it were an `T` in Objective-C. Given that `Any` is used in dynamic APIs 
that can be passed *any* type, I don't think it is worrisome that this will 
convert to `NSNull`. If the API is designed to only accept certain types, this 
should be annotated with generics.

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

I think so. I definitely don't think this issue is as important as fixing 
numeric bridging, but this seems like a logical improvement to the current 
bridging behavior.

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

Definitely. In my understanding, Objective-C interop is a major feature of 
Swift. The Swift team has done a fantastic job improving this since the first 
release of Swift, and this seems like a logical, incremental step in the same 
direction.

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

I'm not familiar with other languages with such comprehensive bridging features 
as Swift. Objective-C is built atop C, and thus has multiple concepts of null 
(NSNull and NULL), but it has never made sense to bridge between these because 
Objective-C is a superset of C, not an unrelated language that interops with C 
(and in this case, these separate types were necessary, something that has been 
avoided in Swift).

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

I've spent a significant number of hours dealings with issues causes by the 
lack of bridging, both with `Int8` and friends and here. The lack of bridging 
of `NSNull` and `nil` is definitely less expected than the lack of numeric 
bridging, but still problematic for those building Swift wrappers for a dynamic 
API on top of an Objective-C APIs.

> On Sep 2, 2016, at 3:50 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0140 "Bridge Optional As Its Payload Or NSNull" begins now 
> and runs through September 8, 2016. The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0140-bridge-optional-to-nsnull.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/0140-bridge-optional-to-nsnull.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 
> 

Re: [swift-evolution] [Idea] Distinguishing code comments from text comments.

2016-08-29 Thread Jaden Geller via swift-evolution
You don't have to.

#if false {
// disabled code here
}

> On Aug 29, 2016, at 1:16 PM, DifferentApps info via swift-evolution 
>  wrote:
> 
> The advantage is that you do not need to define a conditional flag for the 
> #if.
> It is also more concise.
> 
> Code disabling (with /{...}/) is a tool useful when developing algorithm, and 
> disabled code should not be aimed to remain definitively in a Swift file.
> 
> Andre Ponzo
> 
>> Le 29 août 2016 à 20:20, Magnus Ahltorp  a écrit :
>> 
>> 
>>> 27 Aug. 2016 21:03 Andre Ponzo via swift-evolution 
>>>  wrote:
>>> 
>>> 1) Advantages of disabled code ( /{ ... } ) instead of commented-out code 
>>> (/* ... */):
>> 
>>> 2) Advantages of /{ ... } instead of "if false { ... }":
>> 
>> What are the advantages of this compared to conditional compilation (#if)?
>> 
>> /Magnus
> 
> ___
> 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] Keyword for protocol conformance

2016-08-25 Thread Jaden Geller via swift-evolution
If we really want to be overkill, we could use `required` for implementing an 
un-defaulted protocol requirement, `override` for implementing a defaulted 
protocol requirement, and `default` for implementing a protocol requirement in 
a protocol extension.

I think this might be more verbose than necessary, but I think it is at least 
worth exploring some subset of those keywords. They all reuse existing ones 
too, which is mostly a plus.

The biggest benefit I see from these is confidence that what you wrote 
satisfies your expectations. Just like `try` is required to document at the 
call-site that a method throws and like argument labels are required to 
document at the call-site the usage of each parameter, it's reasonable to 
require these keywords to document these expectations at the 
implementation-site. If you forget them, the compiler can easily remind you.

Requiring `override` and/or `required` would make it clear that you're actually 
implementing the protocol. It's too easily to make a typo and define a 
completely unrelated method. If the requirement is defaulted, you would never 
know until runtime weirdness. These keywords make protocol conformance less 
stringily typed.

I'm +1 on this idea in some form (but not necessarily what I suggested).

> On Aug 24, 2016, at 10:13 AM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> Requiring "override" when anything overrides a method defined in a protocol 
> extension should be added - structure and enumerated included, of course.
> 
> Protocol extensions added inheritance to structs and enums and this should be 
> made explicit.
> 
> Sent from my iPad
> 
> On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution 
> > wrote:
> 
>>> On Aug 24, 2016, at 1:20 AM, Robert Widmann >> > wrote:
>>> 2016/08/23 20:52、Charles Srstka >> > のメッセージ:
>>> 
> On Aug 23, 2016, at 10:34 PM, Robert Widmann  > wrote:
> 
> 2016/08/23 15:29、Charles Srstka  > のメッセージ:
> 
>>> On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution 
>>> > wrote:
>>> 
>>> 2016/08/22 14:30、David Cordero via swift-evolution 
>>> > のメッセージ:
>>> 
 
 The problem:
 At the moment, looking at the code of a class or a struct implementing 
 a protocol, it is hard to know what methods are actually implementing 
 the protocol and what other methods are just part of the code of the 
 class or struct.
 
>>> 
>>> That seems like a feature, not a bug.  Why should I as an author care 
>>> whether a method contributes to a protocol conformance or not if the 
>>> compiler can tell me that kind of information itself?
>> 
>> Being able to reason about your code, what it does, and what it’s for is 
>> undesirable?
> 
> That's not an answer to the question I asked.  Why is this significant 
> enough to warrant an entire keyword?  The clutter of a whole keyword that 
> does nothing but wait for a developer to make a source-compatible 
> binary-breaking change to an interface does not seem worth it.  Maybe you 
> can convince me otherwise. 
 
 Same reason overriding a class method warrants a keyword. It expresses the 
 purpose more clearly, and allows the compiler to catch mistakes for us.
 
>>> 
>>> That's just it: The class of mistakes one can make by not being explicit 
>>> about overrides is significantly more dangerous than the class of mistakes 
>>> caused by dead code leftover from trimming protocols.
>> 
>> I am in the middle of a large refactor of code that was originally 
>> Objective-C and then Swift written like Objective-C, to more idiomatic 
>> protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols 
>> with overrides are serving very nearly the same purpose that overrides were 
>> serving in the old design; hence, I don’t really think either is more or 
>> less dangerous than the other.
>> 
 ```
 protocol MyProtocol {
 func myMethod() -> String
 }
 
 class MyClass: MyProtocol {
 
 conform func myMethod() -> String {
 return "Yuhuuu,I am conforming \\o// "
 }
 
 func whatever() {
 print("I am a boring method and I don't conform anything")
 }
 }
 ```
 
 It would be something similar to the current keyword `override` but 
 for protocols. 
 
 Apart 

Re: [swift-evolution] [Proposal draft] Bridge Optional As Its Payload Or NSNull

2016-08-24 Thread Jaden Geller via swift-evolution
Why is exposing an Optional as an opaque box less error prone than an NSNull? 
That doesn't seem obviously true to me.

> On Aug 24, 2016, at 8:00 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>>> On Aug 24, 2016, at 8:27 PM, Greg Parker via swift-evolution 
>>>  wrote:
>>> 
>>> On Aug 23, 2016, at 3:36 PM, Douglas Gregor via swift-evolution 
>>>  wrote:
>>> 
>>> Proposed solution
>>> 
>>> When an Optional value is bridged to an Objective-C object, if it 
>>> contains some value, that value should be bridged; otherwise, NSNull or 
>>> another sentinel object should be used.
>>> 
>> I don't think I like this.
>> 
>> Let me verify my understanding. If I have this:
>> 
>> // imported from ObjC
>> func f(with object: Any)
>> 
>> let s: String? = nil
>> f(s)
>> 
>> then at runtime it will call 
>> f([NSNull null])
>> ?
>> 
>> The problem is that NSNull is in fact rare in Cocoa. They are used in the 
>> Foundation containers and almost nowhere else. Passing NSNull into almost 
>> any API is going to do something confusing at runtime. If you're lucky you 
>> get a prompt error "-[NSNull something]: unrecognized selector". If you're 
>> not lucky you'll get that error somewhere much later, or something even less 
>> obviously related to NSNull and your call site. That sounds like the wrong 
>> outcome for developers who are confused or careless or unaware of an 
>> optional.
> 
> I agree, particularly since passing an array of optionals to an Objective-C 
> API is much more likely to be the result of a typo or other programmer error 
> than something actually intentional that ought to invoke the bridge.
> 
> 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] Pitch: really_is and really_as operators

2016-08-24 Thread Jaden Geller via swift-evolution
Though this performs an *extra* check over just `x as! U`, it avoids bridging 
conversions. I don't think this extra check matters though because you wouldn't 
be using `Any` in code that's performance critical enough for this to matter, 
so I'm currently -1 on this proposal.

> On Aug 24, 2016, at 6:09 PM, Jaden Geller  wrote:
> 
> Scratch that last message. Determining what's stored in `Any` was Charles's 
> original goal, and what I said made no sense. This should work:
> 
> func unbridgedCast(_ x: T, to: U.Type) -> U? {
> guard type(of: x) is U.Type else { return nil }
> return x as! U
> }
> 
> if let x = unbridgedCast(x, to: String.self) { ... }
> 
>> On Aug 24, 2016, at 6:06 PM, Jaden Geller > > wrote:
>> 
>> Actually, the code I proposed does not work. First of all, it doesn't work 
>> for subtype relations. This can easily be fixed though by changing `== 
>> U.self` to `is U`. More importantly though, it fails when `T` is an 
>> existential since `type(of:)` looks within the existential to determine the 
>> type. It would be useful if there were a way to determine the *actual* 
>> runtime representation of the value.
>> 
>>> On Aug 24, 2016, at 6:00 PM, Jaden Geller >> > wrote:
>>> 
>>> Taking that suggestion a step further, it's pretty easy to define a 
>>> function that performs this sort of casting without bridging.
>>> 
>>> func unbridgedCast(_ x: T, to: U.Type) -> U? {
>>> guard type(of: x) == U.self else { return nil }
>>> return unsafeBitCast(x, to: U.self)
>>> }
>>> 
 On Aug 24, 2016, at 5:42 PM, Xiaodi Wu via swift-evolution 
 > wrote:
 
 import Foundation
 
 let foo: Any = "Hello"
 type(of: foo) == String.self // true
 type(of: foo) == NSString.self // false
 
 let bar: Any = "Hello" as NSString
 type(of: bar) == String.self // false
 type(of: bar) == NSString.self // true
 
 Why not this?
 
 
 On Wed, Aug 24, 2016 at 19:09 Charles Srstka via swift-evolution 
 > wrote:
 MOTIVATION:
 
 SE-0083 appears to be dead in the water, having been deferred until later 
 in Swift 3 back in May and not having been heard from since then, with the 
 Swift 3 release looming closer and closer. However, the predictability 
 gains that would have been provided by this change remain desirable for 
 cases where one needs to know the actual dynamic type of an entity before 
 any bridging magic is involved. Additionally, performance-critical code 
 may desire the ability to check something’s type quickly without incurring 
 the overhead of Objective-C bridging code.
 
 PROPOSED SOLUTION:
 
 I propose the following operators: really_is, really_as, really_as?, and 
 really_as!. These operators would only return a positive result if the 
 type actually was what was being asked for, instead of something that 
 might be able to bridge to that type.
 
 DETAILED DESIGN:
 
 let foo: Any = "Foo"
 let bar: Any = NSString(string: "Bar")
 
 let fooIsString = foo is String  // true
 let fooReallyIsString = foo really_is String // true
 
 let fooIsNSString = foo is NSString  // true
 let fooReallyIsNSString = foo really_is NSString // false
 
 let barIsString = bar is String  // true
 let barReallyIsString = bar really_is String // false
 
 let barIsNSString = bar is NSString  // true
 let barReallyIsNSString = bar really_is NSString // true
 
 ALTERNATIVES CONSIDERED:
 
 Stick with using an unholy combination of Mirror and unsafeBitCast when 
 you need to know what you’ve actually got.
 
 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 
 
>>> 
>> 
> 

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


Re: [swift-evolution] Pitch: really_is and really_as operators

2016-08-24 Thread Jaden Geller via swift-evolution
Scratch that last message. Determining what's stored in `Any` was Charles's 
original goal, and what I said made no sense. This should work:

func unbridgedCast(_ x: T, to: U.Type) -> U? {
guard type(of: x) is U.Type else { return nil }
return x as! U
}

if let x = unbridgedCast(x, to: String.self) { ... }

> On Aug 24, 2016, at 6:06 PM, Jaden Geller  wrote:
> 
> Actually, the code I proposed does not work. First of all, it doesn't work 
> for subtype relations. This can easily be fixed though by changing `== 
> U.self` to `is U`. More importantly though, it fails when `T` is an 
> existential since `type(of:)` looks within the existential to determine the 
> type. It would be useful if there were a way to determine the *actual* 
> runtime representation of the value.
> 
>> On Aug 24, 2016, at 6:00 PM, Jaden Geller > > wrote:
>> 
>> Taking that suggestion a step further, it's pretty easy to define a function 
>> that performs this sort of casting without bridging.
>> 
>> func unbridgedCast(_ x: T, to: U.Type) -> U? {
>> guard type(of: x) == U.self else { return nil }
>> return unsafeBitCast(x, to: U.self)
>> }
>> 
>>> On Aug 24, 2016, at 5:42 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> import Foundation
>>> 
>>> let foo: Any = "Hello"
>>> type(of: foo) == String.self // true
>>> type(of: foo) == NSString.self // false
>>> 
>>> let bar: Any = "Hello" as NSString
>>> type(of: bar) == String.self // false
>>> type(of: bar) == NSString.self // true
>>> 
>>> Why not this?
>>> 
>>> 
>>> On Wed, Aug 24, 2016 at 19:09 Charles Srstka via swift-evolution 
>>> > wrote:
>>> MOTIVATION:
>>> 
>>> SE-0083 appears to be dead in the water, having been deferred until later 
>>> in Swift 3 back in May and not having been heard from since then, with the 
>>> Swift 3 release looming closer and closer. However, the predictability 
>>> gains that would have been provided by this change remain desirable for 
>>> cases where one needs to know the actual dynamic type of an entity before 
>>> any bridging magic is involved. Additionally, performance-critical code may 
>>> desire the ability to check something’s type quickly without incurring the 
>>> overhead of Objective-C bridging code.
>>> 
>>> PROPOSED SOLUTION:
>>> 
>>> I propose the following operators: really_is, really_as, really_as?, and 
>>> really_as!. These operators would only return a positive result if the type 
>>> actually was what was being asked for, instead of something that might be 
>>> able to bridge to that type.
>>> 
>>> DETAILED DESIGN:
>>> 
>>> let foo: Any = "Foo"
>>> let bar: Any = NSString(string: "Bar")
>>> 
>>> let fooIsString = foo is String  // true
>>> let fooReallyIsString = foo really_is String // true
>>> 
>>> let fooIsNSString = foo is NSString  // true
>>> let fooReallyIsNSString = foo really_is NSString // false
>>> 
>>> let barIsString = bar is String  // true
>>> let barReallyIsString = bar really_is String // false
>>> 
>>> let barIsNSString = bar is NSString  // true
>>> let barReallyIsNSString = bar really_is NSString // true
>>> 
>>> ALTERNATIVES CONSIDERED:
>>> 
>>> Stick with using an unholy combination of Mirror and unsafeBitCast when you 
>>> need to know what you’ve actually got.
>>> 
>>> 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 
>>> 
>> 
> 

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


Re: [swift-evolution] Pitch: really_is and really_as operators

2016-08-24 Thread Jaden Geller via swift-evolution
Actually, the code I proposed does not work. First of all, it doesn't work for 
subtype relations. This can easily be fixed though by changing `== U.self` to 
`is U`. More importantly though, it fails when `T` is an existential since 
`type(of:)` looks within the existential to determine the type. It would be 
useful if there were a way to determine the *actual* runtime representation of 
the value.

> On Aug 24, 2016, at 6:00 PM, Jaden Geller  wrote:
> 
> Taking that suggestion a step further, it's pretty easy to define a function 
> that performs this sort of casting without bridging.
> 
> func unbridgedCast(_ x: T, to: U.Type) -> U? {
> guard type(of: x) == U.self else { return nil }
> return unsafeBitCast(x, to: U.self)
> }
> 
>> On Aug 24, 2016, at 5:42 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> import Foundation
>> 
>> let foo: Any = "Hello"
>> type(of: foo) == String.self // true
>> type(of: foo) == NSString.self // false
>> 
>> let bar: Any = "Hello" as NSString
>> type(of: bar) == String.self // false
>> type(of: bar) == NSString.self // true
>> 
>> Why not this?
>> 
>> 
>> On Wed, Aug 24, 2016 at 19:09 Charles Srstka via swift-evolution 
>> > wrote:
>> MOTIVATION:
>> 
>> SE-0083 appears to be dead in the water, having been deferred until later in 
>> Swift 3 back in May and not having been heard from since then, with the 
>> Swift 3 release looming closer and closer. However, the predictability gains 
>> that would have been provided by this change remain desirable for cases 
>> where one needs to know the actual dynamic type of an entity before any 
>> bridging magic is involved. Additionally, performance-critical code may 
>> desire the ability to check something’s type quickly without incurring the 
>> overhead of Objective-C bridging code.
>> 
>> PROPOSED SOLUTION:
>> 
>> I propose the following operators: really_is, really_as, really_as?, and 
>> really_as!. These operators would only return a positive result if the type 
>> actually was what was being asked for, instead of something that might be 
>> able to bridge to that type.
>> 
>> DETAILED DESIGN:
>> 
>> let foo: Any = "Foo"
>> let bar: Any = NSString(string: "Bar")
>> 
>> let fooIsString = foo is String  // true
>> let fooReallyIsString = foo really_is String // true
>> 
>> let fooIsNSString = foo is NSString  // true
>> let fooReallyIsNSString = foo really_is NSString // false
>> 
>> let barIsString = bar is String  // true
>> let barReallyIsString = bar really_is String // false
>> 
>> let barIsNSString = bar is NSString  // true
>> let barReallyIsNSString = bar really_is NSString // true
>> 
>> ALTERNATIVES CONSIDERED:
>> 
>> Stick with using an unholy combination of Mirror and unsafeBitCast when you 
>> need to know what you’ve actually got.
>> 
>> 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
> 

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


Re: [swift-evolution] Pitch: really_is and really_as operators

2016-08-24 Thread Jaden Geller via swift-evolution
Taking that suggestion a step further, it's pretty easy to define a function 
that performs this sort of casting without bridging.

func unbridgedCast(_ x: T, to: U.Type) -> U? {
guard type(of: x) == U.self else { return nil }
return unsafeBitCast(x, to: U.self)
}

> On Aug 24, 2016, at 5:42 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> import Foundation
> 
> let foo: Any = "Hello"
> type(of: foo) == String.self // true
> type(of: foo) == NSString.self // false
> 
> let bar: Any = "Hello" as NSString
> type(of: bar) == String.self // false
> type(of: bar) == NSString.self // true
> 
> Why not this?
> 
> 
> On Wed, Aug 24, 2016 at 19:09 Charles Srstka via swift-evolution 
> > wrote:
> MOTIVATION:
> 
> SE-0083 appears to be dead in the water, having been deferred until later in 
> Swift 3 back in May and not having been heard from since then, with the Swift 
> 3 release looming closer and closer. However, the predictability gains that 
> would have been provided by this change remain desirable for cases where one 
> needs to know the actual dynamic type of an entity before any bridging magic 
> is involved. Additionally, performance-critical code may desire the ability 
> to check something’s type quickly without incurring the overhead of 
> Objective-C bridging code.
> 
> PROPOSED SOLUTION:
> 
> I propose the following operators: really_is, really_as, really_as?, and 
> really_as!. These operators would only return a positive result if the type 
> actually was what was being asked for, instead of something that might be 
> able to bridge to that type.
> 
> DETAILED DESIGN:
> 
> let foo: Any = "Foo"
> let bar: Any = NSString(string: "Bar")
> 
> let fooIsString = foo is String  // true
> let fooReallyIsString = foo really_is String // true
> 
> let fooIsNSString = foo is NSString  // true
> let fooReallyIsNSString = foo really_is NSString // false
> 
> let barIsString = bar is String  // true
> let barReallyIsString = bar really_is String // false
> 
> let barIsNSString = bar is NSString  // true
> let barReallyIsNSString = bar really_is NSString // true
> 
> ALTERNATIVES CONSIDERED:
> 
> Stick with using an unholy combination of Mirror and unsafeBitCast when you 
> need to know what you’ve actually got.
> 
> 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

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


Re: [swift-evolution] [Proposal draft] Bridge Optional As Its Payload Or NSNull

2016-08-24 Thread Jaden Geller via swift-evolution
I'd imagine an implementation something like this (but, in the bridging logic, 
not as a top level function…):

func dynamicCast(_ array: [Any]) -> [T?] {
var _type: CollectionCastType?
func assertType(_ checkType: CollectionCastType) {
guard let type = _type else {
_type = checkType
return
}
assert(type == checkType)
}
return array.map { element in
switch element {
case let element as T?:
assertType(.normal)
return element
case let element as T:
assertType(.lifting)
return element
case is NSNull:
assertType(.lifting)
return nil
default:
fatalError("Incorrect types")
}
}
}

Essentially, it either identifies an array as being entirely of `T?` (normal 
cast type) or being entirely of both `T` and `NSNull` (lifted cast type) and 
returns the proper value. In the bridging logic, this would be done lazily 
(like how `NSArray`s bridged to `[T]` lazily check element type on access).

What are your thoughts?

> On Aug 24, 2016, at 4:08 PM, Jaden Geller  wrote:
> 
> First of all, I'm really happy with this proposal so far. I really appreciate 
> the work that's been done to improve Swift and Objective-C interoperability.
> 
> Now, question: Does this proposal also improve bridging from Objective-C to 
> Swift or only the other direction? For example, let's say an `[Any]` contains 
> either `Foo` or `NSNull`. Could this bridge to Swift as `[Foo?]`? I'd like to 
> be able to write
> 
> let x = [Foo(), Foo(), nil] as [Foo?] as [Any]
> let x2 = x as! [Foo?] // Already works
> 
> let y = [Foo(), Foo(), NSNull()] as [Any]
> let y2 = y as! [Foo?] // Should work
> 
> and have this succeed. That is, an `[Any]` can be cast to `[T?]` either if it 
> only contains `T` and `NSNull` or if it only contains `T?`, not some 
> combination of both.
> 
>> On Aug 24, 2016, at 11:20 AM, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Aug 24, 2016, at 4:16 AM, David Rönnqvist >> > wrote:
>>> 
>>> I have some problems understanding the scope of this proposal. More 
>>> specifically if it’s limited to arrays and dictionaries or if it’s broader 
>>> than that, and if it’s limited to objects that originate in Swift or if the 
>>> same applies for objects that originate in Objective-C code.
>> 
>> It’s broader than that. It affects any Optional value that is put into an 
>> ‘Any’ and passed to Objective-C. Note, however, that if you have a nullable 
>> parameter in Objective-C, e.g.,
>> 
>>  -(void)methodWithObject:(nullable id)object;
>> 
>> Which comes into Swift as
>> 
>>  func method(with object: Any?)
>> 
>> Then ‘nil’ will be passed through as ‘nil’. This only affects the case where 
>> you’re passing a Swift optional to a non-optional parameter:
>> 
>>  -(void)methodWithNonNullObject:(nonnull id)object;
>> 
>>  func method(withNonNullObject object: Any)
>> 
>>> 
>>> For me, it makes sense that Swift arrays of type [C?] and [Any] would 
>>> bridge to Objective-C as NSArrays bridge nils to NSNull. That feels like 
>>> the most natural way of representing those missing values in Objective-C. 
>> 
>> Right. The alternative is that nil values bridge to an opaque box type known 
>> only to the Swift runtime. NSNull seems strictly better here, because 
>> Objective-C code can reason about it.
>> 
>>> For dictionaries of type [K:C?] and [K:Any] I feel that bridging Swift nils 
>>> to NSNull is pretty straight forward and allows for the distinction of a 
>>> key with no value and a key with an explicit nil value. However, I feel 
>>> that the same doesn’t work in the other direction. If a NSNull value in an 
>>> Objective-C NSDictionary would bridge to a nil value it wouldn’t be 
>>> possible to distinguish between a key without a value and key with a nil 
>>> value (something one might have to do when checking the KVO change 
>>> dictionary).  
>> 
>> NSNulls are handled dynamically. If you wanted to check whether Objective-C 
>> put an ‘NSNull’ in there explicitly, you can do so with “as? NSNull”.  If 
>> instead you do “as? SomeType?”, the NSNull will become the ‘nil’ value in 
>> the SomeType.
>> 
>>> 
>>> There are also some APIs that make a distinction between NSNull and nil, 
>>> for example action(for:forKey:) on CALayerDelegate. Does this proposal have 
>>> any impact on those APIs?
>> 
>> That method returns “CAAction?”, so ‘nil’ will come through as ‘nil’ and 
>> NSNull can be stored in the .some(x).
>> 
>>  - Doug
>> 
>>> 
>>> - David
>>> 
 On 24 Aug 2016, at 00:36, Douglas Gregor via swift-evolution 
 > wrote:
 
 Introduction
 
 Optionals can be used as values of the type 

Re: [swift-evolution] [Proposal draft] Bridge Optional As Its Payload Or NSNull

2016-08-24 Thread Jaden Geller via swift-evolution
First of all, I'm really happy with this proposal so far. I really appreciate 
the work that's been done to improve Swift and Objective-C interoperability.

Now, question: Does this proposal also improve bridging from Objective-C to 
Swift or only the other direction? For example, let's say an `[Any]` contains 
either `Foo` or `NSNull`. Could this bridge to Swift as `[Foo?]`? I'd like to 
be able to write

let x = [Foo(), Foo(), nil] as [Foo?] as [Any]
let x2 = x as! [Foo?] // Already works

let y = [Foo(), Foo(), NSNull()] as [Any]
let y2 = y as! [Foo?] // Should work

and have this succeed. That is, an `[Any]` can be cast to `[T?]` either if it 
only contains `T` and `NSNull` or if it only contains `T?`, not some 
combination of both.

> On Aug 24, 2016, at 11:20 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
>> On Aug 24, 2016, at 4:16 AM, David Rönnqvist > > wrote:
>> 
>> I have some problems understanding the scope of this proposal. More 
>> specifically if it’s limited to arrays and dictionaries or if it’s broader 
>> than that, and if it’s limited to objects that originate in Swift or if the 
>> same applies for objects that originate in Objective-C code.
> 
> It’s broader than that. It affects any Optional value that is put into an 
> ‘Any’ and passed to Objective-C. Note, however, that if you have a nullable 
> parameter in Objective-C, e.g.,
> 
>   -(void)methodWithObject:(nullable id)object;
> 
> Which comes into Swift as
> 
>   func method(with object: Any?)
> 
> Then ‘nil’ will be passed through as ‘nil’. This only affects the case where 
> you’re passing a Swift optional to a non-optional parameter:
> 
>   -(void)methodWithNonNullObject:(nonnull id)object;
> 
>   func method(withNonNullObject object: Any)
> 
>> 
>> For me, it makes sense that Swift arrays of type [C?] and [Any] would bridge 
>> to Objective-C as NSArrays bridge nils to NSNull. That feels like the most 
>> natural way of representing those missing values in Objective-C. 
> 
> Right. The alternative is that nil values bridge to an opaque box type known 
> only to the Swift runtime. NSNull seems strictly better here, because 
> Objective-C code can reason about it.
> 
>> For dictionaries of type [K:C?] and [K:Any] I feel that bridging Swift nils 
>> to NSNull is pretty straight forward and allows for the distinction of a key 
>> with no value and a key with an explicit nil value. However, I feel that the 
>> same doesn’t work in the other direction. If a NSNull value in an 
>> Objective-C NSDictionary would bridge to a nil value it wouldn’t be possible 
>> to distinguish between a key without a value and key with a nil value 
>> (something one might have to do when checking the KVO change dictionary).  
> 
> NSNulls are handled dynamically. If you wanted to check whether Objective-C 
> put an ‘NSNull’ in there explicitly, you can do so with “as? NSNull”.  If 
> instead you do “as? SomeType?”, the NSNull will become the ‘nil’ value in the 
> SomeType.
> 
>> 
>> There are also some APIs that make a distinction between NSNull and nil, for 
>> example action(for:forKey:) on CALayerDelegate. Does this proposal have any 
>> impact on those APIs?
> 
> That method returns “CAAction?”, so ‘nil’ will come through as ‘nil’ and 
> NSNull can be stored in the .some(x).
> 
>   - Doug
> 
>> 
>> - David
>> 
>>> On 24 Aug 2016, at 00:36, Douglas Gregor via swift-evolution 
>>> > wrote:
>>> 
>>> Introduction
>>> 
>>> Optionals can be used as values of the type Any, but only bridge as opaque 
>>> objects in Objective-C. We should bridge Optionals with some value by 
>>> bridging the wrapped value, and bridge nils to the NSNull singleton.
>>> 
>>> Swift-evolution thread: TBD 
>>> 
>>>  
>>> Motivation
>>> 
>>> SE-0116 
>>> 
>>>  changed how Objective-C's id and untyped collections import into Swift to 
>>> use the Any type. This makes it much more natural to pass in Swift value 
>>> types such as String and Array, but introduces the opportunity for 
>>> optionality mismatches, since an Any can contain a wrapped Optional value 
>>> just like anything else. Our current behavior, where Optional is given only 
>>> the default opaque bridging behavior, leads to brittle transitivity 
>>> problems with collection subtyping. For example, an array of Optional 
>>> objects bridges to an NSArray of opaque objects, unusable from ObjC:
>>> 
>>> class C {}
>>> let objects: [C?] = [C(), nil, C()]
>>> The more idiomatic mapping would be to use NSNull or some other sentinel to 
>>> represent the missing values 

Re: [swift-evolution] [Proposal draft] Bridge Numeric Types to NSNumber and Cocoa Structs to NSValue

2016-08-23 Thread Jaden Geller via swift-evolution
Strong +1 to this proposal. Lack of implicit bridging for 
Int8/Int16/Int32/Int64 types has caused crashes in production code I've worked 
with, so this is a real problem. Now that `id` is imported as `Any`, it's even 
easy to run into these crashes since there's no compile-time error when you 
pass an `Int8` into Objective-C as `Any` and try to use it as if it were an 
`NSNumber`.

> On Aug 23, 2016, at 3:36 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Introduction
> 
> A handful of Swift numeric types are bridged to NSNumber when passed into 
> Objective-C object contexts. We should extend this bridging behavior to all 
> Swift numeric types. We should also bridge common Cocoa structs such as 
> NSRangeby boxing them into NSValue objects.
> 
> Swift-evolution thread: TBD 
> 
>  
> Motivation
> 
> SE-0116 
> 
>  changed how Objective-C's id and untyped collections import into Swift to 
> use the Any type. This makes it much more natural to pass in Swift value 
> types such as String and Array, but introduces the hazard of passing in types 
> that don't bridge well to Objective-C objects. Particularly problematic are 
> number types; whereas Int, UInt, and Double will automatically bridge as 
> NSNumber, other-sized numeric types fall back to opaque boxing:
> 
> let i = 17
> let plist = ["seventeen": i]
> // OK
> try! NSJSONSerialization.data(withJSONObject: plist)
> 
> let j: UInt8 = 38
> let brokenPlist = ["thirty-eight": j]
> // Will throw because `j` didn't bridge to a JSON type
> try! NSJSONSerialization.data(withJSONObject: brokenPlist)
> We had shied away from enabling this bridging for all numeric types in the 
> Swift 1.x days, among other reasons because we allowed implicit bridging 
> conversions in both directions from Swift value types to NS objects and back, 
> which meant that you could slowly and brokenly convert between any two 
> numeric types transitively via NSNumber if we allowed this. We killed the 
> implicit conversions completely with SE-0072 
> 
>  so that is no longer a concern, so expanding the bridging behavior should no 
> longer be a major problem, since it must now always be explicitly asked for.
> 
> There are also many Cocoa APIs that accept NSArray and NSDictionary objects 
> with members that are NSValue-boxed structs. Matt Neuberg highlights Core 
> Automation as an example in this bug report 
> . With id-as-Any, it's natural to 
> expect this to work:
> 
> anim.toValue = CGPoint.zero
> However, the CGPoint value does not box as a meaningful Objective-C object, 
> so this currently breaks Core Animation at runtime despite compiling 
> successfully. It would be more idiomatic to bridge these types to NSValue.
> 
>  
> Proposed
>  solution
> 
> All of Swift's number types should be made to bridge to NSNumber when used as 
> objects in Objective-C:
> 
> Int8
> Int16
> Int32
> Int64
> UInt8
> UInt16
> UInt32
> UInt64
> Float
> Double
> Cocoa structs with existing NSValue factory and property support should be 
> made to bridge to NSValue when used as objects:
> 
> NSRange
> CGPoint
> CGVector
> CGSize
> CGRect
> CGAffineTransform
> UIEdgeInsets
> UIOffset
> CATransform3D
> CMTime
> CMTimeRange
> CMTimeMapping
> MKCoordinate
> MKCoordinateSpan
> SCNVector3
> SCNVector4
> SCNMatrix4
>  
> Detailed
>  design
> 
> Bridged NSNumber and NSValue objects must be castable back to their original 
> Swift value types. NSValue normally preserves the type information of its 
> included struct in its objCType property. We can check the objCType of an 
> NSValue instance when attempting to cast back to a specific bridged struct 
> type.
> 
> NSNumber is a bit trickier, since Cocoa's implementation does not generally 
> guarantee to remember the exact number type an instance was constructed from. 
> We can instead say that casting an NSNumber to a Swift number type succeeds 
> if the value of the NSNumber is exactly representable as the target type. 
> This is imperfect, since it means that an NSNumbercan potentially be cast to 
> a different type from the original value, but it at least ensures that Swift 
> values round-trip through the bridge without depending on NSNumber 
> implementation details.
> 
>  
> 

Re: [swift-evolution] Multi dimensional - iterator, Iterator2D, Iterator3D

2016-07-30 Thread Jaden Geller via swift-evolution
What benefit do Iterator2D and Iterator3D provide that nesting does not?

> On Jul 30, 2016, at 1:48 PM, Ted F.A. van Gaalen via swift-evolution 
>  wrote:
> 
> Hi Chris,
> 
> thanks for the tip about Hirundo app!
> 
> A positive side-effect of removing the classical for;; loop
>  (yes, it’s me saying this :o)  is that it forces me to find
> a good and generic equivalent for it, 
> making the conversion of my for;;s to 3.0 easier.
> which is *not* based on collections or sequences and
> does not rely on deeper calls to Sequence etc.
> 
> so, I’ve made the functions [iterator, iterator2D, iterator3D]  (hereunder)
> wich btw clearly demonstrate the power and flexibility of Swift. 
> 
> Very straightforward, and efficient (i assume) just like the classical for;; 
> loop.  
> It works quite well in my sources.
> 
> As a spin-off,  I’ve extended these to iterators for matrices 2D and cubes? 
> 3D...
> 
> Question: 
> Perhaps implementing “multi dimensional iterator functions
> in Swift might  be a good idea. so that is no longer necessary to 
> nest/nest/nest iterators. 
> 
> Met vriendelijke groeten, sorry for my “intensity” in discussing the 
> classical for;; 
> I'll have to rethink this for;; again..  
> Thanks, Ted.
> 
> Any remarks ( all ), suggestions about the code hereunder:  ? 
> 
> protocol NumericType
> {
> func +(lhs: Self, rhs: Self) -> Self
> func -(lhs: Self, rhs: Self) -> Self
> func *(lhs: Self, rhs: Self) -> Self
> func /(lhs: Self, rhs: Self) -> Self
> func %(lhs: Self, rhs: Self) -> Self
> }
> 
> extension Double : NumericType { }
> extension Float  : NumericType { }
> extension CGFloat: NumericType { }
> extension Int: NumericType { }
> extension Int8   : NumericType { }
> extension Int16  : NumericType { }
> extension Int32  : NumericType { }
> extension Int64  : NumericType { }
> extension UInt   : NumericType { }
> extension UInt8  : NumericType { }
> extension UInt16 : NumericType { }
> extension UInt32 : NumericType { }
> extension UInt64 : NumericType { }
> 
> 
> /// Simple iterator with generic parameters, with just a few lines of code.
> /// for most numeric types (see above)
> /// Usage Example:
> ///
> ///   iterate(xmax, { $0 > xmin}, -xstep,
> ///{x in
> ///print("x = \(x)")
> ///return true  // returning false acts like a break
> /// } )
> ///
> ///  -Parameter vstart: Initial value
> ///  -Parameter step:The iteration stepping value.
> ///  -Parameter test:A block with iteration test. e.g. {$0 > 10}
> ///
> ///  -Parameter block:   A block to be executed with each step.
> ///   The block must include a return true (acts like "continue")
> ///   or false (acts like "break")
> ///  -Please Note: 
> ///  There is minor precision loss ca: 1/1000 ... 1/500 
> ///  when iterating with floating point numbers.
> ///  However, in most cases this can be safely ignored.
> ///  made by ted van gaalen.
> 
> 
> func iterate (
> vstart:  T,
>_ vstep:  T,
>_  test: (T) -> Bool,
>_ block: (T) -> Bool )
> {
> var current = vstart
> 
> while test(current) && block(current)
> {
> current = current + vstep
> }
> }
> 
> 
> /// X,Y 2D matrix (table) iterator with generic parameters
> func iterate2D (
>  xstart:  T,  _ xstep: T, _ xtest: (T) -> Bool,
>_ ystart:  T,  _ ystep: T, _ ytest: (T) -> Bool,
>_ block: (T,T) -> Bool )
> {
> var xcurrent = xstart
> var ycurrent = ystart
> 
> var dontStop = true
> 
> while xtest(xcurrent) && dontStop
> {
> ycurrent = ystart
> while ytest(ycurrent) && dontStop
> {
> dontStop = block(xcurrent, ycurrent)
> ycurrent = ycurrent + ystep
> }
> xcurrent = xcurrent + xstep
> }
> }
> 
> 
> /// X,Y,Z 3D (cubic) iterator with generic parameters:
> 
> func iterate3D (
> xstart:  T,  _ xstep: T, _ xtest: (T) -> Bool,
>   _ ystart:  T,  _ ystep: T, _ ytest: (T) -> Bool,
>   _ zstart:  T,  _ zstep: T, _ ztest: (T) -> Bool,
>   _ block: (T,T,T) -> Bool )
> {
> var xcurrent = xstart
> var ycurrent = ystart
> var zcurrent = zstart
> 
> var dontStop = true
> 
> while xtest(xcurrent) && dontStop
> {
> ycurrent = ystart
> while ytest(ycurrent) && dontStop
> {
> zcurrent = zstart
> while ztest(zcurrent) && dontStop
> {
> dontStop = block(xcurrent, ycurrent, zcurrent)
> zcurrent = zcurrent + zstep
> }
> ycurrent = ycurrent + ystep
> }
> xcurrent = xcurrent + xstep
> }
> }
> 
> 
> func testIterator()
> {
> iterate(0.0, 0.5, {$0 < 1000.0} ,
> { value in
> print("Value = \(value) ")
> return true
> } )
> 
> let 

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-23 Thread Jaden Geller via swift-evolution
What if you wanted to filter such that you keep values less than some element 
that happens to be positive zero; might that keep around any negative zeros? 
Seems problematic.

> On Jul 22, 2016, at 7:53 PM, Dave Abrahams <dabrah...@apple.com> wrote:
> 
> 
>> on Fri Jul 22 2016, Xiaodi Wu  wrote:
>> 
>>> On Fri, Jul 22, 2016 at 9:38 PM, <jaden.gel...@gmail.com> wrote:
>>> 
>>> This seems reasonable to me. I don't see why `===` has to do a total order
>>> comparison when we already have another operator, `<=>`, that does that.
>> 
>> I take it back. It wouldn't solve the issue that generic `<` would
>> still behave in surprising ways, where two equal floating point values
>> represented differently might be less than each other or greater than
>> each other.
> 
> I wonder if that's really a problem.  What generic algorithm are you
> going to run on a collection of floats where it *would* be problematic?
> Hmm, stableSort would not necessarily preserve the order of zeros in the
> original collection if it contained both positive and negative zeros.
> 
>> I think what we really want is all identity and comparison divorced
>> from IEEE totalOrder.
> 
> That might work.  Thanks for thinking this problem through; keep it up!
> 
>>> On Jul 22, 2016, at 7:35 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>> 
>>> On Fri, Jul 22, 2016 at 9:28 PM, Dave Abrahams <dabrah...@apple.com>
>>> wrote:
>>> 
>>>> 
>>>>> on Fri Jul 22 2016, Xiaodi Wu  wrote:
>>>>> 
>>>>> On Fri, Jul 22, 2016 at 9:13 PM, Matthew Johnson <
>>>> matt...@anandabits.com>
>>>>> wrote:
>>>>> 
>>>>>> 
>>>>>> On Jul 22, 2016, at 9:10 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>>>> 
>>>>>> On Fri, Jul 22, 2016 at 9:08 PM, Matthew Johnson <
>>>> matt...@anandabits.com>
>>>>>> wrote:
>>>>>> 
>>>>>>> 
>>>>>>> On Jul 22, 2016, at 9:04 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>>>>> 
>>>>>>> On Fri, Jul 22, 2016 at 8:57 PM, Matthew Johnson <
>>>> matt...@anandabits.com>
>>>>>>> wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> On Jul 22, 2016, at 8:54 PM, Xiaodi Wu via swift-evolution <
>>>>>>>> swift-evolution@swift.org> wrote:
>>>>>>>> 
>>>>>>>> On Fri, Jul 22, 2016 at 8:52 PM, Jaden Geller via swift-evolution <
>>>>>>>> swift-evolution@swift.org> wrote:
>>>>>>>> 
>>>>>>>>> "The totalOrder predicate will order these cases, and it also
>>>>>>>>> distinguishes between different representations of NaNs and between
>>>> the
>>>>>>>>> same decimal floating point number encoded in different ways."
>>>>>>>>> - [Wikipedia](
>>>> https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate
>>>>>>>>> )
>>>>>>>>> 
>>>>>>>>> Sounds like `===` should not return `true` for zeros of different
>>>>>>>>> signs, then.
>>>>>>>> 
>>>>>>>> Fair enough; the result of that will be, as Pyry noted above, that:
>>>>>>>> 
>>>>>>>> ```
>>>>>>>> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
>>>>>>>> ```
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Maybe we need floating point specific implementations of some
>>>> algorithms
>>>>>>>> to resolve this problem?
>>>>>>>> 
>>>>>>>> It doesn’t seem like there is a way to provide the semantics
>>>> required by
>>>>>>>> generic algorithms and still provide the expected behavior for
>>>> floating
>>>>>>>> point values.
>>>>>>> 
>>>>>>> Well, what I'm trying to say is that generic algorithms such as
>>>>>>> `index(of:)` require only an equivalence relation. For floating point
>>>>>>> types, there are three ways to slice it:
>>>>>>> 
>>>>>>> 1. NaN != NaN a

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
This seems reasonable to me. I don't see why `===` has to do a total order 
comparison when we already have another operator, `<=>`, that does that.

> On Jul 22, 2016, at 7:35 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
>> On Fri, Jul 22, 2016 at 9:28 PM, Dave Abrahams <dabrah...@apple.com> wrote:
>> 
>> on Fri Jul 22 2016, Xiaodi Wu  wrote:
>> 
>> > On Fri, Jul 22, 2016 at 9:13 PM, Matthew Johnson <matt...@anandabits.com>
>> > wrote:
>> >
>> >>
>> >> On Jul 22, 2016, at 9:10 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>> >>
>> >> On Fri, Jul 22, 2016 at 9:08 PM, Matthew Johnson <matt...@anandabits.com>
>> >> wrote:
>> >>
>> >>>
>> >>> On Jul 22, 2016, at 9:04 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>> >>>
>> >>> On Fri, Jul 22, 2016 at 8:57 PM, Matthew Johnson <matt...@anandabits.com>
>> >>>  wrote:
>> >>>
>> >>>>
>> >>>> On Jul 22, 2016, at 8:54 PM, Xiaodi Wu via swift-evolution <
>> >>>> swift-evolution@swift.org> wrote:
>> >>>>
>> >>>> On Fri, Jul 22, 2016 at 8:52 PM, Jaden Geller via swift-evolution <
>> >>>> swift-evolution@swift.org> wrote:
>> >>>>
>> >>>>> "The totalOrder predicate will order these cases, and it also
>> >>>>> distinguishes between different representations of NaNs and between the
>> >>>>> same decimal floating point number encoded in different ways."
>> >>>>> - [Wikipedia](
>> >>>>> https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate
>> >>>>> )
>> >>>>>
>> >>>>> Sounds like `===` should not return `true` for zeros of different
>> >>>>> signs, then.
>> >>>>>
>> >>>>
>> >>>> Fair enough; the result of that will be, as Pyry noted above, that:
>> >>>>
>> >>>> ```
>> >>>> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
>> >>>> ```
>> >>>>
>> >>>>
>> >>>> Maybe we need floating point specific implementations of some algorithms
>> >>>> to resolve this problem?
>> >>>>
>> >>>> It doesn’t seem like there is a way to provide the semantics required by
>> >>>> generic algorithms and still provide the expected behavior for floating
>> >>>> point values.
>> >>>>
>> >>>
>> >>> Well, what I'm trying to say is that generic algorithms such as
>> >>> `index(of:)` require only an equivalence relation. For floating point
>> >>> types, there are three ways to slice it:
>> >>>
>> >>> 1. NaN != NaN and +0 == -0 [what the traditional comparison operators are
>> >>> constrained to do]
>> >>> 2. NaN == NaN, +0 == -0, and the same number encoded different ways
>> >>> compare equal
>> >>> 3. NaN == NaN, +0 != -0, and the same number encoded different ways
>> >>> compare not equal
>> >>>
>> >>> Both #2 and #3 can fall out of valid equivalence relations; if `===`
>> >>> behaved like #2 for FloatingPoint types, then generic algorithms work 
>> >>> just
>> >>> fine. If we insist on using a total ordering defined by `<=>` all the 
>> >>> time,
>> >>> then we've got problems.
>> >>>
>> >>>
>> >>> And if we don’t then we’re back to 3 different concepts of equality.
>> >>> There is definitely a tradeoff no matter what we choose.
>> >>>
>> >>
>> >> If some types have three concepts of equality, each with their particular
>> >> use, why must we eliminate one of them?
>> >>
>> >>
>> >> This isn’t about eliminating concepts of equality for a type.  They can
>> >> have 42 if they want.
>> >>
>> >> This is about the right way to define the semantics of specific
>> >> protocols.  It says nothing about additional notions of equality a type 
>> >> may
>> >> have available.
>> >>
>> >> The difficulty is finding a design for the protocols that makes sense with
>> >> floating point types

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
> 1. NaN != NaN and +0 == -0 [what the traditional comparison operators are 
> constrained to do]
> 2. NaN == NaN, +0 == -0, and the same number encoded different ways compare 
> equal
> 3. NaN == NaN, +0 != -0, and the same number encoded different ways compare 
> not equal

Though it seems super confusing that a language have THREE ways to compare 
values, that does almost seem necessary here. Do we actually need an operator 
that performs #3? I understand that that is equality under total ordering, but 
couldn't users just write `(a <=> b) == .same` if they want that?

> On Jul 22, 2016, at 7:04 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Fri, Jul 22, 2016 at 8:57 PM, Matthew Johnson <matt...@anandabits.com 
> <mailto:matt...@anandabits.com>> wrote:
> 
>> On Jul 22, 2016, at 8:54 PM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Fri, Jul 22, 2016 at 8:52 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> "The totalOrder predicate will order these cases, and it also distinguishes 
>> between different representations of NaNs and between the same decimal 
>> floating point number encoded in different ways."
>> - 
>> [Wikipedia](https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate
>>  
>> <https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate>)
>> 
>> Sounds like `===` should not return `true` for zeros of different signs, 
>> then.
>> 
>> Fair enough; the result of that will be, as Pyry noted above, that:
>> 
>> ```
>> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
>> ```
> 
> Maybe we need floating point specific implementations of some algorithms to 
> resolve this problem?
> 
> It doesn’t seem like there is a way to provide the semantics required by 
> generic algorithms and still provide the expected behavior for floating point 
> values.  
> 
> Well, what I'm trying to say is that generic algorithms such as `index(of:)` 
> require only an equivalence relation. For floating point types, there are 
> three ways to slice it:
> 
> 1. NaN != NaN and +0 == -0 [what the traditional comparison operators are 
> constrained to do]
> 2. NaN == NaN, +0 == -0, and the same number encoded different ways compare 
> equal
> 3. NaN == NaN, +0 != -0, and the same number encoded different ways compare 
> not equal
> 
> Both #2 and #3 can fall out of valid equivalence relations; if `===` behaved 
> like #2 for FloatingPoint types, then generic algorithms work just fine. If 
> we insist on using a total ordering defined by `<=>` all the time, then we've 
> got problems.
> 
>  
> 
>> 
>>> On Jul 22, 2016, at 6:48 PM, Dave Abrahams via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> on Fri Jul 22 2016, Jaden Geller <swift-evolution@swift.org 
>>> <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>>> For floating point, I'd hope that `a === b` if `(a <=> b) == .same`
>>>>> *but not iff*. This is to satisfy IEEE 754: "Comparisons shall
>>>>> ignore the sign of zero (so +0 = −0)".
>>>> 
>>>> I don't see why both `(+0) === (-0)` and `(+0) <=> (-0)` can't return
>>>> `true` and `.same`, respectively. This doesn't break the total
>>>> ordering of values. `===` doesn't do raw memory comparison. They're
>>>> "identical", so it ought to return `true`.
>>> 
>>> It ought to do whatever IEEE-754 specifies that its total ordering test
>>> does.  That is, IEEE-754 gets to decide whether the difference between
>>> +0 and -0 is “essential” to IEEE-754 floating point types, or not.
>>> 
>>>> 
>>>>> On Jul 22, 2016, at 6:37 PM, Xiaodi Wu via swift-evolution
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> On Fri, Jul 22, 2016 at 8:20 PM, Dave Abrahams via swift-evolution
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>>
>>>>> wrote:
>>>>> 
>>>>> on Fri Jul 22 2016, Daniel Duan >>>> <http://daniel-at-duan.org/>> wrote:
>>>>> 
>>>>>>> On Jul 22, 2016, at 

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
> If `===` is the new `areSame`, and `Hashable` is based on `===`, wouldn't 
> that mean that objects could only be hashed (and thus, be looked up in 
> Dictionary and Set) by identity? So, for instance, code like this:
> 
>   var set = Set()
>   
>   set.insert("test")
>   set.insert("test")
>   
>   print(set.count)
> 
> Would print "2"? Or worse, might print "1" or "2" depending on the details of 
> how Swift generates literals and Foundation implements short strings?
> 
> Am I the only one who thinks that's a problem?

I was under the impression that the identity of an `NSObject` would use the 
existing `isEqual:` method. That is, identity doesn't necessarily mean 
reference identity anymore.

> On Jul 22, 2016, at 7:00 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Jul 22, 2016, at 4:55 PM, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>>> Well, it's still a very real question whether we ought to have the
>>> additional API surface implied by areSame, or wether we should collapse
>>> it with ===.
>>> 
>> 
>> To spell this out (because I had to think about it for a second): === will 
>> be derived from
>> <=>, but also becomes default implementation for ==, which remains open for 
>> customization.
>> 
>> I like this idea. If we keep === as a separate thing, now users have 3 
>> “opportunities” to define
>> equality. The must be few, if any, use cases for this.
>> 
>> Would love to see if anyone on the list can give us an example. Otherwise we 
>> should make
>> areSame === again™!
> 
> If `===` is the new `areSame`, and `Hashable` is based on `===`, wouldn't 
> that mean that objects could only be hashed (and thus, be looked up in 
> Dictionary and Set) by identity? So, for instance, code like this:
> 
>   var set = Set()
>   
>   set.insert("test")
>   set.insert("test")
>   
>   print(set.count)
> 
> Would print "2"? Or worse, might print "1" or "2" depending on the details of 
> how Swift generates literals and Foundation implements short strings?
> 
> Am I the only one who thinks that's a problem?
> 
> -- 
> 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] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
> Fair enough; the result of that will be, as Pyry noted above, that:
> 
> ```
> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
> ```

Well, ummm, that's unfortunate. This would be extremely surprising behavior, 
and I could easily see this causing bugs. Users would have to be very careful 
to write:
```
[-0.0, 1.0, .nan, 0.0].firstIndex(where: { $0 == 0 })
```

This might be a deal-breaker… unless:

> Maybe we need floating point specific implementations of some algorithms to 
> resolve this problem?

That seems like a reasonable workaround. I wish it weren't necessary though. 
Feels like we must have a flawed design. (Or IEEE does :P)

> On Jul 22, 2016, at 6:57 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
>> 
>> On Jul 22, 2016, at 8:54 PM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Fri, Jul 22, 2016 at 8:52 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> "The totalOrder predicate will order these cases, and it also distinguishes 
>> between different representations of NaNs and between the same decimal 
>> floating point number encoded in different ways."
>> - 
>> [Wikipedia](https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate
>>  
>> <https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate>)
>> 
>> Sounds like `===` should not return `true` for zeros of different signs, 
>> then.
>> 
>> Fair enough; the result of that will be, as Pyry noted above, that:
>> 
>> ```
>> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
>> ```
> 
> Maybe we need floating point specific implementations of some algorithms to 
> resolve this problem?
> 
> It doesn’t seem like there is a way to provide the semantics required by 
> generic algorithms and still provide the expected behavior for floating point 
> values.  
> 
>> 
>>> On Jul 22, 2016, at 6:48 PM, Dave Abrahams via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> on Fri Jul 22 2016, Jaden Geller <swift-evolution@swift.org 
>>> <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>>> For floating point, I'd hope that `a === b` if `(a <=> b) == .same`
>>>>> *but not iff*. This is to satisfy IEEE 754: "Comparisons shall
>>>>> ignore the sign of zero (so +0 = −0)".
>>>> 
>>>> I don't see why both `(+0) === (-0)` and `(+0) <=> (-0)` can't return
>>>> `true` and `.same`, respectively. This doesn't break the total
>>>> ordering of values. `===` doesn't do raw memory comparison. They're
>>>> "identical", so it ought to return `true`.
>>> 
>>> It ought to do whatever IEEE-754 specifies that its total ordering test
>>> does.  That is, IEEE-754 gets to decide whether the difference between
>>> +0 and -0 is “essential” to IEEE-754 floating point types, or not.
>>> 
>>>> 
>>>>> On Jul 22, 2016, at 6:37 PM, Xiaodi Wu via swift-evolution
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> On Fri, Jul 22, 2016 at 8:20 PM, Dave Abrahams via swift-evolution
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>>
>>>>> wrote:
>>>>> 
>>>>> on Fri Jul 22 2016, Daniel Duan >>>> <http://daniel-at-duan.org/>> wrote:
>>>>> 
>>>>>>> On Jul 22, 2016, at 3:00 PM, Dave Abrahams via swift-evolution
>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>>
>>>>>>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>> on Fri Jul 22 2016, Daniel Duan
>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
"The totalOrder predicate will order these cases, and it also distinguishes 
between different representations of NaNs and between the same decimal floating 
point number encoded in different ways."
- 
[Wikipedia](https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate)

Sounds like `===` should not return `true` for zeros of different signs, then.

> On Jul 22, 2016, at 6:48 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Fri Jul 22 2016, Jaden Geller  > wrote:
> 
>>> For floating point, I'd hope that `a === b` if `(a <=> b) == .same`
>>> *but not iff*. This is to satisfy IEEE 754: "Comparisons shall
>>> ignore the sign of zero (so +0 = −0)".
>> 
>> I don't see why both `(+0) === (-0)` and `(+0) <=> (-0)` can't return
>> `true` and `.same`, respectively. This doesn't break the total
>> ordering of values. `===` doesn't do raw memory comparison. They're
>> "identical", so it ought to return `true`.
> 
> It ought to do whatever IEEE-754 specifies that its total ordering test
> does.  That is, IEEE-754 gets to decide whether the difference between
> +0 and -0 is “essential” to IEEE-754 floating point types, or not.
> 
>> 
>>> On Jul 22, 2016, at 6:37 PM, Xiaodi Wu via swift-evolution
>>> > wrote:
>>> 
>>> On Fri, Jul 22, 2016 at 8:20 PM, Dave Abrahams via swift-evolution
>>> 
>>> >>
>>> wrote:
>>> 
>>> on Fri Jul 22 2016, Daniel Duan >> > wrote:
>>> 
> On Jul 22, 2016, at 3:00 PM, Dave Abrahams via swift-evolution
> 
> >>
> wrote:
> 
> 
> on Fri Jul 22 2016, Daniel Duan
> 
> >
> 
>  wrote:
> 
 
>>> On Jul 22, 2016, at 11:05 AM, Dave Abrahams via swift-evolution
>>> 
>>> >
>>> 
>>> >> wrote:
>>> 
>>> 
>>> on Thu Jul 21 2016, Duan
>> 
>>> 
>>> >
>>> 
>>> >>
>>> 
>>> >
>>> 
>>> 
>>> wrote:
>>> 
 Great proposal. I want to second that areSame may mislead user to
 think this is about identity.
 
 I like areEquivalent() but there may be better names.
>>> 
>>> It really *is* about identity as I posted in a previous message.  But
>>> that doesn't change the fact that areEquivalent might be a better name.
>>> It's one of the things we considered; it just seemed long for no real
>>> benefit.
>>> 
>> 
>> If the addresses of the arguments aren’t being used, then we don’t 
>> consider
>> them part of their *identity*. I can follow this logic. My fear is most 
>> users
>> won’t make this leap on their own and get the same initial impression as 
>> I did.
>> It's entirely possible this fear is unfounded. Some educated bikesheding
>> wouldn't hurt here IMO :)
> 
> Well, it's still a very real question whether we ought to have the
> additional API surface implied by areSame, or wether we should collapse
> it with ===.
> 
 
 To spell this out (because I had to think about it for a second): === will 
 be derived from
 <=>,
 but also becomes default implementation for ==, which remains open for
 customization.
>>> 
>>> I was imagining roughly this (untested):
>>> 
>>>  /// Two references are identical if they refer to the same
>>>  /// instance.
>>>  ///
>>>  /// - Note: Classes with a more-refined notion of “identical”
>>>  ///   should conform to `Identifiable` and implement `===`.
>>>  func ===(lhs: AnyObject, rhs: AnyObject) -> Bool {
>>> 

Re: [swift-evolution] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Jaden Geller via swift-evolution
I really like this idea. I was initially opposed to changing the behavior of 
`===`, but I think I'm for it now. Though there have been quite a few 
situations where I specifically want reference identity, in these situations I 
would not override the `===` operator anyway; these objects were identified by 
their reference.

I think this refinement of the proposal makes the semantics easier to reason 
about, and nicely repurposes the `===` operator instead of introducing a new 
3rd notion of equality. If users explicitly want to compare references, it 
isn't difficult to create an `ObjectIdentifier`, and it probably leads to 
clearer code in cases where the object identity isn't defined by it's reference.

Could types that conform to `Comparable` not get a default implementation of 
`===`?

> On Jul 22, 2016, at 6:20 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Fri Jul 22 2016, Daniel Duan  wrote:
> 
>>> On Jul 22, 2016, at 3:00 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> on Fri Jul 22 2016, Daniel Duan >> > wrote:
>>> 
>> 
> On Jul 22, 2016, at 11:05 AM, Dave Abrahams via swift-evolution
> > wrote:
> 
> 
> on Thu Jul 21 2016, Duan
 
> 
> >>
> wrote:
> 
>> Great proposal. I want to second that areSame may mislead user to
>> think this is about identity.
>> 
>> I like areEquivalent() but there may be better names.
> 
> It really *is* about identity as I posted in a previous message.  But
> that doesn't change the fact that areEquivalent might be a better name.
> It's one of the things we considered; it just seemed long for no real
> benefit.
> 
 
 If the addresses of the arguments aren’t being used, then we don’t consider
 them part of their *identity*. I can follow this logic. My fear is most 
 users
 won’t make this leap on their own and get the same initial impression as I 
 did.
 It's entirely possible this fear is unfounded. Some educated bikesheding
 wouldn't hurt here IMO :)
>>> 
>>> Well, it's still a very real question whether we ought to have the
>>> additional API surface implied by areSame, or wether we should collapse
>>> it with ===.
>>> 
>> 
>> To spell this out (because I had to think about it for a second): === will 
>> be derived from
>> <=>, 
>> but also becomes default implementation for ==, which remains open for
>> customization.
> 
> I was imagining roughly this (untested):
> 
>  /// Two references are identical if they refer to the same
>  /// instance.
>  ///
>  /// - Note: Classes with a more-refined notion of “identical” 
>  ///   should conform to `Identifiable` and implement `===`.
>  func ===(lhs: AnyObject, rhs: AnyObject) -> Bool {
>ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
>  }
> 
>  /// Supports testing that two values of `Self` are identical
>  ///
>  /// If `a` and `b` are of type `Self`, `a === b` means that
>  /// `a` and `b` are interchangeable in most code.  A conforming 
>  /// type can document that specific observable characteristics
>  /// (such as the `capacity` of an `Array`) are inessential and 
>  /// thus not to be considered as part of the interchangeability 
>  /// guarantee.
>  ///
>  /// - Requires: `===` induces an equivalence relation over
>  ///   instances.
>  /// - Note: conforming types will gain an `==` operator that 
>  ///   forwards to `===`.  
>  /// - Note: Types that require domain-specific `==` 
>  ///   implementations with different semantics (e.g. floating 
>  ///   point) should define a more-specific overload of `==`, 
>  ///   which will be used in contexts where the static type is
>  ///   known to the compiler.
>  /// - Note: Generic code should usually use `==` to compare 
>  ///   conforming instances; that will always dispatch to `===` 
>  ///   and will be unaffected by more specific overloads of
>  ///   `==`.
>  protocol Identifiable { // née Equatable name is negotiable
>func ===(_: Self, _: aSelf) -> Bool
>  }
> 
>  /// Default definition of `==` for Identifiable types.
>  func ==(lhs: T, rhs: T) -> Bool {
>return lhs === rhs
>  }
> 
>  /// Conforming types have a default total ordering.
>  /// 
>  /// If `a` and `b` are of type `Self`, `a <=> b` means that
>  /// `a` and `b` are interchangeable in most code.  A conforming 
>  /// type can document that specific observable characteristics
>  /// (such as the `capacity` of an `Array`) are inessential and 
>  /// thus not to be considered as part of the interchangeability 
>  /// guarantee.
>  ///
>  /// - Requires: `<=>` induces a total ordering over
>  ///   instances.
>  /// - Requires: the semantics of `<=>` 

Re: [swift-evolution] [Review] SE-0122: Use colons for subscript declarations

2016-07-20 Thread Jaden Geller via swift-evolution
I don't disagree with discussing other languages. I'm just pointing out that 
C++ doesn't have a notion of computed properties, so subscript couldn't pretend 
to be a computed property even if it'd like! Python does have a similar 
construct, but it's computed properties *also* look like functions (you first 
define a set_foo() and a get_foo() before making the property) so it is also 
not relevant.

> On Jul 20, 2016, at 7:24 PM, Duan  wrote:
> 
> It's part of the review template :)
> 
> Daniel Duan
> Sent from my iPhone
> 
> On Jul 20, 2016, at 7:23 PM, Jaden Geller  > wrote:
> 
>>> Python's __getitem__() method, C++'s [] operator are some analogous 
>>> examples. Non -of them pretend not to be a function. The users of these 
>>> features appear to be satisfied by the decision.
>> 
>> This seems irrelevant since Swift already has computed properties which 
>> pretend not to be a function.
>> 
>>> On Jul 20, 2016, at 7:13 PM, Duan via swift-evolution 
>>> > wrote:
>>> 
>>> * What is your evaluation of the proposal ?
>>> 
>>> -1. 
>>> 
>>> To me, subscripts have always seen more functions than properties for the 
>>> fact that they can take arbitrary number of arguments. If we were to "clean 
>>> up" its syntax, I'd rather align it with functions. Something along the 
>>> lines of
>>> 
>>>   subscribe(get) func foo(_ x: X) -> Y
>>>   subscribe(set) func foo(_ y: Y)
>>> 
>>>  * Is the problem being addressed significant enough to warrant a change to 
>>> Swift?
>>> 
>>> No. More importantly, the change is a regression visually.
>>> 
>>> * Does this proposal fit well with the feel and direction of Swift?
>>> 
>>> It's an attempt of a syntax dress-up.
>>> 
>>> * If you have used other languages or libraries with a similar feature, how 
>>> do you feel that this proposal compares to those?
>>> 
>>> Python's __getitem__() method, C++'s [] operator are some analogous 
>>> examples. Non -of them pretend not to be a function. The users of these 
>>> features appear to be satisfied by the decision.
>>> 
>>>  * How much effort did you put into your review? A glance, a quick reading, 
>>> or an in-depth study?
>>>  
>>> Quick read of proposal and discussion on ML.
>>> 
>>> Daniel Duan
>>> Sent from my iPhone
>>> 
>>> On Jul 20, 2016, at 10:17 AM, Jose Cheyo Jimenez via swift-evolution 
>>> > wrote:
>>> 
 
> On Jul 20, 2016, at 7:51 AM, Vladimir.S via swift-evolution 
> > wrote:
> 
> +1 to clean up the syntax of subscripts. They acts as properties, not 
> methods, so it is natural to express them with `:` and not with `->`.
> 
> Actually, I'd prefer additional change to use [] instead of () in 
> declaration like:
> 
> subscript[externalName internalName: ParamType] : ElementType {
>get { … }
>set { … }
> }
 
 I got to second this suggestion. To me this is an elegant solution. 
 
 If subscripts are so special that Swift decided to give it its own name 
 (as oppose to just making it two functions), 
 why not declare it in a special way like the above?
 
 I think that in addition to replacing -> with : if we replaced () with [] 
 then it would be much clearer that this is not a function or property. 
 
 subscript[externalName internalName: ParamType] : ElementType {
 get { … }
 set { … }
 }
 
 I don’t see another place in the language where [] would make more sense 
 than here: 
 Otherwise I don’t see  replacing -> with : as a big win like Dmitri 
 Gribenko said down thread ->
 
>> I think by changing subscripts to use colons we would end in the 
>> opposite, but
>> totally symmetrical situation compared to what we have now.
 
 
  
 
> 
> especially if thinking about "Future directions" and confusion with 
> parameterised accessor syntax(both declared with `()` but first used with 
> `[]` and second with `()`).
> 
> On 20.07.2016 8:50, Chris Lattner via swift-evolution wrote:
>> Hello Swift community,
>> 
>> The review of "SE-0122: Use colons for subscript declarations " begins 
>> now and runs through July 24. The proposal is available here:
>> 
>>  
>> https://github.com/apple/swift-evolution/blob/master/proposals/0122-use-colons-for-subscript-type-declarations.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 
>> 

  1   2   >