Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution

> On Jun 15, 2016, at 2:25 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> How about this, it might make more sense and relax the behavior a little:
> 
> // 1. file scope (Level 0)
> 
> // Level 0 because its declared at file scope
> private struct A {
>  
> /* implicit private */ init() {} // Level 1
> }
> 
> // Level 0
> struct B {
>  
> // `A` is visible here and is seen as `fileprivate` because it is accessed
> // from a level >= itself (imagine something like a "scope level tree").  
> // also every member of `A` are interpreted as  
> // `fileprivate` and everyting is visible again as intended  
> var a: A = A()
> }
> 
> // 2. file scope (Level 0)
> 
> struct C {
>  
> // `A` is not visible here
> // `B` is visible because its `internal` by default
> }
> Does this makes sense to you?
> 
> 

This does not make sense to me at all.  In order for this to be consistent with 
the rest of our access control rules `init` in #1 has the same visibility as 
`A`.  That is why it is visible inside `B`.  

Your example #2 is just incorrect.  `A` is visible inside the scope of `C`.

Now that we have introduced a scope-dependent access modifier it is an 
incorrect mental model to consider members with no access modifier as having 
the exact same access modifier as the containing scope.  This is no longer 
correct.  They have the same *visibility*, not the same *access modifier*.

>  ___
> | file Root |
> |___|
>|__
>  __|_   __|_
> | struct B (Level 0) | | private struct A (Level 0) |
> || ||
>|  |  
>  __|__   _|
> | var a (Level 1) | | private init() (Level 1) |
> |_| |__|
> 
> To check if `a` has visibility to `init` of `A` we need to compare the  
> visibility level of `B` against `A`. If it is equal than `private` is  
> handled as `fileprivate` which means that any other member from within  
> the scope of `A` are also handled as `fileprivate`. We've get the same result
> if `B`s level is greater than `A`s. That means that we'll get back the  
> visibility by relaxing `private` in some cases as `fileprivate`.
> The described behavior is the same for private on higher levels, but we don’t 
> describe it as fileprivate there (or can we do that?):
> 
> extension B {
> 
>private func foo() {
>  
> // `boo` should be visible here
> }
>  
> private func boo() {
>  
> // `foo` should be visible here
> }
> }
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 15. Juni 2016 um 20:53:21, Robert Widmann via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> Then it is no different from fileprivate.
>> 
>> ~Robert Widmann
>> 
>> 2016/06/15 11:47、Matthew Johnson > > のメッセージ:
>> 
>> > 
>> >> On Jun 15, 2016, at 1:37 PM, Robert Widmann  
>> >> wrote:
>> >> 
>> >> The scope of the *declaration* is not the issue. The scope of its 
>> >> *members* is.
>> > 
>> > Let’s consider an example:
>> > 
>> > private struct Foo {
>> > var bar: Int
>> > }
>> > 
>> > // elsewhere in the same file:
>> > var foo = Foo(bar: 42)
>> > foo.bar = 44
>> > 
>> > `Foo` is declared private. Private for this declaration is at the file 
>> > scope. The `bar` member has no access modifier so it has the same 
>> > visibility as the struct itself, which is file scope. This will also be 
>> > true of the implicitly synthesized memberwise initializer.  
>> > 
>> > This means that it is possible to initialize `foo` with a newly 
>> > constructed instance of `Foo` and to modify the `bar` member anywhere else 
>> > in the same file.
>> > 
>> > If `bar` was also declared `private` this would not be possible as its 
>> > visibility would be restricted to the surrounding scope of the initial 
>> > declaration of `Foo`. This means `Foo` would need to provide an explicit 
>> > initializer or factory method with `fileprivate` visibility in order to be 
>> > usable.
>> > 
>> > Members with no explicit access modifier should have the same *visibility* 
>> > as their containing type (with a maximum implicit visibility of internal), 
>> > not the same *modifier* as their containing type. The only case where 
>> > there is a distinction is the new `private` visibility. Maybe that is what 
>> > is causing the confusion?
>> > 
>> > Does this help?
>> > 
>> > -Matthew
>> > 
>> >> 
>> >> ~Robert Widmann
>> >> 
>> >> 2016/06/15 11:36、Matthew Johnson  のメッセージ:
>> >> 
>> >>> The scope for a top-level declaration is the file itself. This means 
>> >>> that top-level declarations with `private` and `fileprivate` should have 
>> >>> the same behavior. They should not be uninstantiable or unusable.
>> >>> 
>> >>> -Matthew
>> >>> 
>>  On Jun 15, 2016, at 1:31 PM, Robert Widma

Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution

> On Jun 15, 2016, at 2:19 PM, Robert Widmann  wrote:
> 
> We have diagnostics specifically to prohibit this case.  You cannot raise the 
> access level of members.
> 
> private struct Foo {
> internal var x : String = ""
> }
> 
> warning: declaring an internal var for a private struct.
> 
> Hence, the highest allowable level of access for x is private and it becomes 
> invisible.
> 
> I would not like the compiler to synthesize this in my code, and if it did I 
> would like the proposal to say it will raise access levels of members as you 
> would like it to.

That diagnostic is a good thing.  I am not suggesting that you to disregard it.

What you are missing is that the meaning of `private` is scope-dependent.  The 
following example is perfectly valid:

private struct Foo {
fileprivate var x : String = “”
}

`fileprivate` inside `Foo` specifies the same visibility as `private` at the 
top level, thus we are not “raising" the visibility of the member.  If no 
modifier is provided for `x` it receives the same visibility as its containing 
type (up to `internal`).

Consider another example:

struct Foo {
private struct Bar {
var x : String = “”
}
}

In this example we *cannot* mark `x` as `fileprivate` because that *would* 
raise the visibility of `x` beyond that of `Bar`.  `Bar` is only visible inside 
`Foo`, not at file scope.  This means that `x` also has visibility throughout 
the lexical scope of `Foo`, but not outside of it.

-Matthew


> 
> ~Robert Widmann
> 
> 2016/06/15 12:14、Matthew Johnson  > のメッセージ:
> 
>> 
>>> On Jun 15, 2016, at 2:04 PM, Robert Widmann >> > wrote:
>>> 
>>> 
>>> 
>>> 2016/06/15 11:47、Matthew Johnson >> > のメッセージ:
>>> 
 
> On Jun 15, 2016, at 1:37 PM, Robert Widmann  > wrote:
> 
> The scope of the *declaration* is not the issue.  The scope of its 
> *members* is.
 
 Let’s consider an example:
 
 private struct Foo {
   var bar: Int
 }
 
 // elsewhere in the same file:
 var foo = Foo(bar: 42)
 foo.bar = 44
 
 `Foo` is declared private.  Private for this declaration is at the file 
 scope.  The `bar` member has no access modifier so it has the same 
 visibility as the struct itself, which is file scope.  This will also be 
 true of the implicitly synthesized memberwise initializer.  
>>> 
>>> No, it is also private.  It does not inherit its parent scope because, 
>>> following the letter of the proposal, that symbol will only be visible 
>>> within the current declaration.  We cannot arbitrarily break access control 
>>> rules because it is convenient in one special case. 
>>> 
 
 This means that it is possible to initialize `foo` with a newly 
 constructed instance of `Foo` and to modify the `bar` member anywhere else 
 in the same file.
>>> 
>>> bar is not visible here.  If it were you could break access control rules.
>>> 
 
 If `bar` was also declared `private` this would not be possible as its 
 visibility would be restricted to the surrounding scope of the initial 
 declaration of `Foo`.  This means `Foo` would need to provide an explicit 
 initializer or factory method with `fileprivate` visibility in order to be 
 usable.
>>> 
>>> bar is private.  Declarations within Foo cannot decide to raise that access 
>>> level to make themselves more visible.  If this should be the case, the 
>>> proposal must be amended as much.
>>> 
 
 Members with no explicit access modifier should have the same *visibility* 
 as their containing type (with a maximum implicit visibility of internal), 
 not the same *modifier* as their containing type.  The only case where 
 there is a distinction is the new `private` visibility.  Maybe that is 
 what is causing the confusion?
>>> 
>>> That is not what the proposal says.  The proposal says it is invisible 
>>> outside the current decl, which is the containing structure here.
>> 
>> The access modifier is applied to `Foo`, not `bar`.  `Foo` is visible in the 
>> scope of the “current declaration” (this is badly worded - it should say 
>> current scope, which is the file).  Because `Foo` has a visibility lower 
>> than `internal` the default visibility of its members match the visibility 
>> of `Foo`, which again is the current scope: the file.  The detailed design 
>> section of the proposal is sparse, but it correctly uses the phrase "visible 
>> only within that lexical scope” rather than the less precise (in the case of 
>> top-level code) “current declaration”.
>> 
>> I didn’t write the proposal but I was very heavily involved in the 
>> discussions and IIRC I provided the original suggestion for introducing a 
>> scoped access modifier.
>> 
>> If my example was the following:
>> 
>> private struct Foo {
>>   private var bar: Int
>> }
>> 
>> Then wha

Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution

> On Jun 15, 2016, at 2:04 PM, Robert Widmann  wrote:
> 
> 
> 
> 2016/06/15 11:47、Matthew Johnson  > のメッセージ:
> 
>> 
>>> On Jun 15, 2016, at 1:37 PM, Robert Widmann  
>>> wrote:
>>> 
>>> The scope of the *declaration* is not the issue.  The scope of its 
>>> *members* is.
>> 
>> Let’s consider an example:
>> 
>> private struct Foo {
>>   var bar: Int
>> }
>> 
>> // elsewhere in the same file:
>> var foo = Foo(bar: 42)
>> foo.bar = 44
>> 
>> `Foo` is declared private.  Private for this declaration is at the file 
>> scope.  The `bar` member has no access modifier so it has the same 
>> visibility as the struct itself, which is file scope.  This will also be 
>> true of the implicitly synthesized memberwise initializer.  
> 
> No, it is also private.  It does not inherit its parent scope because, 
> following the letter of the proposal, that symbol will only be visible within 
> the current declaration.  We cannot arbitrarily break access control rules 
> because it is convenient in one special case. 
> 
>> 
>> This means that it is possible to initialize `foo` with a newly constructed 
>> instance of `Foo` and to modify the `bar` member anywhere else in the same 
>> file.
> 
> bar is not visible here.  If it were you could break access control rules.
> 
>> 
>> If `bar` was also declared `private` this would not be possible as its 
>> visibility would be restricted to the surrounding scope of the initial 
>> declaration of `Foo`.  This means `Foo` would need to provide an explicit 
>> initializer or factory method with `fileprivate` visibility in order to be 
>> usable.
> 
> bar is private.  Declarations within Foo cannot decide to raise that access 
> level to make themselves more visible.  If this should be the case, the 
> proposal must be amended as much.
> 
>> 
>> Members with no explicit access modifier should have the same *visibility* 
>> as their containing type (with a maximum implicit visibility of internal), 
>> not the same *modifier* as their containing type.  The only case where there 
>> is a distinction is the new `private` visibility.  Maybe that is what is 
>> causing the confusion?
> 
> That is not what the proposal says.  The proposal says it is invisible 
> outside the current decl, which is the containing structure here.

The access modifier is applied to `Foo`, not `bar`.  `Foo` is visible in the 
scope of the “current declaration” (this is badly worded - it should say 
current scope, which is the file).  Because `Foo` has a visibility lower than 
`internal` the default visibility of its members match the visibility of `Foo`, 
which again is the current scope: the file.  The detailed design section of the 
proposal is sparse, but it correctly uses the phrase "visible only within that 
lexical scope” rather than the less precise (in the case of top-level code) 
“current declaration”.

I didn’t write the proposal but I was very heavily involved in the discussions 
and IIRC I provided the original suggestion for introducing a scoped access 
modifier.

If my example was the following:

private struct Foo {
  private var bar: Int
}

Then what you are saying would be correct.  However, The example I showed did 
not provide an access modifier for `bar`.

You cannot just apply the same *access modifier* to members of the type that do 
not contain an access modifier.  You have to apply the same *visibility* 
(limited to internal).  When a type is marked as `private` in the lexical scope 
of the file, its unmodified members will be visible in the same lexical scope 
as the type itself (which is the file in the current example).

-Matthew

> 
>> 
>> Does this help?
>> 
>> -Matthew
>> 
>>> 
>>> ~Robert Widmann
>>> 
>>> 2016/06/15 11:36、Matthew Johnson  のメッセージ:
>>> 
 The scope for a top-level declaration is the file itself.  This means that 
 top-level declarations with `private` and `fileprivate` should have the 
 same behavior.  They should not be uninstantiable or unusable.
 
 -Matthew
 
> On Jun 15, 2016, at 1:31 PM, Robert Widmann via swift-evolution 
>  wrote:
> 
> While implementing SE-0025 (fileprivate), I noticed an interesting bug in 
> the proposal.  Under the implementation outlined there, any top-level 
> structure, class, or enum declared private cannot possibly be 
> instantiated and so cannot be used in any way.  Because of this, private 
> top-level declarations are more often than not blown away entirely by the 
> compiler for being unused.  It seems strange to me to allow a key 
> language feature to act solely as a hint to the optimizer to reduce the 
> size of your binary.  Perhaps the restrictions around private needs to be 
> relaxed or the line between fileprivate and private needs to be 
> investigated again by the community before inclusion in the language.
> 
> Thoughts?
> 
> ~Robert Widmann
> ___
>

Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 15, 2016, at 1:51 PM, Robert Widmann  wrote:
> 
> Then it is no different from fileprivate.

Yes, at file scope this is true.  A reasonable argument can be made for 
prohibiting it at file scope for the sake of clarity, but if it is allowed it 
should behave the same as fileprivate.

Note that similar issues apply for nests types:

struct S {
private struct T { 
var foo: Int
}
// ok - T and foo are visible inside the scope of S
private var t = T(foo: 42)
}

> 
> ~Robert Widmann
> 
> 2016/06/15 11:47、Matthew Johnson  のメッセージ:
> 
>> 
>>> On Jun 15, 2016, at 1:37 PM, Robert Widmann  
>>> wrote:
>>> 
>>> The scope of the *declaration* is not the issue.  The scope of its 
>>> *members* is.
>> 
>> Let’s consider an example:
>> 
>> private struct Foo {
>>   var bar: Int
>> }
>> 
>> // elsewhere in the same file:
>> var foo = Foo(bar: 42)
>> foo.bar = 44
>> 
>> `Foo` is declared private.  Private for this declaration is at the file 
>> scope.  The `bar` member has no access modifier so it has the same 
>> visibility as the struct itself, which is file scope.  This will also be 
>> true of the implicitly synthesized memberwise initializer.  
>> 
>> This means that it is possible to initialize `foo` with a newly constructed 
>> instance of `Foo` and to modify the `bar` member anywhere else in the same 
>> file.
>> 
>> If `bar` was also declared `private` this would not be possible as its 
>> visibility would be restricted to the surrounding scope of the initial 
>> declaration of `Foo`.  This means `Foo` would need to provide an explicit 
>> initializer or factory method with `fileprivate` visibility in order to be 
>> usable.
>> 
>> Members with no explicit access modifier should have the same *visibility* 
>> as their containing type (with a maximum implicit visibility of internal), 
>> not the same *modifier* as their containing type.  The only case where there 
>> is a distinction is the new `private` visibility.  Maybe that is what is 
>> causing the confusion?
>> 
>> Does this help?
>> 
>> -Matthew
>> 
>>> 
>>> ~Robert Widmann
>>> 
>>> 2016/06/15 11:36、Matthew Johnson  のメッセージ:
>>> 
 The scope for a top-level declaration is the file itself.  This means that 
 top-level declarations with `private` and `fileprivate` should have the 
 same behavior.  They should not be uninstantiable or unusable.
 
 -Matthew
 
> On Jun 15, 2016, at 1:31 PM, Robert Widmann via swift-evolution 
>  wrote:
> 
> While implementing SE-0025 (fileprivate), I noticed an interesting bug in 
> the proposal.  Under the implementation outlined there, any top-level 
> structure, class, or enum declared private cannot possibly be 
> instantiated and so cannot be used in any way.  Because of this, private 
> top-level declarations are more often than not blown away entirely by the 
> compiler for being unused.  It seems strange to me to allow a key 
> language feature to act solely as a hint to the optimizer to reduce the 
> size of your binary.  Perhaps the restrictions around private needs to be 
> relaxed or the line between fileprivate and private needs to be 
> investigated again by the community before inclusion in the language.
> 
> Thoughts?
> 
> ~Robert Widmann
> ___
> 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] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution

> On Jun 15, 2016, at 1:37 PM, Robert Widmann  wrote:
> 
> The scope of the *declaration* is not the issue.  The scope of its *members* 
> is.

Let’s consider an example:

private struct Foo {
var bar: Int
}

// elsewhere in the same file:
var foo = Foo(bar: 42)
foo.bar = 44

`Foo` is declared private.  Private for this declaration is at the file scope.  
The `bar` member has no access modifier so it has the same visibility as the 
struct itself, which is file scope.  This will also be true of the implicitly 
synthesized memberwise initializer.  

This means that it is possible to initialize `foo` with a newly constructed 
instance of `Foo` and to modify the `bar` member anywhere else in the same file.

If `bar` was also declared `private` this would not be possible as its 
visibility would be restricted to the surrounding scope of the initial 
declaration of `Foo`.  This means `Foo` would need to provide an explicit 
initializer or factory method with `fileprivate` visibility in order to be 
usable.

Members with no explicit access modifier should have the same *visibility* as 
their containing type (with a maximum implicit visibility of internal), not the 
same *modifier* as their containing type.  The only case where there is a 
distinction is the new `private` visibility.  Maybe that is what is causing the 
confusion?

Does this help?

-Matthew

> 
> ~Robert Widmann
> 
> 2016/06/15 11:36、Matthew Johnson  のメッセージ:
> 
>> The scope for a top-level declaration is the file itself.  This means that 
>> top-level declarations with `private` and `fileprivate` should have the same 
>> behavior.  They should not be uninstantiable or unusable.
>> 
>> -Matthew
>> 
>>> On Jun 15, 2016, at 1:31 PM, Robert Widmann via swift-evolution 
>>>  wrote:
>>> 
>>> While implementing SE-0025 (fileprivate), I noticed an interesting bug in 
>>> the proposal.  Under the implementation outlined there, any top-level 
>>> structure, class, or enum declared private cannot possibly be instantiated 
>>> and so cannot be used in any way.  Because of this, private top-level 
>>> declarations are more often than not blown away entirely by the compiler 
>>> for being unused.  It seems strange to me to allow a key language feature 
>>> to act solely as a hint to the optimizer to reduce the size of your binary. 
>>>  Perhaps the restrictions around private needs to be relaxed or the line 
>>> between fileprivate and private needs to be investigated again by the 
>>> community before inclusion in the language.
>>> 
>>> Thoughts?
>>> 
>>> ~Robert Widmann
>>> ___
>>> 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] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Matthew Johnson via swift-evolution
The scope for a top-level declaration is the file itself.  This means that 
top-level declarations with `private` and `fileprivate` should have the same 
behavior.  They should not be uninstantiable or unusable.

-Matthew

> On Jun 15, 2016, at 1:31 PM, Robert Widmann via swift-evolution 
>  wrote:
> 
> While implementing SE-0025 (fileprivate), I noticed an interesting bug in the 
> proposal.  Under the implementation outlined there, any top-level structure, 
> class, or enum declared private cannot possibly be instantiated and so cannot 
> be used in any way.  Because of this, private top-level declarations are more 
> often than not blown away entirely by the compiler for being unused.  It 
> seems strange to me to allow a key language feature to act solely as a hint 
> to the optimizer to reduce the size of your binary.  Perhaps the restrictions 
> around private needs to be relaxed or the line between fileprivate and 
> private needs to be investigated again by the community before inclusion in 
> the language.
> 
> Thoughts?
> 
> ~Robert Widmann
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Jun 11, 2016, at 7:48 AM, Brent Royal-Gordon  wrote:

>> Functions and tuples are structural types, although it is probably possible 
>> to make tuples syntactic sugar for a Tuple type of we get the necessary 
>> variadic generics support.
> 
> The design the variadic generics thread seems to have preliminarily settled 
> on is based on representing variadic generics as tuples, so I imagine we 
> would hit some issues with circularity!

I'm not sure this topic is settled at all (felt a bit more like deferred I 
thought).  But this may well turn out to be the case.  There is some 
circularity either way of course - one will probably be defined in terms of the 
other.

The more important point is that Swift does have structural types and even if 
you could define Tuple with variadic generics you still have structural 
function types.  So it will always have at least one structural type.

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

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 10, 2016, at 7:46 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Thu Jun 09 2016, Matthew Johnson 
>  wrote:
> 
>>> On Jun 9, 2016, at 3:05 PM, Dave Abrahams 
>>>  wrote:
>>> 
>>> 
>>> on Thu Jun 09 2016, Matthew Johnson  wrote:
>> 
> On Jun 9, 2016, at 11:42 AM, Dave Abrahams 
>  wrote:
> 
> 
> on Thu Jun 09 2016, Matthew Johnson  > wrote:
 
>>> On Jun 9, 2016, at 9:55 AM, Dave Abrahams
>>> >> >
>>> wrote:
>>> 
>>> 
>>> on Wed Jun 08 2016, Matthew Johnson >> 
>>> >> >> wrote:
>> 
> On Jun 8, 2016, at 1:33 PM, Dave Abrahams
>  >
> wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  > wrote:
 
>>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams
>>> >> >
>>> wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson >> 
>>> >> >> wrote:
>> 
> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via
> swift-evolution 
>  > 
> wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson
>  >
> wrote:
 
>>> , but haven't realized
>>> that if you step around the type relationships encoded in Self
>>> requirements and associated types you end up with types that 
>>> appear to
>>> interoperate but in fact trap at runtime unless used in exactly 
>>> the
>>> right way.
>> 
>> Trap at runtime?  How so?  Generalized existentials should still 
>> be
>> type-safe.  
> 
> There are two choices when you erase static type relationships:
> 
> 1. Acheive type-safety by trapping at runtime
> 
> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
> 
> 2. Don't expose protocol requirements that involve these 
> relationships,
> which would prevent the code above from compiling and prevent
> FloatingPoint from conforming to itself.
> 
>> Or are you talking about the hypothetical types / behaviors 
>> people
>> think they want when they don’t fully understand what is 
>> happening...
> 
> I don't know what you mean here.  I think generalized 
> existentials will
> be nice to have, but I think most people will want them to do 
> something
> they can't possibly do.
 
 Exactly.  What I meant is that people think they want that 
 expression
 to compile because they don’t understand that the only thing it 
 can do
 is trap.  I said “hypothetical” because producing a compile time 
 error
 rather than a runtime trap is the only sane thing to do.  Your 
 comment
 surprised me because I can’t imagine we would move forward in Swift
 with the approach of trapping.
>>> 
>>> I would very much like to be able to create instances of “Collection
>>> where Element == Int” so we can throw away the wrappers in the 
>>> stdlib.
>>> That will require some type mismatches to be caught at runtime via
>>> trapping.
>> 
>> For invalid index because the existential accepts a type erased 
>> index?
> 
> Exactly.
> 
>> How do you decide where to draw the line here?  It feels like a very
>> slippery slope for a language where safety is a stated priority to
>> start adopting a strategy of runtime trapping for something as
>> fundamental as how you expose members on an existential.
> 
> If you don't do this, the alternative is that “Collection where 
> Element
> == Int” does not conform to Collection.  
 
 This isn’t directly related to having self or associated type
 requirements.  It is true of all existentials.  
>>> 
>>> That is just an implementation limitation today, IIUC.  What I'm talking
>>> about here would make it impossible for some to do that.
>> 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 11, 2016, at 7:31 AM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> 
>>> Am 11.06.2016 um 14:23 schrieb Brent Royal-Gordon :
>>> 
>>> The only magic would be that all type definitions (`protocol` etc.) which 
>>> do not give a supertype they conform to, will implicitly conform to `Any`, 
>>> i.e.
>>> 
>>> protocol Foo { … }
>>> 
>>> means
>>> 
>>> protocol Foo : Any { … }
>> 
>> Any is also the supertype of all structural types, and structural types 
>> cannot conform to protocols.
> 
> AFAIK Swift does not support structural types and I am not sure whether we 
> should change that. In that case `Any` would become magic, yes.

Functions and tuples are structural types, although it is probably possible to 
make tuples syntactic sugar for a Tuple type of we get the necessary variadic 
generics support.

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

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-09 Thread Matthew Johnson via swift-evolution

> On Jun 9, 2016, at 3:05 PM, Dave Abrahams  wrote:
> 
> 
> on Thu Jun 09 2016, Matthew Johnson  wrote:
> 
>>> On Jun 9, 2016, at 11:42 AM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Thu Jun 09 2016, Matthew Johnson >> > wrote:
>>> 
>> 
> On Jun 9, 2016, at 9:55 AM, Dave Abrahams  > wrote:
> 
> 
> on Wed Jun 08 2016, Matthew Johnson  
>  >> wrote:
> 
 
>>> On Jun 8, 2016, at 1:33 PM, Dave Abrahams >> > wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson >> > wrote:
>>> 
>> 
> On Jun 7, 2016, at 9:15 PM, Dave Abrahams  > wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  
>  >> wrote:
> 
 
>>> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via
>>> swift-evolution >> > wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson >> > wrote:
>>> 
>> 
> , but haven't realized
> that if you step around the type relationships encoded in Self
> requirements and associated types you end up with types that 
> appear to
> interoperate but in fact trap at runtime unless used in exactly 
> the
> right way.
 
 Trap at runtime?  How so?  Generalized existentials should still be
 type-safe.  
>>> 
>>> There are two choices when you erase static type relationships:
>>> 
>>> 1. Acheive type-safety by trapping at runtime
>>> 
>>> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
>>> 
>>> 2. Don't expose protocol requirements that involve these 
>>> relationships,
>>> which would prevent the code above from compiling and prevent
>>> FloatingPoint from conforming to itself.
>>> 
 Or are you talking about the hypothetical types / behaviors people
 think they want when they don’t fully understand what is 
 happening...
>>> 
>>> I don't know what you mean here.  I think generalized existentials 
>>> will
>>> be nice to have, but I think most people will want them to do 
>>> something
>>> they can't possibly do.
>> 
>> Exactly.  What I meant is that people think they want that expression
>> to compile because they don’t understand that the only thing it can 
>> do
>> is trap.  I said “hypothetical” because producing a compile time 
>> error
>> rather than a runtime trap is the only sane thing to do.  Your 
>> comment
>> surprised me because I can’t imagine we would move forward in Swift
>> with the approach of trapping.
> 
> I would very much like to be able to create instances of “Collection
> where Element == Int” so we can throw away the wrappers in the stdlib.
> That will require some type mismatches to be caught at runtime via
> trapping.
 
 For invalid index because the existential accepts a type erased index?
>>> 
>>> Exactly.
>>> 
 How do you decide where to draw the line here?  It feels like a very
 slippery slope for a language where safety is a stated priority to
 start adopting a strategy of runtime trapping for something as
 fundamental as how you expose members on an existential.
>>> 
>>> If you don't do this, the alternative is that “Collection where Element
>>> == Int” does not conform to Collection.  
>> 
>> This isn’t directly related to having self or associated type
>> requirements.  It is true of all existentials.  
> 
> That is just an implementation limitation today, IIUC.  What I'm talking
> about here would make it impossible for some to do that.
 
 If it is just an implementation limitation I am happy to hear that.
 
> 
>> If that changes for simple existentials and generalized existentials
>> expose all members (as in the latest draft of the proposal) maybe it
>> will be possible for all existentials to conform to their protocol.
> 
> Not without introducing runtime traps.  See my “subscript function”
> example.
 
> 
>> 
>>> That's weird and not very
>>> useful.  You could expose all the methods that were on protocol
>>> extensions of Collection on this existential, unless they 

Re: [swift-evolution] Name disambiguation of computed property/function with same type defined in extensions

2016-06-09 Thread Matthew Johnson via swift-evolution

> On Jun 9, 2016, at 1:01 PM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> 
>> Am 09.06.2016 um 19:46 schrieb L Mihalkovic via swift-evolution 
>> mailto:swift-evolution@swift.org>>:
>> 
>>> 
>>> On Jun 9, 2016, at 7:04 PM, Jordan Rose >> > wrote:
>>> 
 
 On Jun 9, 2016, at 07:35, L. Mihalkovic >>> > wrote:
 
 
 On Jun 9, 2016, at 3:27 AM, Jordan Rose via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> Hi, Paulo. Thanks for bringing this up; it’s definitely an interesting 
> problem to solve.
> 
> My thoughts are mostly in line with yours, that disambiguation at the 
> call site is the most Swift-like thing to do, at least as a first step. 
> Maybe we can add some way to record general preferences, or maybe just 
> asking people to define a wrapper function to put the disambiguation in 
> one place is fine.
> 
> I’m not particularly a fan of the “from” syntax or the “@“ syntax, but I 
> don’t have anything better. (And the “not a fan” is entirely a taste 
> thing, plus a general desire not to steal new keywords or operator 
> characters. Neither of these are blockers.) I’ve been playing with silly 
> things like this:
> 
> str.(ModuleA.capitalized)()
> 
 
 Seeing all these proposals that people make, it makes me thinks that 
 extensions as they exist are not fully understood... People seem to 
 consider them  like the Xtext/Xtend/c# extension METHODS, which means that 
 maybe they should also be added to Swift, and people would not be confused:
 
 public static func capitalized(self:String)() {}
 
 Then these would be easily individually imported from module x,y or z with 
 the current syntax, and then "extension String {}" would retain it current 
 scoping behavior
 
 No matter what, I think many extensions are just a bad outlook on OOD, but 
 properly understood, they are great.
>>> 
>>> I’m not sure what you mean. How does changing the declaration site solve 
>>> the disambiguation problem at the call site? (And how do you think Swift 
>>> extensions differ from C# extensions?)
>>> 
>> 
>> sorry, I thought the example was clearer than it actually is (pb with 
>> writing thgs in a train)
>> 
>> 
>> This is code I wrote a couple weeks ago (parsing some WWDC related things in 
>> C#):
>> namespace HtmlAgilityPackPlus {
>> using HtmlAgilityPack;
>> 
>> public static class Extender {
>> public static HtmlNode ChildOfType(this HtmlNode node, string name) {
>> var n = node.ChildNodes.Where( x => x.Name == name).First();
>> return n;
>> } 
>> public static HtmlNode FirstLink(this HtmlNode node) {
>> var child = node.ChildOfType("a");
>> return child;
>> }
>> public static HtmlNode FirstDescendantMatching(this HtmlNode node, 
>> Func predicate) {
>> var seq = node.Descendants().Where( x => predicate(x) );
>> return ((seq?.Count() ?? 0) > 0) ? seq.First() : null;
>> }
>> }
>> }
>> 
>> XText and XTend work the same (I think at some point so did kotlin, but I 
>> haven’t checked since the final)
>> 
>> 
>> Now this is some Swift code (yes I am not bothering with the details)
>> module A ===
>> 
>> extension String {
>> func oneA() {  }
>> func twoA() {  }
>> func threeA() {  }
>> }
>> 
>> 
>> module B ===
>> 
>> extension String {
>> func oneB() {  }
>> func twoB() {  }
>> func threeB() {  }
>> }
>> 
>> We could say that the Swift extension is a ‘batch’ oriented mechanism: 
>> first a target type is decided by forming a scope
>> then many extension methods can be added together
>> Of course one can also add a single method at a time in as many single 
>> scopes. But the fact remains.. the syntax is oriented towards 
>> anonymity of the source
>> batch adds
>> 
>> as you can see, this is not how C# works.
>> 
>> So now, given that context, I was suggesting that people seem to consider 
>> Swift extensions as something they currently are NOT: there is no way to 
>> pinpoint a particular extension in a particular module (import the module, 
>> inherit its extensions), there is NO way to target a given method in a given 
>> extension in a given module.
>> 
>> 
>> My point was to suggest that it may show that current extensions are 
>> invaluable for something like the adapter pattern (than you E. Gamma), but 
>> not entirely suited for the more fine-grained scenario that people keep use 
>> in the mail thread.
>> 
>> This led to my proposal to ALSO support (not REPLACE) 
>> 
>> module A ===
>> extension String {
>> func oneA() {  }
>> func twoA() {  }
>> func threeA() {  }
>> }
>> // more like the GO syntax
>> public static func 
>> indexOfSubStringInReversedOrder(self:String)(pattern:String) -> Int {}   

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-09 Thread Matthew Johnson via swift-evolution

> On Jun 9, 2016, at 11:42 AM, Dave Abrahams  wrote:
> 
> 
> on Thu Jun 09 2016, Matthew Johnson  > wrote:
> 
>>> On Jun 9, 2016, at 9:55 AM, Dave Abrahams >> > wrote:
>>> 
>>> 
>>> on Wed Jun 08 2016, Matthew Johnson >>  >> >> wrote:
>>> 
>> 
> On Jun 8, 2016, at 1:33 PM, Dave Abrahams  > wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  > wrote:
> 
 
>>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams >> > wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson >>  >> >> wrote:
>>> 
>> 
> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  > wrote:
> 
 
>>> , but haven't realized
>>> that if you step around the type relationships encoded in Self
>>> requirements and associated types you end up with types that appear 
>>> to
>>> interoperate but in fact trap at runtime unless used in exactly the
>>> right way.
>> 
>> Trap at runtime?  How so?  Generalized existentials should still be
>> type-safe.  
> 
> There are two choices when you erase static type relationships:
> 
> 1. Acheive type-safety by trapping at runtime
> 
> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
> 
> 2. Don't expose protocol requirements that involve these 
> relationships,
> which would prevent the code above from compiling and prevent
> FloatingPoint from conforming to itself.
> 
>> Or are you talking about the hypothetical types / behaviors people
>> think they want when they don’t fully understand what is happening...
> 
> I don't know what you mean here.  I think generalized existentials 
> will
> be nice to have, but I think most people will want them to do 
> something
> they can't possibly do.
 
 Exactly.  What I meant is that people think they want that expression
 to compile because they don’t understand that the only thing it can do
 is trap.  I said “hypothetical” because producing a compile time error
 rather than a runtime trap is the only sane thing to do.  Your comment
 surprised me because I can’t imagine we would move forward in Swift
 with the approach of trapping.
>>> 
>>> I would very much like to be able to create instances of “Collection
>>> where Element == Int” so we can throw away the wrappers in the stdlib.
>>> That will require some type mismatches to be caught at runtime via
>>> trapping.
>> 
>> For invalid index because the existential accepts a type erased index?
> 
> Exactly.
> 
>> How do you decide where to draw the line here?  It feels like a very
>> slippery slope for a language where safety is a stated priority to
>> start adopting a strategy of runtime trapping for something as
>> fundamental as how you expose members on an existential.
> 
> If you don't do this, the alternative is that “Collection where Element
> == Int” does not conform to Collection.  
 
 This isn’t directly related to having self or associated type
 requirements.  It is true of all existentials.  
>>> 
>>> That is just an implementation limitation today, IIUC.  What I'm talking
>>> about here would make it impossible for some to do that.
>> 
>> If it is just an implementation limitation I am happy to hear that.
>> 
>>> 
 If that changes for simple existentials and generalized existentials
 expose all members (as in the latest draft of the proposal) maybe it
 will be possible for all existentials to conform to their protocol.
>>> 
>>> Not without introducing runtime traps.  See my “subscript function”
>>> example.
>> 
>>> 
 
> That's weird and not very
> useful.  You could expose all the methods that were on protocol
> extensions of Collection on this existential, unless they used
> associated types other than the element type.  But you couldn't pass the
> existential to a generic function like
> 
> func scrambled(_ c: C) -> [C.Element]
> 
>> IMO you should *have* to introduce unsafe behavior like that manually.
> 
> Collection where Element == Int & Index == *
> 
> ?
 
 I didn’t mean directly through the type of the existential.
>>> 
>>> My question i

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-09 Thread Matthew Johnson via swift-evolution

> On Jun 9, 2016, at 9:55 AM, Dave Abrahams  wrote:
> 
> 
> on Wed Jun 08 2016, Matthew Johnson  > wrote:
> 
>>> On Jun 8, 2016, at 1:33 PM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson  wrote:
>>> 
>> 
> On Jun 7, 2016, at 9:15 PM, Dave Abrahams  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  > wrote:
> 
 
>>> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson  wrote:
>>> 
>> 
> , but haven't realized
> that if you step around the type relationships encoded in Self
> requirements and associated types you end up with types that appear to
> interoperate but in fact trap at runtime unless used in exactly the
> right way.
 
 Trap at runtime?  How so?  Generalized existentials should still be
 type-safe.  
>>> 
>>> There are two choices when you erase static type relationships:
>>> 
>>> 1. Acheive type-safety by trapping at runtime
>>> 
>>> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
>>> 
>>> 2. Don't expose protocol requirements that involve these relationships,
>>> which would prevent the code above from compiling and prevent
>>> FloatingPoint from conforming to itself.
>>> 
 Or are you talking about the hypothetical types / behaviors people
 think they want when they don’t fully understand what is happening...
>>> 
>>> I don't know what you mean here.  I think generalized existentials will
>>> be nice to have, but I think most people will want them to do something
>>> they can't possibly do.
>> 
>> Exactly.  What I meant is that people think they want that expression
>> to compile because they don’t understand that the only thing it can do
>> is trap.  I said “hypothetical” because producing a compile time error
>> rather than a runtime trap is the only sane thing to do.  Your comment
>> surprised me because I can’t imagine we would move forward in Swift
>> with the approach of trapping.
> 
> I would very much like to be able to create instances of “Collection
> where Element == Int” so we can throw away the wrappers in the stdlib.
> That will require some type mismatches to be caught at runtime via
> trapping.
 
 For invalid index because the existential accepts a type erased index?
>>> 
>>> Exactly.
>>> 
 How do you decide where to draw the line here?  It feels like a very
 slippery slope for a language where safety is a stated priority to
 start adopting a strategy of runtime trapping for something as
 fundamental as how you expose members on an existential.
>>> 
>>> If you don't do this, the alternative is that “Collection where Element
>>> == Int” does not conform to Collection.  
>> 
>> This isn’t directly related to having self or associated type
>> requirements.  It is true of all existentials.  
> 
> That is just an implementation limitation today, IIUC.  What I'm talking
> about here would make it impossible for some to do that.

If it is just an implementation limitation I am happy to hear that.

> 
>> If that changes for simple existentials and generalized existentials
>> expose all members (as in the latest draft of the proposal) maybe it
>> will be possible for all existentials to conform to their protocol.
> 
> Not without introducing runtime traps.  See my “subscript function”
> example.



> 
>> 
>>> That's weird and not very
>>> useful.  You could expose all the methods that were on protocol
>>> extensions of Collection on this existential, unless they used
>>> associated types other than the element type.  But you couldn't pass the
>>> existential to a generic function like
>>> 
>>>  func scrambled(_ c: C) -> [C.Element]
>>> 
 IMO you should *have* to introduce unsafe behavior like that manually.
>>> 
>>> Collection where Element == Int & Index == *
>>> 
>>> ?
>> 
>> I didn’t mean directly through the type of the existential.
> 
> My question is, why not?  That is still explicit.

It’s not explicit in the sense that nobody wrote `fatalError` or similar in 
their code.  It’s too easy to write something like that without realizing that 
it introduces the possibility of a crash.  If we adopt syntax like that to 
introduce an existential that introduces traps we should at least require 
members that can be trap to be invoked using a `!` suffix or something like 
that to make it clear to users that a trap will happen if they are not 
extremely careful when using that member.  

More generally though, I don’t want the rules of the language to be written in 
a way that causes the compiler to synthesize traps in such a general way.

The existential should not introduce a precondition that isn’t already present 
in the semantics of th

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-08 Thread Matthew Johnson via swift-evolution

> On Jun 8, 2016, at 4:47 PM, Austin Zheng  wrote:
> 
> FWIW my opinion is that existentials either shouldn't be allowed to stand in 
> for generic type parameters, or Dave's option #1 if they are.
> 
> The implied promise of a generic type parameter T right now is that T always 
> stands for the same concrete type (modulo things like passing in a subclass 
> where a class would do), and likewise for all of T's associated types (T.Foo 
> is always the same type everywhere in the context where T is valid). This is 
> what makes using anything with 'self' requirements in a generic context 
> sound. Allowing existentials to satisfy T would violate that constraint. 
> 
> Relaxing these semantics would make it too easy to write code that traps at 
> runtime "without the user having to reach" (to paraphrase Jordan from the 
> "Swift philosophy" thread). Anyone who really really wants to write code that 
> is 'compile-time unsound' in this way should have to explicitly type erase 
> using concrete wrappers.

Yes, exactly.

> 
> Best,
> Austin
> 
> 
> On Wed, Jun 8, 2016 at 2:37 PM, Austin Zheng  <mailto:austinzh...@gmail.com>> wrote:
> We might be talking past each other. I think Matthew is talking about using 
> an existential outside the context of generic functions. For example, 
> something like this should be trap-proof (as long as 'x' is immutable, which 
> it is in this example):
> 
> func copySequenceIntoArray(x: Any) 
> -> [Int] {
>   var buffer : [Int] = []
> // Stupid implementation to make a point
>   var iterator : x.Iterator = x.makeIterator()
>   while true {
>   let nextItem : Int? = iterator.next()
>   if let nextItem = nextItem {
>   buffer.append(nextItem)
>   } else {
>   return buffer
>   }
>   }
> }
> 
> Even this would never trap as well:
> 
> func copySequenceIntoArray(x: Any) 
> -> [T] {
>   var buffer : [T] = []
>   for item in x {
>   buffer.append(item)
>   }
>   return buffer
> }
> 
> Where we run into difficulty is something like this (forgive my abuse of the 
> collections API; I don't remember all the new indexing APIs off the top of my 
> head):
> 
> func doSomething(x: T, y: T) {
>   // Get indexes out of x and use them to index into y
>   var idx = x.startIndex
>   while (idx != x.endIndex || idx != y.endIndex) {
>   print(x[idx])
>   print(y[idx])
>   idx = x.nextIndex(idx)
>   }
> }
> let someSeq : Any = // ...
> let anotherSeq : Any = // ...
> // Trouble!
> // someSeq and anotherSeq are the same existential type
> // But the concrete index types within each of the existential variables may 
> be different
> doSomething(someSeq, anotherSeq)
> 
> It's this situation (using an existential type to fulfill a generic type 
> parameter constrained to the same requirements that comprise that 
> existential) that requires either of the two options that Dave presented, due 
> to our lack of compile-time type information about the fulfilling type's 
> associated types.
> 
> Best,
> Austin
> 
> On Wed, Jun 8, 2016 at 2:33 PM, Matthew Johnson via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
> Sent from my iPad
> 
> > On Jun 8, 2016, at 3:16 PM, Dave Abrahams via swift-evolution 
> > mailto:swift-evolution@swift.org>> wrote:
> >
> >
> >> on Wed Jun 08 2016, Thorsten Seitz  >> <mailto:swift-evolution@swift.org>> wrote:
> >>
> >> Ah, thanks, I forgot!  I still consider this a bug, though (will have
> >> to read up again what the reasons are for that behavior).
> >
> > Yes, but in the case of the issue we're discussing, the choices are:
> >
> > 1. Omit from the existential's API any protocol requirements that depend
> >   on Self or associated types, in which case it *can't* conform to
> >   itself because it doesn't fulfill the requirements.
> 
> They don't need to be omitted.  They are exposed in different ways depending 
> on how the existential is constrained.  Austin's proposal was originally 
> written to omit some members but it was modified based on feedback from Doug 
> Gregor IIRC (Austin, is that right?).  Now it contains examples showing how 
> these members are made available in a safe way.   Some members may still not 
> be usable because you can't form an argument but IIRC the suggestion was that 
> they be exposed anyway for con

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-08 Thread Matthew Johnson via swift-evolution

> On Jun 8, 2016, at 1:33 PM, Dave Abrahams  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  wrote:
> 
>>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson >> > wrote:
>>> 
>> 
> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  wrote:
> 
 
>>> , but haven't realized
>>> that if you step around the type relationships encoded in Self
>>> requirements and associated types you end up with types that appear to
>>> interoperate but in fact trap at runtime unless used in exactly the
>>> right way.
>> 
>> Trap at runtime?  How so?  Generalized existentials should still be
>> type-safe.  
> 
> There are two choices when you erase static type relationships:
> 
> 1. Acheive type-safety by trapping at runtime
> 
> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
> 
> 2. Don't expose protocol requirements that involve these relationships,
> which would prevent the code above from compiling and prevent
> FloatingPoint from conforming to itself.
> 
>> Or are you talking about the hypothetical types / behaviors people
>> think they want when they don’t fully understand what is happening...
> 
> I don't know what you mean here.  I think generalized existentials will
> be nice to have, but I think most people will want them to do something
> they can't possibly do.
 
 Exactly.  What I meant is that people think they want that expression
 to compile because they don’t understand that the only thing it can do
 is trap.  I said “hypothetical” because producing a compile time error
 rather than a runtime trap is the only sane thing to do.  Your comment
 surprised me because I can’t imagine we would move forward in Swift
 with the approach of trapping.
>>> 
>>> I would very much like to be able to create instances of “Collection
>>> where Element == Int” so we can throw away the wrappers in the stdlib.
>>> That will require some type mismatches to be caught at runtime via
>>> trapping.
>> 
>> For invalid index because the existential accepts a type erased index?
> 
> Exactly.
> 
>> How do you decide where to draw the line here?  It feels like a very
>> slippery slope for a language where safety is a stated priority to
>> start adopting a strategy of runtime trapping for something as
>> fundamental as how you expose members on an existential.
> 
> If you don't do this, the alternative is that “Collection where Element
> == Int” does not conform to Collection.  

This isn’t directly related to having self or associated type requirements.  It 
is true of all existentials.  If that changes for simple existentials and 
generalized existentials expose all members (as in the latest draft of the 
proposal) maybe it will be possible for all existentials to conform to their 
protocol.  

> That's weird and not very
> useful.  You could expose all the methods that were on protocol
> extensions of Collection on this existential, unless they used
> associated types other than the element type.  But you couldn't pass the
> existential to a generic function like
> 
>   func scrambled(_ c: C) -> [C.Element]
> 
>> IMO you should *have* to introduce unsafe behavior like that manually.
> 
>  Collection where Element == Int & Index == *
> 
> ?

I didn’t mean directly through the type of the existential.

One obvious mechanism for introducing unsafe behavior is to write manual type 
erasure wrappers like we do today.  

Another possibility would be to allow extending the existential type (not the 
protocol).  This would allow you to write overloads on the Collection 
existential that takes some kind of type erased index if that is what you want 
and either trap if you receive an invalid index or better (IMO) return an 
`Element?`.  I’m not sure how extensions on existentials might be implemented, 
but this is an example of the kind of operation you might want available on it 
that you wouldn’t want available on all Collection types.

> 
>> Collection indices are already something that isn’t fully statically
>> safe so I understand why you might want to allow this.  
> 
> By the same measure, so are Ints :-)
> 
> The fact that a type's methods have preconditions does *not* make it
> “statically unsafe.”

That depends on what you mean by safe.  Sure, those methods aren’t going 
corrupt memory, but they *are* going to explicitly and intentionally crash for 
some inputs.  That doesn’t qualify as “fully safe” IMO.

> 
>> But I don’t think having the language's existentials do this
>> automatically is the right approach.  Maybe there is another approach
>> that could be used in targeted use cases where the less safe behavior
>> makes sense and is carefully designed.
> 
> Whether it makes sense or not really depends on the use-c

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-08 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 8, 2016, at 3:16 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
>> on Wed Jun 08 2016, Thorsten Seitz  wrote:
>> 
>> Ah, thanks, I forgot!  I still consider this a bug, though (will have
>> to read up again what the reasons are for that behavior).
> 
> Yes, but in the case of the issue we're discussing, the choices are:
> 
> 1. Omit from the existential's API any protocol requirements that depend
>   on Self or associated types, in which case it *can't* conform to
>   itself because it doesn't fulfill the requirements.

They don't need to be omitted.  They are exposed in different ways depending on 
how the existential is constrained.  Austin's proposal was originally written 
to omit some members but it was modified based on feedback from Doug Gregor 
IIRC (Austin, is that right?).  Now it contains examples showing how these 
members are made available in a safe way.   Some members may still not be 
usable because you can't form an argument but IIRC the suggestion was that they 
be exposed anyway for consistency.

> 
> 2. Erase type relationships and trap at runtime when they don't line up.
> 
> Matthew has been arguing against #2, but you can't “fix the bug” without
> it.
> 
>> 
>> -Thorsten
>> 
>>> Am 08.06.2016 um 21:43 schrieb Austin Zheng :
>>> 
>>> It's not possible, even with Swift's current implementation of
>>> existentials. A protocol type P isn't considered to conform to
>>> itself, thus the following is rejected:
>>> 
>>> let a : MyProtocol = // ...
>>> func myFunc(x: T) {
>>>  // 
>>> }
>>> myFunc(a) // "Cannot invoke 'myFunc' with an argument list of type 
>>> MyProtocol"
>>> 
>>> Changing how this works is probably worth a proposal by itself.
>>> 
>>> Austin
>>> 
>>> 
>>> On Wed, Jun 8, 2016 at 12:34 PM, Thorsten Seitz via swift-evolution
>>> >> >
>>> wrote:
>>> 
 Am 08.06.2016 um 20:33 schrieb Dave Abrahams via swift-evolution
 >>> >:
 
 
 on Tue Jun 07 2016, Matthew Johnson  wrote:
 
>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams
>> > >
>> wrote:
>> 
>> 
>> on Tue Jun 07 2016, Matthew Johnson > > >> wrote:
> 
 On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution
 >>> >
 wrote:
 
 
 on Tue Jun 07 2016, Matthew Johnson
 >>> >
 wrote:
>>> 
>> , but haven't realized
>> that if you step around the type relationships encoded in Self
>> requirements and associated types you end up with types that appear 
>> to
>> interoperate but in fact trap at runtime unless used in exactly the
>> right way.
> 
> Trap at runtime?  How so?  Generalized existentials should still be
> type-safe.
 
 There are two choices when you erase static type relationships:
 
 1. Acheive type-safety by trapping at runtime
 
 FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
 
 2. Don't expose protocol requirements that involve these relationships,
 which would prevent the code above from compiling and prevent
 FloatingPoint from conforming to itself.
 
> Or are you talking about the hypothetical types / behaviors people
> think they want when they don’t fully understand what is happening...
 
 I don't know what you mean here.  I think generalized existentials will
 be nice to have, but I think most people will want them to do something
 they can't possibly do.
>>> 
>>> Exactly.  What I meant is that people think they want that expression
>>> to compile because they don’t understand that the only thing it can do
>>> is trap.  I said “hypothetical” because producing a compile time error
>>> rather than a runtime trap is the only sane thing to do.  Your comment
>>> surprised me because I can’t imagine we would move forward in Swift
>>> with the approach of trapping.
>> 
>> I would very much like to be able to create instances of “Collection
>> where Element == Int” so we can throw away the wrappers in the stdlib.
>> That will require some type mismatches to be caught at runtime via
>> trapping.
> 
> For invalid index because the existential accepts a type erased index?
 
 Exactly.
 
> How do you decide where to draw the line here?  It feels like a very
> slippery slope for a language where safety is a stated priority to
> start adopting a strategy of runtime trapping for something as
> fundamental as how you expose members on an existential.
 
 If you don't do this, the alternative is that “Collection 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-08 Thread Matthew Johnson via swift-evolution

> On Jun 7, 2016, at 9:27 PM, Matthew Johnson  wrote:
> 
>> 
>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams > > wrote:
>> 
>> 
>> on Tue Jun 07 2016, Matthew Johnson > > wrote:
>> 
 On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 
 on Tue Jun 07 2016, Matthew Johnson >>> > wrote:
 
>>> 
>> , but haven't realized
>> that if you step around the type relationships encoded in Self
>> requirements and associated types you end up with types that appear to
>> interoperate but in fact trap at runtime unless used in exactly the
>> right way.
> 
> Trap at runtime?  How so?  Generalized existentials should still be
> type-safe.  
 
 There are two choices when you erase static type relationships:
 
 1. Acheive type-safety by trapping at runtime
 
 FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
 
 2. Don't expose protocol requirements that involve these relationships,
  which would prevent the code above from compiling and prevent
  FloatingPoint from conforming to itself.
 
> Or are you talking about the hypothetical types / behaviors people
> think they want when they don’t fully understand what is happening...
 
 I don't know what you mean here.  I think generalized existentials will
 be nice to have, but I think most people will want them to do something
 they can't possibly do.
>>> 
>>> Exactly.  What I meant is that people think they want that expression
>>> to compile because they don’t understand that the only thing it can do
>>> is trap.  I said “hypothetical” because producing a compile time error
>>> rather than a runtime trap is the only sane thing to do.  Your comment
>>> surprised me because I can’t imagine we would move forward in Swift
>>> with the approach of trapping.
>> 
>> I would very much like to be able to create instances of “Collection
>> where Element == Int” so we can throw away the wrappers in the stdlib.
>> That will require some type mismatches to be caught at runtime via
>> trapping.

BTW, Austin’s generalized existentials proposal has several examples of how 
existential collections would work: 
https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/-enhanced-existentials.md#protocol-apis-and-associated-types
 
.
  

In what ways do you find this functionality insufficient?  What operations do 
you want to be able to do that this doesn’t support (and can only be supported 
in an unsafe way that must trap for invalid input)?

> 
> For invalid index because the existential accepts a type erased index?
> 
> How do you decide where to draw the line here?  It feels like a very slippery 
> slope for a language where safety is a stated priority to start adopting a 
> strategy of runtime trapping for something as fundamental as how you expose 
> members on an existential.  
> 
> IMO you should *have* to introduce unsafe behavior like that manually.  
> Collection indices are already something that isn’t fully statically safe so 
> I understand why you might want to allow this.  But I don’t think having the 
> language's existentials do this automatically is the right approach.  Maybe 
> there is another approach that could be used in targeted use cases where the 
> less safe behavior makes sense and is carefully designed.
> 
>> 
>>> 
>>> The low hanging fruit in the “protocols whose existentials conform to
>>> the protocol” space is simple protocols that can already by
>>> existentials today (like CustomStringConvertible).  I don’t know
>>> enough about Swift’s implementation to comment on how complex it is
>>> there, but there aren’t any theoretical problems with making their
>>> existentials conform.
>>> 
 
 -- 
 -Dave
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> -- 
>> Dave

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-07 Thread Matthew Johnson via swift-evolution

> On Jun 7, 2016, at 9:15 PM, Dave Abrahams  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  > wrote:
> 
>>> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> on Tue Jun 07 2016, Matthew Johnson  wrote:
>>> 
>> 
> , but haven't realized
> that if you step around the type relationships encoded in Self
> requirements and associated types you end up with types that appear to
> interoperate but in fact trap at runtime unless used in exactly the
> right way.
 
 Trap at runtime?  How so?  Generalized existentials should still be
 type-safe.  
>>> 
>>> There are two choices when you erase static type relationships:
>>> 
>>> 1. Acheive type-safety by trapping at runtime
>>> 
>>> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
>>> 
>>> 2. Don't expose protocol requirements that involve these relationships,
>>>  which would prevent the code above from compiling and prevent
>>>  FloatingPoint from conforming to itself.
>>> 
 Or are you talking about the hypothetical types / behaviors people
 think they want when they don’t fully understand what is happening...
>>> 
>>> I don't know what you mean here.  I think generalized existentials will
>>> be nice to have, but I think most people will want them to do something
>>> they can't possibly do.
>> 
>> Exactly.  What I meant is that people think they want that expression
>> to compile because they don’t understand that the only thing it can do
>> is trap.  I said “hypothetical” because producing a compile time error
>> rather than a runtime trap is the only sane thing to do.  Your comment
>> surprised me because I can’t imagine we would move forward in Swift
>> with the approach of trapping.
> 
> I would very much like to be able to create instances of “Collection
> where Element == Int” so we can throw away the wrappers in the stdlib.
> That will require some type mismatches to be caught at runtime via
> trapping.

For invalid index because the existential accepts a type erased index?

How do you decide where to draw the line here?  It feels like a very slippery 
slope for a language where safety is a stated priority to start adopting a 
strategy of runtime trapping for something as fundamental as how you expose 
members on an existential.  

IMO you should *have* to introduce unsafe behavior like that manually.  
Collection indices are already something that isn’t fully statically safe so I 
understand why you might want to allow this.  But I don’t think having the 
language's existentials do this automatically is the right approach.  Maybe 
there is another approach that could be used in targeted use cases where the 
less safe behavior makes sense and is carefully designed.

> 
>> 
>> The low hanging fruit in the “protocols whose existentials conform to
>> the protocol” space is simple protocols that can already by
>> existentials today (like CustomStringConvertible).  I don’t know
>> enough about Swift’s implementation to comment on how complex it is
>> there, but there aren’t any theoretical problems with making their
>> existentials conform.
>> 
>>> 
>>> -- 
>>> -Dave
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> -- 
> Dave

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-07 Thread Matthew Johnson via swift-evolution

> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  wrote:
> 
>>> , but haven't realized
>>> that if you step around the type relationships encoded in Self
>>> requirements and associated types you end up with types that appear to
>>> interoperate but in fact trap at runtime unless used in exactly the
>>> right way.
>> 
>> Trap at runtime?  How so?  Generalized existentials should still be
>> type-safe.  
> 
> There are two choices when you erase static type relationships:
> 
> 1. Acheive type-safety by trapping at runtime
> 
>  FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap
> 
> 2. Don't expose protocol requirements that involve these relationships,
>   which would prevent the code above from compiling and prevent
>   FloatingPoint from conforming to itself.
> 
>> Or are you talking about the hypothetical types / behaviors people
>> think they want when they don’t fully understand what is happening...
> 
> I don't know what you mean here.  I think generalized existentials will
> be nice to have, but I think most people will want them to do something
> they can't possibly do.

Exactly.  What I meant is that people think they want that expression to 
compile because they don’t understand that the only thing it can do is trap.  I 
said “hypothetical” because producing a compile time error rather than a 
runtime trap is the only sane thing to do.  Your comment surprised me because I 
can’t imagine we would move forward in Swift with the approach of trapping.

The low hanging fruit in the “protocols whose existentials conform to the 
protocol” space is simple protocols that can already by existentials today 
(like CustomStringConvertible).  I don’t know enough about Swift’s 
implementation to comment on how complex it is there, but there aren’t any 
theoretical problems with making their existentials conform. 

> 
> -- 
> -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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-07 Thread Matthew Johnson via swift-evolution

> On Jun 7, 2016, at 12:51 PM, Dave Abrahams  wrote:
> 
> 
> on Tue Jun 07 2016, Matthew Johnson  wrote:
> 
>>> On Jun 6, 2016, at 12:22 AM, Dave Abrahams 
>> wrote:
>>> 
>>> 
>>> on Sun Jun 05 2016, Matthew Johnson > > wrote:
>>> 
>> 
 Sent from my iPhone
 
> On Jun 5, 2016, at 3:51 PM, Dave Abrahams via swift-evolution
>  wrote:
> 
> 
>> on Wed May 25 2016, Matthew Johnson  wrote:
>> 
>> Sent from my iPad
>> 
>>> On May 25, 2016, at 12:10 PM, Jordan Rose via swift-evolution
>>>  wrote:
>>> 
>>> 
> On May 25, 2016, at 05:27, Brent Royal-Gordon via swift-evolution
>  wrote:
> 
> AFAIK an existential type is a type T with type parameters that
> are still abstract (see for example
> https://en.wikipedia.org/wiki/Type_system#Existential_types),
> i.e. have not been assigned concrete values.
 
 My understanding is that, in Swift, the instance used to store
 something whose concrete type is unknown (i.e. is still abstract),
 but which is known to conform to some protocol, is called an
 "existential". Protocols with associated values cannot be packed
 into normal existentials because, even though we know that the
 concrete type conforms to some protocol, the associated types
 represent additional unknowns, and Swift cannot be sure how to
 translate uses of those unknown types into callable members. Hence,
 protocols with associated types are sometimes called
 "non-existential".
 
 If I am misusing the terminology in this area, please understand
 that that's what I mean when I use that word.
>>> 
>>> We’re not consistent about it, but an “existential value” is a value
>>> with protocol or protocol composition type. My mnemonic for this is
>>> that all we know is that certain operations exist (unlike a generic
>>> value, where we also have access to the type). John could explain it
>>> more formally. We sometimes use “existentials” as a (noun) shorthand
>>> for “existential value”.
>>> 
>>> In the compiler source, all protocols and protocol compositions are
>>> referred to as “existential types”, whether they have associated
>>> types or not. Again, a protocol asserts the existence (and
>>> semantics) of various operations, but nothing else about the
>>> conforming type. (Except perhaps that it’s a class.) All protocols
>>> are thus “existential types” whether or not the language supports
>>> values having that type.
>>> 
>>> It is incorrect to say that protocols with associated types (or
>>> requirements involving Self) are “non-existential”.
>> 
>> I haven't heard people using this term myself, but I imagine they
>> probably mean "can't form an existential value with the protocol".
>> There certainly appears to be a lot of confusion in the community with
>> many not realizing that this is a temporary limitation of the
>> implementation, not a necessary fact.
> 
> As far as I know there is no known way to make protocols with Self
> requirements usefully “existentiable,” or whatever you want to
>> call it.
> So unless I'm missing something, in this respect, the limitation
>> is not
> temporary at all.
 
 Take a look at the Equatable example in the opening existentials
 section of Doug's manifesto:
 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html
>>> 
>>> Yes, note that I said *usefully* “existential.”
>> 
>> Fair enough.  But note that I was only talking about the inability to
>> form and open such an existential which appears likely to be a
>> temporary limitation given the generics manifesto (of course things
>> could change).
>> 
>>> While we can of course downcast in this way, you have to handle the
>>> failure case and it's not like you can use this to make a
>>> heterogeneous Set.  AFAICT, this is not at all like what
>>> happens with associated types, where Collection has
>>> obvious uses.
>> 
>> We can’t use this to form Set because existentials don’t
>> conform to the protocol.  I know there is complexity in implementing
>> this and it is not possible to synthesize conformance of the
>> existential for all protocols, but AFAIK it isn’t a settled point that
>> we won’t try to improve the situation in some way.  
> 
> Of course.  I'm just trying to point out that such existentials are
> likely to be a whole lot less useful than many people might think.
> 
>> Maybe we can make progress here somehow.
> 
> Maybe.  It's a research project.
> 
>> In the meantime, we can make a simple wrapper type to provide the
>> required conformance and make a Set that allows us to
>> put Hashable into a Set.  This isn’t ideal but it is a lot less
>> boilerplate than is involved in manual type erasure to

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol syntax with Any

2016-06-07 Thread Matthew Johnson via swift-evolution

> On Jun 6, 2016, at 12:22 AM, Dave Abrahams  wrote:
> 
> 
> on Sun Jun 05 2016, Matthew Johnson  > wrote:
> 
>> Sent from my iPhone
>> 
>>> On Jun 5, 2016, at 3:51 PM, Dave Abrahams via swift-evolution
>>>  wrote:
>>> 
>>> 
 on Wed May 25 2016, Matthew Johnson  wrote:
 
 Sent from my iPad
 
> On May 25, 2016, at 12:10 PM, Jordan Rose via swift-evolution
>  wrote:
> 
> 
>>> On May 25, 2016, at 05:27, Brent Royal-Gordon via swift-evolution
>>>  wrote:
>>> 
>>> AFAIK an existential type is a type T with type parameters that
>>> are still abstract (see for example
>>> https://en.wikipedia.org/wiki/Type_system#Existential_types),
>>> i.e. have not been assigned concrete values.
>> 
>> My understanding is that, in Swift, the instance used to store
>> something whose concrete type is unknown (i.e. is still abstract),
>> but which is known to conform to some protocol, is called an
>> "existential". Protocols with associated values cannot be packed
>> into normal existentials because, even though we know that the
>> concrete type conforms to some protocol, the associated types
>> represent additional unknowns, and Swift cannot be sure how to
>> translate uses of those unknown types into callable members. Hence,
>> protocols with associated types are sometimes called
>> "non-existential".
>> 
>> If I am misusing the terminology in this area, please understand
>> that that's what I mean when I use that word.
> 
> We’re not consistent about it, but an “existential value” is a value
> with protocol or protocol composition type. My mnemonic for this is
> that all we know is that certain operations exist (unlike a generic
> value, where we also have access to the type). John could explain it
> more formally. We sometimes use “existentials” as a (noun) shorthand
> for “existential value”.
> 
> In the compiler source, all protocols and protocol compositions are
> referred to as “existential types”, whether they have associated
> types or not. Again, a protocol asserts the existence (and
> semantics) of various operations, but nothing else about the
> conforming type. (Except perhaps that it’s a class.) All protocols
> are thus “existential types” whether or not the language supports
> values having that type.
> 
> It is incorrect to say that protocols with associated types (or
> requirements involving Self) are “non-existential”.
 
 I haven't heard people using this term myself, but I imagine they
 probably mean "can't form an existential value with the protocol".
 There certainly appears to be a lot of confusion in the community with
 many not realizing that this is a temporary limitation of the
 implementation, not a necessary fact.
>>> 
>>> As far as I know there is no known way to make protocols with Self
>>> requirements usefully “existentiable,” or whatever you want to call it.
>>> So unless I'm missing something, in this respect, the limitation is not
>>> temporary at all.
>> 
>> Take a look at the Equatable example in the opening existentials
>> section of Doug's manifesto:
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html
> 
> Yes, note that I said *usefully* “existential.”

Fair enough.  But note that I was only talking about the inability to form and 
open such an existential which appears likely to be a temporary limitation 
given the generics manifesto (of course things could change).

>  While we can of
> course downcast in this way, you have to handle the failure case and
> it's not like you can use this to make a heterogeneous Set.
> AFAICT, this is not at all like what happens with associated types,
> where Collection has obvious uses.

We can’t use this to form Set because existentials don’t conform to 
the protocol.  I know there is complexity in implementing this and it is not 
possible to synthesize conformance of the existential for all protocols, but 
AFAIK it isn’t a settled point that we won’t try to improve the situation in 
some way.  Maybe we can make progress here somehow.  

In the meantime, we can make a simple wrapper type to provide the required 
conformance and make a Set that allows us to put Hashable into 
a Set.  This isn’t ideal but it is a lot less boilerplate than is involved in 
manual type erasure today where you need to define a struct, base class, and 
wrapper class.  I’d say that’s a win even if we’d like to do better in the 
future.

struct HashableWrapper: Hashable {
var value: Hashable
public var hashValue: Int { return base.hashValue }
}

public func ==(lhs: HashableWrapper, res: HashableWrapper) -> Bool {
if let lhsValue = lhs.value openas T { // T is a the type of lhsValue, 
a copy of the value stored in lhs
if let rhsValue = rhs.value as? T {  // is res also a T?
 

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution
tured by another @once closure, this is the only time it 
>> can be captured.
> 
> I like the idea behind this proposal in theory.  However, it really seems to 
> cry out for linear types.  I have a feeling we would end up with a better 
> (and more general) solution if Swift goes down that path in the future.  At 
> minimum, I would like to hear input from those who work on the type system.  
> If a more robust, less ad-hoc solution will be possible in the future it 
> might be best to wait.
> 
> On the other hand, completion callbacks that require this guarantee are 
> pretty common.  The semantic is part of the contract whether we have language 
> support for it or not.  Maybe we can do something now that could be subsumed 
> by a more general feature in the future...
> 
> I have the same thinking, I'd like the semantics now, and as as strongly as 
> the language can allow. If the language gets better type support then we get 
> better or less restrictive assurances.
> 
>>  
>> 
>>> 
>>> On Sun, Jun 5, 2016 at 11:59 PM, Matthew Johnson >> <mailto:matt...@anandabits.com>> wrote:
>>> 
>>> 
>>> Sent from my iPad
>>> 
>>> On Jun 5, 2016, at 8:52 AM, Andrew Bennett >> <mailto:cac...@gmail.com>> wrote:
>>> 
>>>> Storing into a member would be fine, as long as it must keep @once as a 
>>>> type annotation and the compiler makes sure you maintain:
>>>> sum(callCount, storeCount, passCount) == 1
>>>> 
>>>> For example:
>>>>   class Example {
>>>> private var closure: (@once (T) -> Void)?
>>>> 
>>>> func callClosure(value: T, replace: (@once (T) -> Void)? = nil) {
>>>>   // the compiler should error if it detects the closure:
>>>>   //  * escaping more than once, while still being stored,
>>>>   //  * or being called while still being stored or escaping,
>>>>   //  * or being overwritten without being called
>>>>   if let closure = self.closure {
>>>> self.closure = replace
>>>> closure(value)
>>>>   }
>>>> }
>>>> 
>>>> deinit {
>>>>   // compiler warning: that closure is potentially un-called
>>>>   // runtime fatalError if it's .Some(Closure) after deinit
>>>> }
>>>>   }
>>>> 
>>>> There could be a standard library type with those guarantees built in.
>>> 
>>> I don't consider this compiler verification.  It is runtime verification.  
>>> The best the compiler can do is enforce constraints that allow for 
>>> guaranteed runtime verification.  You can argue that is better than nothing 
>>> but it is not a static guarantee of correct behavior.
>>> 
>>>> 
>>>> 
>>>> On Sun, Jun 5, 2016 at 10:12 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>> wrote:
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>> On Jun 5, 2016, at 6:56 AM, Andrew Bennett >>> <mailto:cac...@gmail.com>> wrote:
>>>> 
>>>>> I like this.
>>>>> 
>>>>> One of the suggestions on @noescape(once) was that it just becomes @once 
>>>>> and works with escaping closures too. It might be possible if compile 
>>>>> time checks verified that the closure isn't copied, and that it is called 
>>>>> before being deinit-ialized. Failing that I'm happy with a runtime 
>>>>> circumstance in the cases the compiler can't check.
>>>> 
>>>> Yeah, maybe if it is only used asynchronously and never stored in a member 
>>>> or global it could be verified and that is a pretty common case.  That 
>>>> would certainly be easier than the general case.
>>>> 
>>>> I prefer @once over @required if the guarantee is single execution.  If 
>>>> the guarantee is *at least once* obviously @once is not the right 
>>>> attribute, but I'm not convinced @required is either.  Maybe @invoked.
>>>> 
>>>>> 
>>>>> It would be great if @required took into the account the feedback from 
>>>>> that proposal and considered the synchronous case too.
>>>>> 
>>>>> As an aside, you can get some of the guarantees you want like this:
>>>>> 
>>>>> func doSomething(completionHandler: (SomeEnum) -> ()) {
&g

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution
vate var closure: (@once (T) -> Void)?
>>>>> 
>>>>> func callClosure(value: T, replace: (@once (T) -> Void)? = nil) {
>>>>>   // the compiler should error if it detects the closure:
>>>>>   //  * escaping more than once, while still being stored,
>>>>>   //  * or being called while still being stored or escaping,
>>>>>   //  * or being overwritten without being called
>>>>>   if let closure = self.closure {
>>>>> self.closure = replace
>>>>> closure(value)
>>>>>   }
>>>>> }
>>>>> 
>>>>> deinit {
>>>>>   // compiler warning: that closure is potentially un-called
>>>>>   // runtime fatalError if it's .Some(Closure) after deinit
>>>>> }
>>>>>   }
>>>>> 
>>>>> There could be a standard library type with those guarantees built in.
>>>> 
>>>> I don't consider this compiler verification.  It is runtime verification.  
>>>> The best the compiler can do is enforce constraints that allow for 
>>>> guaranteed runtime verification.  You can argue that is better than 
>>>> nothing but it is not a static guarantee of correct behavior.
>>>> 
>>>>> 
>>>>> 
>>>>>> On Sun, Jun 5, 2016 at 10:12 PM, Matthew Johnson 
>>>>>>  wrote:
>>>>>> 
>>>>>> 
>>>>>> Sent from my iPad
>>>>>> 
>>>>>>> On Jun 5, 2016, at 6:56 AM, Andrew Bennett  wrote:
>>>>>>> 
>>>>>>> I like this.
>>>>>>> 
>>>>>>> One of the suggestions on @noescape(once) was that it just becomes 
>>>>>>> @once and works with escaping closures too. It might be possible if 
>>>>>>> compile time checks verified that the closure isn't copied, and that it 
>>>>>>> is called before being deinit-ialized. Failing that I'm happy with a 
>>>>>>> runtime circumstance in the cases the compiler can't check.
>>>>>> 
>>>>>> Yeah, maybe if it is only used asynchronously and never stored in a 
>>>>>> member or global it could be verified and that is a pretty common case.  
>>>>>> That would certainly be easier than the general case.
>>>>>> 
>>>>>> I prefer @once over @required if the guarantee is single execution.  If 
>>>>>> the guarantee is *at least once* obviously @once is not the right 
>>>>>> attribute, but I'm not convinced @required is either.  Maybe @invoked.
>>>>>> 
>>>>>>> 
>>>>>>> It would be great if @required took into the account the feedback from 
>>>>>>> that proposal and considered the synchronous case too.
>>>>>>> 
>>>>>>> As an aside, you can get some of the guarantees you want like this:
>>>>>>> 
>>>>>>> func doSomething(completionHandler: (SomeEnum) -> ()) {
>>>>>>>   dispatch_async(someQueue) {
>>>>>>> let result: SomeEnum
>>>>>>> // the compiler ensures 'result' is set
>>>>>>> defer { completionHandler(result) }
>>>>>>> 
>>>>>>> if aCondition {
>>>>>>>   if bCondition {
>>>>>>> result = .Foo
>>>>>>>   } else {
>>>>>>> result = .Bar
>>>>>>>   }
>>>>>>>   // the compiler ensures you do this, because it is 'let'
>>>>>>>   return
>>>>>>> }
>>>>>>> 
>>>>>>> if cCondition {
>>>>>>>   result = .Baz
>>>>>>> }
>>>>>>>   }
>>>>>>> }
>>>>>>> 
>>>>>>>> On Sun, Jun 5, 2016 at 9:42 PM, Matthew Johnson via swift-evolution 
>>>>>>>>  wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Sent from my iPad
>>>>>>>> 
>>>>>>>>> On Jun 5, 2016, at 5:02 AM, Patrick Pijnappel via swift-evolution 
>>>>>>>>>  wrote:
>&

Re: [swift-evolution] Enhanced existential types proposal discussion

2016-06-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 5, 2016, at 6:20 PM, Douglas Gregor  wrote:
> 
> 
>> On May 18, 2016, at 12:35 AM, Austin Zheng  wrote:
>> 
>> I've put together a considerably more detailed draft proposal, taking into 
>> account as much of Matthew's feedback as I could. You can find it below:
>> 
>> https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/-enhanced-existentials.md
>> 
>> Since there is no chance this will come up for review anytime soon, I expect 
>> to make significant revisions to it over the next month or so. Any feedback 
>> would be greatly appreciated.
> 
> This is very much Swift 4 territory, but I can’t help myself… so…
> 
> The actual feature description is spread out through this very long document, 
> with user-facing ideas (e.g., using “anonymous associated types”) intermixed 
> with deeper technical details (existential type equivalence), so it’s very 
> daunting to read. Please bring the user-facing features to the front 
> (“Proposed Solution”) with examples, and save the deeper technical details 
> for “Detailed Design”. You want more readers to make it through the part that 
> affects them.
> 
> Shortcut 'dot' notation: If there is only one protocol with associated types 
> specified in the requirements, and there are no nested Any<...> requirements 
> with where clauses of their own, that protocol's name can be omitted from the 
> whereclause constraints:
> 
> // Okay
> // Would otherwise be Any< ~ where Collection.Element == Int>
> let a : Any where 
> .Element == Int>
> 
> // NOT ALLOWED
> // Both Collection and OptionSetType have associated types.
> let b : Any
> FWIW, I think “.Element == Int” should be the only syntax. In generic 
> signatures, if you have two different protocols with same-named associated 
> types, and a given type parameter (or associated type) conforms to both 
> protocols, the associated types are (implicitly) made equivalent via an 
> inferred same-type constraint. So there’s no reason to introduce the 
> “Collection.Element == Int” syntax, because the “Collection” part is 
> basically irrelevant.
> 
> Once existentials have been suitably enhanced, there is a strong analogy 
> between an existential and a generic signature with a single type parameter 
> that you can’t name. An existential Any Equatable> has most of the same characteristics as a generic something with 
> the signature . Specifically, the 
> sections on “Existential type equivalence”, “Ordering”, “Real types to 
> anonymous associated types”, “Anonymous associated types to real types”. 
> could be reduced to a few small, simple examples and a mention of the 
> analogous behavior of generics. It will be far easier to explain this way, 
> and readers don’t need to get immersed in the details. Where there are 
> differences vs. generics, that’s important to point out.
> 
> “Associated typealias rewriting”: this also falls out of the equivalence with 
> generics + SE-0092.
> 
> “Associated types and member exposure”: you don’t make the point that it only 
> makes sense to refer to the associated types of a let constant; a var could 
> change its type dynamically, which would invalidate the typing rules. Did you 
> consider just using “x.dynamicType” in the type grammar for this? It’s more 
> general, in that you can refer to associated types but also talk about the 
> dynamic type of “x” itself, e.g.,
> 
>   let x: Equatable = …
>   let y: Equatable = …
>   if let yAsX = y as? x.dynamicType { … x == yAsX … }
> 
> which is (almost?) as powerful as a general “open” expression.
> 
> I’m not a fan of the “anonymous associated types” terminology: these are 
> associated types of a type of some runtime-defined value. The only thing 
> “anonymous” about them is that it’s harder to spell the base type; otherwise, 
> they’re just like associated types of a generic type parameter. Again, the 
> generics analogy is strong here.
> 
> FWIW, I don’t think we’ll ever need “opening existentials” with what you’ve 
> described here. Also, remember that a method of a protocol extension 
> essentially opens “Self”, so we already have one way to open an existential 
> (and that’s probably enough).
> 
> I was a little surprised you didn’t point out that AnyObject could become
> 
>   typealias AnyObject = Any
> 
> or give the nice “AnyCollection” syntax:
> 
>   typealias AnyCollection = Any
> 
> the latter of which is fairly important, because it gives nice syntactic sure 
> to one of the most highly-requested features [*]. I’d suggest having that 
> example very, very early.
> 
>   - Doug
> 
> [*] That generally comes in as “Swift should have parameterized protocols…”

Great feedback here Doug.

FWIW, we also occasionally get "Swift should have parameterized protocols" in 
the context of multiple conformances by the same concrete type (as in things 
like ConvertibleTo protocol).


> 
>> 
>> Austin
>> 
>>> On Tue, May 17, 2016 at 9:52 PM, Austin Zheng  wrote:

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 5, 2016, at 6:50 PM, Andrew Bennett  wrote:
> 
> Perhaps I was unclear, in my explanation. The guarantee I'm enforcing is that 
> the closure is called exactly once before being released.
> 
> Everything I suggested is a compile-time check.
> 
> The compile-time warning and runtime `fatalError` I suggested could be 
> replaced with a compile-time error, however even in this case it is still 
> statically checked for the warning.
> 
> The compiler can statically guarantee exactly one of these things happens in 
> methods using the closure:
> the closure is called
> the closure is stored
> the closure is passed to another method
> the program aborts with something like a fatalError
> If the closure is stored then there must be a deinit, and those checks apply 
> there as well.
> 
> I believe this is sufficient to ensure the closure is called once. Please let 
> me know if there are any cases these checks miss.

If the closure is stored in a member it could be called in the implementation 
of any other member.  Calls to other members could come from arbitrary 
locations in the surrounding program at arbitrary points in time (unless you 
have static analysis that can prove a narrower set of possibilities).  And if 
you have a model that relies on behavior in a deinit then storing the closure 
won't be possible for structs.  You have also missed the case that the closure 
is captured by another closure (maybe it is a completion block and you call it 
in a completion block of a method your method calls).

> 
>> On Sun, Jun 5, 2016 at 11:59 PM, Matthew Johnson  
>> wrote:
>> 
>> 
>> Sent from my iPad
>> 
>>> On Jun 5, 2016, at 8:52 AM, Andrew Bennett  wrote:
>>> 
>>> Storing into a member would be fine, as long as it must keep @once as a 
>>> type annotation and the compiler makes sure you maintain:
>>> sum(callCount, storeCount, passCount) == 1
>>> 
>>> For example:
>>>   class Example {
>>> private var closure: (@once (T) -> Void)?
>>> 
>>> func callClosure(value: T, replace: (@once (T) -> Void)? = nil) {
>>>   // the compiler should error if it detects the closure:
>>>   //  * escaping more than once, while still being stored,
>>>   //  * or being called while still being stored or escaping,
>>>   //  * or being overwritten without being called
>>>   if let closure = self.closure {
>>> self.closure = replace
>>> closure(value)
>>>   }
>>> }
>>> 
>>> deinit {
>>>   // compiler warning: that closure is potentially un-called
>>>   // runtime fatalError if it's .Some(Closure) after deinit
>>> }
>>>   }
>>> 
>>> There could be a standard library type with those guarantees built in.
>> 
>> I don't consider this compiler verification.  It is runtime verification.  
>> The best the compiler can do is enforce constraints that allow for 
>> guaranteed runtime verification.  You can argue that is better than nothing 
>> but it is not a static guarantee of correct behavior.
>> 
>>> 
>>> 
>>>> On Sun, Jun 5, 2016 at 10:12 PM, Matthew Johnson  
>>>> wrote:
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>>> On Jun 5, 2016, at 6:56 AM, Andrew Bennett  wrote:
>>>>> 
>>>>> I like this.
>>>>> 
>>>>> One of the suggestions on @noescape(once) was that it just becomes @once 
>>>>> and works with escaping closures too. It might be possible if compile 
>>>>> time checks verified that the closure isn't copied, and that it is called 
>>>>> before being deinit-ialized. Failing that I'm happy with a runtime 
>>>>> circumstance in the cases the compiler can't check.
>>>> 
>>>> Yeah, maybe if it is only used asynchronously and never stored in a member 
>>>> or global it could be verified and that is a pretty common case.  That 
>>>> would certainly be easier than the general case.
>>>> 
>>>> I prefer @once over @required if the guarantee is single execution.  If 
>>>> the guarantee is *at least once* obviously @once is not the right 
>>>> attribute, but I'm not convinced @required is either.  Maybe @invoked.
>>>> 
>>>>> 
>>>>> It would be great if @required took into the account the feedback from 
>>>>> that proposal and considered t

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 5, 2016, at 8:52 AM, Andrew Bennett  wrote:
> 
> Storing into a member would be fine, as long as it must keep @once as a type 
> annotation and the compiler makes sure you maintain:
> sum(callCount, storeCount, passCount) == 1
> 
> For example:
>   class Example {
> private var closure: (@once (T) -> Void)?
> 
> func callClosure(value: T, replace: (@once (T) -> Void)? = nil) {
>   // the compiler should error if it detects the closure:
>   //  * escaping more than once, while still being stored,
>   //  * or being called while still being stored or escaping,
>   //  * or being overwritten without being called
>   if let closure = self.closure {
> self.closure = replace
> closure(value)
>   }
> }
> 
> deinit {
>   // compiler warning: that closure is potentially un-called
>   // runtime fatalError if it's .Some(Closure) after deinit
> }
>   }
> 
> There could be a standard library type with those guarantees built in.

I don't consider this compiler verification.  It is runtime verification.  The 
best the compiler can do is enforce constraints that allow for guaranteed 
runtime verification.  You can argue that is better than nothing but it is not 
a static guarantee of correct behavior.

> 
> 
>> On Sun, Jun 5, 2016 at 10:12 PM, Matthew Johnson  
>> wrote:
>> 
>> 
>> Sent from my iPad
>> 
>>> On Jun 5, 2016, at 6:56 AM, Andrew Bennett  wrote:
>>> 
>>> I like this.
>>> 
>>> One of the suggestions on @noescape(once) was that it just becomes @once 
>>> and works with escaping closures too. It might be possible if compile time 
>>> checks verified that the closure isn't copied, and that it is called before 
>>> being deinit-ialized. Failing that I'm happy with a runtime circumstance in 
>>> the cases the compiler can't check.
>> 
>> Yeah, maybe if it is only used asynchronously and never stored in a member 
>> or global it could be verified and that is a pretty common case.  That would 
>> certainly be easier than the general case.
>> 
>> I prefer @once over @required if the guarantee is single execution.  If the 
>> guarantee is *at least once* obviously @once is not the right attribute, but 
>> I'm not convinced @required is either.  Maybe @invoked.
>> 
>>> 
>>> It would be great if @required took into the account the feedback from that 
>>> proposal and considered the synchronous case too.
>>> 
>>> As an aside, you can get some of the guarantees you want like this:
>>> 
>>> func doSomething(completionHandler: (SomeEnum) -> ()) {
>>>   dispatch_async(someQueue) {
>>> let result: SomeEnum
>>> // the compiler ensures 'result' is set
>>>     defer { completionHandler(result) }
>>> 
>>> if aCondition {
>>>   if bCondition {
>>> result = .Foo
>>>   } else {
>>> result = .Bar
>>>   }
>>>   // the compiler ensures you do this, because it is 'let'
>>>   return
>>> }
>>> 
>>> if cCondition {
>>>   result = .Baz
>>> }
>>>   }
>>> }
>>> 
>>>> On Sun, Jun 5, 2016 at 9:42 PM, Matthew Johnson via swift-evolution 
>>>>  wrote:
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>>> On Jun 5, 2016, at 5:02 AM, Patrick Pijnappel via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> This has actually been proposed before, see SE-0073: 
>>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0073-noescape-once.md
>>>> 
>>>> Actually that proposal was for noescape closures and this suggestion is 
>>>> for escaping closures.  I don't think the compiler can verify this for 
>>>> noescape closures.  If it is possible it would be far more complicated.
>>>> 
>>>>> 
>>>>> 
>>>>>> On Sun, Jun 5, 2016 at 11:37 AM, Charles Srstka via swift-evolution 
>>>>>>  wrote:
>>>>>> MOTIVATION:
>>>>>> 
>>>>>> As per the current situation, there is a pitfall when writing 
>>>>>> asynchronous APIs that does not occur when writing synchronous APIs. 
>>>>>> Consider the following synchronous API:
>>>>>> 
>>>>>> f

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 5, 2016, at 6:56 AM, Andrew Bennett  wrote:
> 
> I like this.
> 
> One of the suggestions on @noescape(once) was that it just becomes @once and 
> works with escaping closures too. It might be possible if compile time checks 
> verified that the closure isn't copied, and that it is called before being 
> deinit-ialized. Failing that I'm happy with a runtime circumstance in the 
> cases the compiler can't check.

Yeah, maybe if it is only used asynchronously and never stored in a member or 
global it could be verified and that is a pretty common case.  That would 
certainly be easier than the general case.

I prefer @once over @required if the guarantee is single execution.  If the 
guarantee is *at least once* obviously @once is not the right attribute, but 
I'm not convinced @required is either.  Maybe @invoked.

> 
> It would be great if @required took into the account the feedback from that 
> proposal and considered the synchronous case too.
> 
> As an aside, you can get some of the guarantees you want like this:
> 
> func doSomething(completionHandler: (SomeEnum) -> ()) {
>   dispatch_async(someQueue) {
> let result: SomeEnum
> // the compiler ensures 'result' is set
> defer { completionHandler(result) }
> 
> if aCondition {
>   if bCondition {
> result = .Foo
>   } else {
> result = .Bar
>   }
>   // the compiler ensures you do this, because it is 'let'
>   return
>     }
> 
> if cCondition {
>   result = .Baz
> }
>   }
> }
> 
>> On Sun, Jun 5, 2016 at 9:42 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> Sent from my iPad
>> 
>>> On Jun 5, 2016, at 5:02 AM, Patrick Pijnappel via swift-evolution 
>>>  wrote:
>>> 
>>> This has actually been proposed before, see SE-0073: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0073-noescape-once.md
>> 
>> Actually that proposal was for noescape closures and this suggestion is for 
>> escaping closures.  I don't think the compiler can verify this for noescape 
>> closures.  If it is possible it would be far more complicated.
>> 
>>> 
>>> 
>>>> On Sun, Jun 5, 2016 at 11:37 AM, Charles Srstka via swift-evolution 
>>>>  wrote:
>>>> MOTIVATION:
>>>> 
>>>> As per the current situation, there is a pitfall when writing asynchronous 
>>>> APIs that does not occur when writing synchronous APIs. Consider the 
>>>> following synchronous API:
>>>> 
>>>> func doSomething() -> SomeEnum {
>>>> if aCondition {
>>>> if bCondition {
>>>> return .Foo
>>>> } else {
>>>> return .Bar
>>>> }
>>>> } else {
>>>> if cCondition {
>>>> return .Baz
>>>> }
>>>> }
>>>> }
>>>> 
>>>> The compiler will give an error here, since if both aCondition and 
>>>> cCondition are false, the function will not return anything.
>>>> 
>>>> However, consider the equivalent async API:
>>>> 
>>>> func doSomething(completionHandler: (SomeEnum) -> ()) {
>>>> dispatch_async(someQueue) {
>>>> if aCondition {
>>>> if bCondition {
>>>> completionHandler(.Foo)
>>>> } else {
>>>> completionHandler(.Bar)
>>>> }
>>>> } else {
>>>> if cCondition {
>>>> completionHandler(.Baz)
>>>> }
>>>> }
>>>> }
>>>> }
>>>> 
>>>> Whoops, now the function can return without ever firing its completion 
>>>> handler, and the problem might not be discovered until runtime (and, 
>>>> depending on the complexity of the function, may be hard to find).
>>>> 
>>>> PROPOSED SOLUTION:
>>>> 
>>>> Add a @required attribute that can be applied to closure arguments. This 
>>>> attribute simply states that the given closure will always be eventually 
>>>> called, and the 

Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 5, 2016, at 5:02 AM, Patrick Pijnappel via swift-evolution 
>  wrote:
> 
> This has actually been proposed before, see SE-0073: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0073-noescape-once.md

Actually that proposal was for noescape closures and this suggestion is for 
escaping closures.  I don't think the compiler can verify this for noescape 
closures.  If it is possible it would be far more complicated.

> 
> 
>> On Sun, Jun 5, 2016 at 11:37 AM, Charles Srstka via swift-evolution 
>>  wrote:
>> MOTIVATION:
>> 
>> As per the current situation, there is a pitfall when writing asynchronous 
>> APIs that does not occur when writing synchronous APIs. Consider the 
>> following synchronous API:
>> 
>> func doSomething() -> SomeEnum {
>> if aCondition {
>> if bCondition {
>> return .Foo
>> } else {
>> return .Bar
>> }
>> } else {
>> if cCondition {
>> return .Baz
>> }
>> }
>> }
>> 
>> The compiler will give an error here, since if both aCondition and 
>> cCondition are false, the function will not return anything.
>> 
>> However, consider the equivalent async API:
>> 
>> func doSomething(completionHandler: (SomeEnum) -> ()) {
>> dispatch_async(someQueue) {
>> if aCondition {
>> if bCondition {
>> completionHandler(.Foo)
>> } else {
>> completionHandler(.Bar)
>> }
>> } else {
>> if cCondition {
>> completionHandler(.Baz)
>> }
>> }
>> }
>> }
>> 
>> Whoops, now the function can return without ever firing its completion 
>> handler, and the problem might not be discovered until runtime (and, 
>> depending on the complexity of the function, may be hard to find).
>> 
>> PROPOSED SOLUTION:
>> 
>> Add a @required attribute that can be applied to closure arguments. This 
>> attribute simply states that the given closure will always be eventually 
>> called, and the compiler can enforce this.
>> 
>> DETAILED DESIGN:
>> 
>> - The @required attribute states in our API contract that a given closure 
>> *must* be called at some point after the function is called.
>> 
>> - Standard API calls like dispatch_async that contractually promise to 
>> execute a closure or block get @required added to their signatures.
>> 
>> - When the compiler sees a @required closure in a function declaration, it 
>> checks to make sure that every execution path either calls the closure at 
>> some point, or sends a @required closure to another API that eventually ends 
>> up calling the closure.
>> 
>> - If there’s a way for a @required closure not to be called, the compiler 
>> emits an error letting the developer know about the bug in his/her code.
>> 
>> IMPACT ON EXISTING CODE:
>> 
>> None. This is purely additive.
>> 
>> ALTERNATIVES CONSIDERED:
>> 
>> I got nothin’.
>> 
>> 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: 'T(literal)' should construct T using the appropriate literal protocol if possible

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

> On Jun 4, 2016, at 10:27 AM, LM  wrote:
> 
> 
> 
> On Jun 4, 2016, at 4:00 PM, Matthew Johnson via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On Jun 3, 2016, at 9:30 PM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>> On Jun 3, 2016, at 7:08 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>> wrote:
>>>>> On Jun 3, 2016, at 8:11 PM, John McCall >>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>> 
>>>>>> On Jun 3, 2016, at 5:13 PM, Matthew Johnson >>>>> <mailto:matt...@anandabits.com>> wrote:
>>>>>> On Jun 3, 2016, at 6:23 PM, John McCall >>>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>>> 
>>>>>>>>> On Jun 3, 2016, at 4:07 PM, David Sweeris >>>>>>>> <mailto:daveswee...@mac.com>> wrote:
>>>>>>>>> On Jun 3, 2016, at 16:17, Matthew Johnson via swift-evolution 
>>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>>> 
>>>>>>>>> Using an external parameter label in a declaration and allowing it to 
>>>>>>>>> be omitted at the call site does not feel like the right answer to 
>>>>>>>>> me.  I think we can find a better way to present this syntactically.
>>>>>>>> 
>>>>>>>> +eleventy gajillion
>>>>>>> 
>>>>>>> I'm actually quite happy with the user-facing aspects of the current 
>>>>>>> literal protocols and see zero reason to update them for this, so if 
>>>>>>> that's the choice, I'll just leave this aside.
>>>>>> 
>>>>>> Are you suggesting that preserving the current syntax of the literal 
>>>>>> protocols is more important than fixing this behavior so it works like 
>>>>>> most people seem to expect?  Why not be open to other syntactic 
>>>>>> solutions? 
>>>>> 
>>>>> I think fixing the behavior is good, and I stand by this proposal.  
>>>> 
>>>> I agree fixing it is good and we should do it.  I’m just trying to explore 
>>>> the solution space to see if there are any alternatives that might be more 
>>>> appealing.  Clearly you’ve thought about this a lot but it’s a new topic 
>>>> to consider for the rest of us.  :)
>>> 
>>> I'm sorry if I've come across as frustrated.  It's easy for me to forget 
>>> that things that I consider well-settled haven't always been covered in 
>>> depth here.  The community is not intentionally re-inventing things for no 
>>> purpose, it's making a genuine effort to explore the constraints on a part 
>>> of the language that it isn't familiar with the rationale for.
>> 
>> No problem.  I know it’s not fun to revisit hard-thought decisions that 
>> you’re happy with! :)  And I can see how it feels like we’re trying to do 
>> that here.  That said, these discussions are the best way for the community 
>> to become familiar with some of the rationale for the way things currently 
>> are.  :)
> 
> I find It helps to read the docs that has been produced (not all up to date 
> but still rich in background data). The source code is also a great place to 
> do a reality chk on ideas. 

Agree.  I have read most of the docs found here: 
https://github.com/apple/swift/tree/master/docs 
<https://github.com/apple/swift/tree/master/docs>.  But docs can only cover so 
much.  A lot of knowledge is often shared communally, but not explicitly 
documented.

> 
> @john thank you for taking the time to share.
> 
> 
>> 
>>> 
>>>>> There is, however, nothing glaringly wrong with the literal protocols.  
>>>>> They do not need to redesigned simply because we found a syntactic 
>>>>> interaction that needs to be cleaned up.
>>>>> 
>>>>> There are good reasons the protocols have evolved the way they have.  The 
>>>>> labels clearly mark the purpose of each initializer and distinguish one 
>>>>> from another on types that support multiple literal kinds.  The labels 
>>>>> also clearly indicate that the initializers are not intended for general 
>>>>> use.  The argument(s) to the initializer do not always represent a single 
>>>>> value of literal type. 

Re: [swift-evolution] Ad hoc enums / options

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


Sent from my iPhone

> On Jun 4, 2016, at 9:58 AM, Hooman Mehr  wrote:
> 
> How about this:
> 
> 
> Going back to Erica’s original example:
> 
> func scaleAndCropImage(
> image: UIImage,
> toSize size: CGSize,
> operation: (.Fit | .Fill) = .Fit
> ) -> UIImage {
> 
> And noting that we are already allowed to declare an enum inside the 
> function, compiler can generate  an enum scoped inside the function named the 
> label of the enum:
> 
> func scaleAndCropImage(
> image: UIImage,
> toSize size: CGSize,
> operation: (.Fit | .Fill) = .Fit
> ) -> UIImage {
>   @_exposed num operation {
>   case Fit
>   case Fill
> }
> 
> Then you could declare a var:
> 
> var myOperation: scaleAndCropImage.operation = .Fill
> 
> Then you can call:
> 
> let scaledImage = scaleAndCropImage(image: myImage, toSize: theSize, 
> operation: myOperation)
> 
> @_exposed above would be a compiler private annotation for the auto generated 
> enum that will make if visible outside of the function. This way the impact 
> is minimal and such ad hoc enum would be just the same as any other enum. The 
> only big change in the compiler would be the ability to make some declaration 
> inside functions visible to the outside code.
> 

The type name would be super verbose, but this does address the basic concerns 
I have with the original proposal and it is a lot simpler than structural 
subtyping.


>> On Jun 3, 2016, at 5:10 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>>> On Jun 3, 2016, at 6:44 PM, Erica Sadun  wrote:
>>>> 
>>>> 
>>>> On Jun 3, 2016, at 5:20 PM, Greg Parker via swift-evolution 
>>>>  wrote:
>>>> What about the ABI? This sounds expensive to implement.
>>>> 
>>>> Consider this set of ad-hoc enum types:
>>>> 
>>>> (.a | .b)
>>>> (.c | .d)
>>>> 
>>>> Naive implementation: we'll represent these things as ints, with .a=1, 
>>>> .b=2, .c=1, .d=2.
>>>> 
>>>> The naive implementation breaks when a newly-loaded shared library or some 
>>>> library evolution adds this type:
>>>> 
>>>> (.a | .b | .c | .d)
>>>> 
>>>> In order to provide ABI stability in the face of arbitrary ad-hoc enum 
>>>> types we must ensure that every ad-hoc enum value has a globally unique 
>>>> ABI representation. 
>>>> 
>>>> You could constrain ad-hoc enum values to module or class boundaries and 
>>>> prevent creation of types that use values from different places. For 
>>>> example, if Foundation defines (.a | .b) then you can't define your own 
>>>> ad-hoc enum (.a | .b | .c) that is compatible with Foundation's value for 
>>>> .a. Then the implementation could use ordinary symbols. If usage of ad-hoc 
>>>> enums is not constrained then ordinary symbols don't work because there is 
>>>> no universally agreed-upon place where .a is defined.
>>> 
>>> In my mind, the ad hoc enum must be tied to a specific function or method 
>>> signature. In doing so, it has a unique module/selector associated with it, 
>>> so it's not just .a but rather Foo.funcname.a (assuming no more than one ad 
>>> hoc enum per function) or Foo.funcname.3.a (assuming its the third 
>>> parameter of the selector). The conversation has drifted a bit from my 
>>> request.
>>> 
>>> If the enum needs to be used in more situations, it needs to be a proper 
>>> enum because the semantics are tied to a higher level of visibility.
>>> 
>>> I'm striving for enhanced readability in intent (for example, where !x is a 
>>> poor description of the option other than x, or even when there are >2 
>>> options that will never be used elsewhere such as fill, fit, scale) and in 
>>> expression (choosing self-annotating switch statements over if statements, 
>>> where its clear what each branch intends to do).
>>> 
>>> These enums would be limited to basic hashValue types, and would appear in 
>>> QuickHelp as annotations of legal values to supply to the argument. My 
>>> intent is that there never be more than 3-5 enumeration cases used in this 
>>> anonymous fashion.
>> 
>> Are you still insisting that we not be able to declare a variable holding 
>> one of these to call the function with later?  If so, what is the 
>> justification for placing a burden on callers that the argument must always 
>> be a literal?  If not, how do you suggest a variable be declared?
>> 
>>> 
>>> -- 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

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

> On Jun 3, 2016, at 9:30 PM, John McCall  wrote:
> 
>> On Jun 3, 2016, at 7:08 PM, Matthew Johnson  wrote:
>>> On Jun 3, 2016, at 8:11 PM, John McCall  wrote:
>>> 
>>>> On Jun 3, 2016, at 5:13 PM, Matthew Johnson  wrote:
>>>> On Jun 3, 2016, at 6:23 PM, John McCall  wrote:
>>>> 
>>>>>>> On Jun 3, 2016, at 4:07 PM, David Sweeris  wrote:
>>>>>>> On Jun 3, 2016, at 16:17, Matthew Johnson via swift-evolution 
>>>>>>>  wrote:
>>>>>>> 
>>>>>>> Using an external parameter label in a declaration and allowing it to 
>>>>>>> be omitted at the call site does not feel like the right answer to me.  
>>>>>>> I think we can find a better way to present this syntactically.
>>>>>> 
>>>>>> +eleventy gajillion
>>>>> 
>>>>> I'm actually quite happy with the user-facing aspects of the current 
>>>>> literal protocols and see zero reason to update them for this, so if 
>>>>> that's the choice, I'll just leave this aside.
>>>> 
>>>> Are you suggesting that preserving the current syntax of the literal 
>>>> protocols is more important than fixing this behavior so it works like 
>>>> most people seem to expect?  Why not be open to other syntactic solutions? 
>>> 
>>> I think fixing the behavior is good, and I stand by this proposal.  
>> 
>> I agree fixing it is good and we should do it.  I’m just trying to explore 
>> the solution space to see if there are any alternatives that might be more 
>> appealing.  Clearly you’ve thought about this a lot but it’s a new topic to 
>> consider for the rest of us.  :)
> 
> I'm sorry if I've come across as frustrated.  It's easy for me to forget that 
> things that I consider well-settled haven't always been covered in depth 
> here.  The community is not intentionally re-inventing things for no purpose, 
> it's making a genuine effort to explore the constraints on a part of the 
> language that it isn't familiar with the rationale for.

No problem.  I know it’s not fun to revisit hard-thought decisions that you’re 
happy with! :)  And I can see how it feels like we’re trying to do that here.  
That said, these discussions are the best way for the community to become 
familiar with some of the rationale for the way things currently are.  :)

> 
>>> There is, however, nothing glaringly wrong with the literal protocols.  
>>> They do not need to redesigned simply because we found a syntactic 
>>> interaction that needs to be cleaned up.
>>> 
>>> There are good reasons the protocols have evolved the way they have.  The 
>>> labels clearly mark the purpose of each initializer and distinguish one 
>>> from another on types that support multiple literal kinds.  The labels also 
>>> clearly indicate that the initializers are not intended for general use.  
>>> The argument(s) to the initializer do not always represent a single value 
>>> of literal type.  Some protocols provide multiple initializers, and it is 
>>> quite possible that that will become gradually more common as we explore 
>>> ways to grant more flexibility to code outside of the standard library.  
>>> And we actually consider it good that you can invoke these initializers 
>>> explicitly; it's only accidental use that we feel it's important to avoid, 
>>> which labels provide excellent protection against.
>> 
>> If it is important that these initializers be callable directly I suppose 
>> the label is the only way to go.  I can’t think of a reason why this is 
>> necessary though.  I would consider it bad design for a type that expects to 
>> be initialized with an Int variable to require its callers to use the label, 
>> as opposed to providing an alternate initializer that doesn’t have a label 
>> with “literal” in its name.  Are there specific use cases where you think 
>> this capability is important or is it just the principle that you should be 
>> able to call any initializer you write?
> 
> Partly that principle, but partly the ability to forward 
> literal-initialization.  You can forward literal-initialization to, say, a 
> BuiltinIntegerLiteralConvertible type by just appointing it your associated 
> IntegerLiteralType, but if you're wrapping another type, that doesn't work.  
> For example:
> 
>  struct MyValue : IntegerLiteralConvertible {
>init(integerLiteral literal: JSONValue.IntegerLiteralType) {
>  json = J

Re: [swift-evolution] Ad hoc enums / options

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


Sent from my iPad

> On Jun 3, 2016, at 10:27 PM, Félix Cloutier  wrote:
> 
> If there's any interest in going down that road, it seems to me that the only 
> viable option is to allow subsets to be convertible to their superset. Items 
> of (.foo | .bar) would be convertible to (.foo | .bar | .baz), but not the 
> opposite (and not necessarily, although preferably, through a simple bitcast).

Yes, I suppose in this case implicit convertibility would suffice.  Thanks for 
bringing it up.  It is effectively a subtype relationship.

> 
> Félix
> 
>>> Le 3 juin 2016 à 16:20:18, Greg Parker via swift-evolution 
>>>  a écrit :
>>> 
>>> 
>>>> On Jun 1, 2016, at 5:42 PM, Matthew Johnson via swift-evolution 
>>>>  wrote:
>>>> 
>>>>> On Jun 1, 2016, at 5:02 PM, Vladimir.S via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> in other words, we could consider allowing this:
>>>>>   func foo(bar: (.fit | .fill)) {
>>>>> baz(bar: bar)
>>>>>   }
>>>>>   func baz(bar: (.fit | .fill | .florp) { ... }
>>>>> 
>>>>> In other words, an ad hoc enum T can be used wherever an ad hoc enum U is
>>>>> expected if T ⊆ U.
>>>> 
>>>> Can't agree with this. Just because the same analogue with tuples : 
>>>> differently defined tuples are different types. Tuples with different 
>>>> order of types in declaration - are different types. So I expect here 
>>>> instance of (.fit | .fill) `bar` is not of the same type as (.fit | .fill 
>>>> | .florp)
>>> 
>>> They are not the same type but there is a structural subtype relationship 
>>> between them.  All values of type (.fit | .fill) are also values of type 
>>> (.fit | .fill | .florp).
>> 
>> What about disjoint types? Some values of type (.fit | .fill) are values of 
>> type (.fit | .florp) and some are not. I'm not a type system expert but my 
>> understanding is that this capability gets very complicated very fast.
>> 
>> 
>> What about the ABI? This sounds expensive to implement.
>> 
>> Consider this set of ad-hoc enum types:
>> 
>>   (.a | .b)
>>   (.c | .d)
>> 
>> Naive implementation: we'll represent these things as ints, with .a=1, .b=2, 
>> .c=1, .d=2.
>> 
>> The naive implementation breaks when a newly-loaded shared library or some 
>> library evolution adds this type:
>> 
>>   (.a | .b | .c | .d)
>> 
>> In order to provide ABI stability in the face of arbitrary ad-hoc enum types 
>> we must ensure that every ad-hoc enum value has a globally unique ABI 
>> representation. 
>> 
>> You could constrain ad-hoc enum values to module or class boundaries and 
>> prevent creation of types that use values from different places. For 
>> example, if Foundation defines (.a | .b) then you can't define your own 
>> ad-hoc enum (.a | .b | .c) that is compatible with Foundation's value for 
>> .a. Then the implementation could use ordinary symbols. If usage of ad-hoc 
>> enums is not constrained then ordinary symbols don't work because there is 
>> no universally agreed-upon place where .a is defined.
>> 
>> An implementation like ObjC's @selector or C/C++ weak definition would work, 
>> but those are expensive in memory overhead and launch time. 
>> 
>> You could give each linkage unit its own copy of the value that includes a 
>> string of the value's name plus an == operator that compares the name 
>> strings; that would avoid uniquing but would make some operations slow. 
>> 
>> In any case the performance of these things will not be comparable to ints 
>> nor to typical Swift enums that are encoded as ints.
>> 
>> 
>> -- 
>> 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


Re: [swift-evolution] [Proposal] Enum subsets

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


Sent from my iPad

> On Jun 4, 2016, at 12:34 AM, Austin Zheng via swift-evolution 
>  wrote:
> 
> It seems like it would make sense to model enum subsets as a subtype 
> relationship.
> 
> Is the core team planning on drawing up a structs/enums subtyping proposal 
> later this year?

+1.  Subtype relationship is mostly what is desired here.  

Some people have also talked about members of the supertype also being 
available on the subtype which would involve implementation inheritance.  That 
could probably be made to work for enums if the subtype receives identical 
storage and as long as all supertype members are considered final (because 
value type members are always final).  But it's a slippery slope and would 
likely bloat the storage of many subtype enums.

-Matthew

> 
> Austin
> 
>>> On Jun 3, 2016, at 10:25 PM, Chris Lattner  wrote:
>>> 
>>> 
>>> On Jun 3, 2016, at 2:35 PM, T.J. Usiyan via swift-evolution 
>>>  wrote:
>>> 
>>> Since this seems to have some interest, I've made a gist.
>>> 
>>> https://gist.github.com/griotspeak/963bc87a0c244c120264b11fb022d78c
>> 
>> We have frequently discussed introducing subtype relationships between 
>> structs and enums, in an effort to allow limited implicit promotions (e.g. 
>> from small integers to wider integers).  Wouldn’t that be a more general 
>> solution to this same problem?
>> 
>> -Chris
> 
> ___
> 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: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-03 Thread Matthew Johnson via swift-evolution

> On Jun 3, 2016, at 8:11 PM, John McCall  wrote:
> 
>> On Jun 3, 2016, at 5:13 PM, Matthew Johnson  wrote:
>> On Jun 3, 2016, at 6:23 PM, John McCall  wrote:
>> 
>>>>> On Jun 3, 2016, at 4:07 PM, David Sweeris  wrote:
>>>>> On Jun 3, 2016, at 16:17, Matthew Johnson via swift-evolution 
>>>>>  wrote:
>>>>> 
>>>>> Using an external parameter label in a declaration and allowing it to be 
>>>>> omitted at the call site does not feel like the right answer to me.  I 
>>>>> think we can find a better way to present this syntactically.
>>>> 
>>>> +eleventy gajillion
>>> 
>>> I'm actually quite happy with the user-facing aspects of the current 
>>> literal protocols and see zero reason to update them for this, so if that's 
>>> the choice, I'll just leave this aside.
>> 
>> Are you suggesting that preserving the current syntax of the literal 
>> protocols is more important than fixing this behavior so it works like most 
>> people seem to expect?  Why not be open to other syntactic solutions? 
> 
> I think fixing the behavior is good, and I stand by this proposal.  

I agree fixing it is good and we should do it.  I’m just trying to explore the 
solution space to see if there are any alternatives that might be more 
appealing.  Clearly you’ve thought about this a lot but it’s a new topic to 
consider for the rest of us.  :)

> There is, however, nothing glaringly wrong with the literal protocols.  They 
> do not need to redesigned simply because we found a syntactic interaction 
> that needs to be cleaned up.
> 
> There are good reasons the protocols have evolved the way they have.  The 
> labels clearly mark the purpose of each initializer and distinguish one from 
> another on types that support multiple literal kinds.  The labels also 
> clearly indicate that the initializers are not intended for general use.  The 
> argument(s) to the initializer do not always represent a single value of 
> literal type.  Some protocols provide multiple initializers, and it is quite 
> possible that that will become gradually more common as we explore ways to 
> grant more flexibility to code outside of the standard library.  And we 
> actually consider it good that you can invoke these initializers explicitly; 
> it's only accidental use that we feel it's important to avoid, which labels 
> provide excellent protection against.

If it is important that these initializers be callable directly I suppose the 
label is the only way to go.  I can’t think of a reason why this is necessary 
though.  I would consider it bad design for a type that expects to be 
initialized with an Int variable to require its callers to use the label, as 
opposed to providing an alternate initializer that doesn’t have a label with 
“literal” in its name.  Are there specific use cases where you think this 
capability is important or is it just the principle that you should be able to 
call any initializer you write?

-Matthew

> 
> If you have specific criticisms of any of the literal protocols, e.g. you 
> find them limiting or non-performant for your own types, then you are welcome 
> to raise them here.  However, resemblance to actual literal syntax has never 
> been a design goal for the literal protocols; and besides, this will always 
> be a secondary literal syntax, one far less important than contextual typing.
> 
> John.

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-03 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Jun 3, 2016, at 6:23 PM, John McCall  wrote:

>>> On Jun 3, 2016, at 4:07 PM, David Sweeris  wrote:
>>> On Jun 3, 2016, at 16:17, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> Using an external parameter label in a declaration and allowing it to be 
>>> omitted at the call site does not feel like the right answer to me.  I 
>>> think we can find a better way to present this syntactically.
>> 
>> +eleventy gajillion
> 
> I'm actually quite happy with the user-facing aspects of the current literal 
> protocols and see zero reason to update them for this, so if that's the 
> choice, I'll just leave this aside.

Are you suggesting that preserving the current syntax of the literal protocols 
is more important than fixing this behavior so it works like most people seem 
to expect?  Why not be open to other syntactic solutions? 

> 
> John.

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


Re: [swift-evolution] Ad hoc enums / options

2016-06-03 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 3, 2016, at 6:44 PM, Erica Sadun  wrote:
> 
> 
>> On Jun 3, 2016, at 5:20 PM, Greg Parker via swift-evolution 
>>  wrote:
>> What about the ABI? This sounds expensive to implement.
>> 
>> Consider this set of ad-hoc enum types:
>> 
>>  (.a | .b)
>>  (.c | .d)
>> 
>> Naive implementation: we'll represent these things as ints, with .a=1, .b=2, 
>> .c=1, .d=2.
>> 
>> The naive implementation breaks when a newly-loaded shared library or some 
>> library evolution adds this type:
>> 
>>  (.a | .b | .c | .d)
>> 
>> In order to provide ABI stability in the face of arbitrary ad-hoc enum types 
>> we must ensure that every ad-hoc enum value has a globally unique ABI 
>> representation. 
>> 
>> You could constrain ad-hoc enum values to module or class boundaries and 
>> prevent creation of types that use values from different places. For 
>> example, if Foundation defines (.a | .b) then you can't define your own 
>> ad-hoc enum (.a | .b | .c) that is compatible with Foundation's value for 
>> .a. Then the implementation could use ordinary symbols. If usage of ad-hoc 
>> enums is not constrained then ordinary symbols don't work because there is 
>> no universally agreed-upon place where .a is defined.
> 
> In my mind, the ad hoc enum must be tied to a specific function or method 
> signature. In doing so, it has a unique module/selector associated with it, 
> so it's not just .a but rather Foo.funcname.a (assuming no more than one ad 
> hoc enum per function) or Foo.funcname.3.a (assuming its the third parameter 
> of the selector). The conversation has drifted a bit from my request.
> 
> If the enum needs to be used in more situations, it needs to be a proper enum 
> because the semantics are tied to a higher level of visibility.
> 
> I'm striving for enhanced readability in intent (for example, where !x is a 
> poor description of the option other than x, or even when there are >2 
> options that will never be used elsewhere such as fill, fit, scale) and in 
> expression (choosing self-annotating switch statements over if statements, 
> where its clear what each branch intends to do).
> 
> These enums would be limited to basic hashValue types, and would appear in 
> QuickHelp as annotations of legal values to supply to the argument. My intent 
> is that there never be more than 3-5 enumeration cases used in this anonymous 
> fashion.

Are you still insisting that we not be able to declare a variable holding one 
of these to call the function with later?  If so, what is the justification for 
placing a burden on callers that the argument must always be a literal?  If 
not, how do you suggest a variable be declared?

> 
> -- E
> 
> 

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


Re: [swift-evolution] Ad hoc enums / options

2016-06-03 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 3, 2016, at 6:20 PM, Greg Parker  wrote:
> 
> 
>>> On Jun 1, 2016, at 5:42 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>>> On Jun 1, 2016, at 5:02 PM, Vladimir.S via swift-evolution 
>>>>  wrote:
>>>> 
>>>> in other words, we could consider allowing this:
>>>>   func foo(bar: (.fit | .fill)) {
>>>> baz(bar: bar)
>>>>   }
>>>>   func baz(bar: (.fit | .fill | .florp) { ... }
>>>> 
>>>> In other words, an ad hoc enum T can be used wherever an ad hoc enum U is
>>>> expected if T ⊆ U.
>>> 
>>> Can't agree with this. Just because the same analogue with tuples : 
>>> differently defined tuples are different types. Tuples with different order 
>>> of types in declaration - are different types. So I expect here instance of 
>>> (.fit | .fill) `bar` is not of the same type as (.fit | .fill | .florp)
>> 
>> They are not the same type but there is a structural subtype relationship 
>> between them.  All values of type (.fit | .fill) are also values of type 
>> (.fit | .fill | .florp).
> 
> What about disjoint types? Some values of type (.fit | .fill) are values of 
> type (.fit | .florp) and some are not. I'm not a type system expert but my 
> understanding is that this capability gets very complicated very fast.

It feels like the only sane way to model these is as union types where each 
member of the union has a single literal value like '.fit'.  This is where 
structural subtyping would come from.

In your example I would say there is no subtype relationship there, just as a 
union of 'Fit | Fill' would not have any subtype / supertype relationship with 
'Fit | Florp' in a language like Ceylon that has union types.  

Without the structural subtyping these types would be way too fragile to be 
considered IMO.

> 
> 
> What about the ABI? This sounds expensive to implement.
> 
> Consider this set of ad-hoc enum types:
> 
>   (.a | .b)
>   (.c | .d)
> 
> Naive implementation: we'll represent these things as ints, with .a=1, .b=2, 
> .c=1, .d=2.
> 
> The naive implementation breaks when a newly-loaded shared library or some 
> library evolution adds this type:
> 
>   (.a | .b | .c | .d)
> 
> In order to provide ABI stability in the face of arbitrary ad-hoc enum types 
> we must ensure that every ad-hoc enum value has a globally unique ABI 
> representation. 
> 
> You could constrain ad-hoc enum values to module or class boundaries and 
> prevent creation of types that use values from different places. For example, 
> if Foundation defines (.a | .b) then you can't define your own ad-hoc enum 
> (.a | .b | .c) that is compatible with Foundation's value for .a. Then the 
> implementation could use ordinary symbols. If usage of ad-hoc enums is not 
> constrained then ordinary symbols don't work because there is no universally 
> agreed-upon place where .a is defined.
> 
> An implementation like ObjC's @selector or C/C++ weak definition would work, 
> but those are expensive in memory overhead and launch time. 
> 
> You could give each linkage unit its own copy of the value that includes a 
> string of the value's name plus an == operator that compares the name 
> strings; that would avoid uniquing but would make some operations slow. 
> 
> In any case the performance of these things will not be comparable to ints 
> nor to typical Swift enums that are encoded as ints.

You bring up very good points.  I'm not saying we *should* do this.  Only that 
if we do introduce ad-hoc enums this seems like the only sane way to do it.  I 
would want to be able to declare declare variables, etc that use the type 
without having every mention of the type break when the author of the function 
adds a new option.

My opinion is that everything you bring up is a pretty solid argument against 
ad-hoc enums.  Maybe is Swift ever gets union types we could revisit the idea 
under that umbrella (but that is sounding unlikely, and is definitely not 
something that will happen soon).

> 
> 
> -- 
> Greg Parker gpar...@apple.com Runtime Wrangler
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-03 Thread Matthew Johnson via swift-evolution

> On Jun 3, 2016, at 4:05 PM, Brent Royal-Gordon  wrote:
> 
>> I am not the only one who feels that way.  Quoting Brent:
>> 
>> "But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
>> don't think that's a good idea. Parameter labels are supposed to be 
>> significant; we don't want to lose that.”
>> 
>> I agree with this.  That is the motivation for my suggestion.  I think it’s 
>> at least worth discussing as an alternative to magically allowing an 
>> external parameter label to be omitted.  Brent, what do you think of my 
>> suggestion?
> 
> I think it could be simpler:
> 
>   public struct Literal {
>   public let value: LiteralType
>   internal init(_value value: LiteralType)
>   }
>   
>   public protocol IntegerLiteralConvertible {
>   associatedtype IntegerLiteralType
>   init(_ literal: Literal)
>   }
> 
> Only the standard library can create a Literal, which it would do by 
> constructing the IntegerLiteralType with its magic builtin literal stuff and 
> wrapping it. You still have your magic parameter aspect, but without any 
> actual magic, just access control. 

I like this solution as well as Xiaodi’s `@literal` idea better than the idea I 
came up with.  I think I like `@literal` best because it feels more appropriate 
to restrict an attribute to a specific context (signatures for literal 
convertible initializers) than anything else.  We don’t want to allow this in 
any other signatures and no types are restricted in that way.  The solution I 
came up with has that problem as well as the `#literal` “value” that is also 
restricted unlike other compiler generated values.  

I think our decision should be based upon which syntactic construct feels least 
inconsistent with other similar syntactic constructs and therefore feels the 
least arbitrary.  Restricting the usage of a generic `Literal` type to literal 
convertible initializers feels a little bit less arbitrary than allowing the 
call site to omit a label, but it feels a little bit more arbitrary than 
introducing an attribute that has a very specialized context of applicability.

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

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-03 Thread Matthew Johnson via swift-evolution

> On Jun 3, 2016, at 3:17 PM, John McCall  wrote:
> 
>> On Jun 3, 2016, at 12:41 PM, Matthew Johnson > > wrote:
>>> On Jun 3, 2016, at 1:36 PM, John McCall >> > wrote:
>>> 
 On Jun 2, 2016, at 6:48 PM, Matthew Johnson >>> > wrote:
 On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
>> On Jun 2, 2016, at 4:33 PM, Xiaodi Wu > > wrote:
>> The IntegerLiteral type idea might be worth exploring. It does seem to 
>> provide some additional consistency. For example, wasn't it clarified on 
>> this list just recently that literals don't have a type and adopt one 
>> based on context? It'd be nice to point out that 42 is an IntegerLiteral 
>> when explaining that it's not an Int.
> 
> I think that's a very promising way of thinking about literals.  Writing 
> a literal creates a notional value whose type is the informal, 
> infinite-precise type of all integer/FP/collection/etc. literals, which 
> (1) can be implicitly converted to any type that implements the 
> appropriate protocol and (2) in fact *must* be converted to some such 
> type (possibly the default type for that literal) in order for the code 
> to be executable.  You can then think about this proposal as saying that 
> an explicit conversion from that informal type to a literal-convertible 
> type follows the same path as an implicit conversion would have.
 
 It sounds like the reason you don't want to remove the label is because it 
 distinguishes the literal initializer and you don't want it called with a 
 variable accidentally right?  
 
 What if we do something like this:
 
 init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal)
 
 The idea here is that the IntegerLiteral type and friends are special 
 types that have no members and cannot be used except by the literal 
 convertible protocols and their conformances.  There is nothing you can do 
 with the value at all.  
 
 The trick is that by defaulting it to #literal we are indicating the 
 compiler synthesizes the logical value, as with #file, #line, etc.  The 
 compiler would refuse to synthesize this value when a literal is not used. 
  This means it is never selected when the user provides a variable to a 
 converting initializer.  If an independent initializer accepting a value 
 of the same type also exists that would be selected.  However, when a 
 literal *is* used and the type conforms to the relevant literal 
 convertible protocol the compiler always synthesized the value making it 
 always the most specific overload.
 
 Of course no runtime value would actually exist.  This is just a logical 
 value marking the fact that a literal was used to call the initializer.  
 
 This approach solves the same problem while retaining semantic consistency 
 with the language (no label elision or short circuit of overload 
 resolution).  The magic is arguably a lot more restrained - types for 
 which values can only be supplied by the compiler.  We could artificially 
 restrict usage of these types if we wanted to, but we wouldn't have to.  
 Nothing could be accomplished by using the types anywhere else so nobody 
 do so and it wouldn't be actively harmful to allow them to be used 
 anywhere other types can be used.  Only the ability to create values of 
 the type needs to be restricted and we can already write types like that 
 by marking the initializers private.
 
 Any thoughts on this approach?
>>> 
>>> This is still a special-case type-checking rule, which means that it's 
>>> still basically my proposal except, instead of just rewriting the call to 
>>> use a labeled literal initializer, it rewrites the call to use a magic 
>>> initializer which cannot be used by users because it requires arguments 
>>> that users cannot create.  I just don't understand the motivation here.  
>>> It's not a simpler language model to use, explain, or implement; it 
>>> purports to be conceptually simpler and less magical while actually 
>>> inventing two magic new language concepts (IntegerLiteral and #literal) on 
>>> top of the same special cases.
>> 
>> I understand that this is still a special case and also that the 
>> implementation is pretty much identical.  But I think the way it is 
>> presented to users is important. 
>> 
>>  The motivation is to come up with a design that lets us implement your 
>> proposal without magically eliding a parameter label.  There is no other 
>> case in Swift where you can directly call any function (initializer or 
>> otherwise) without including labels for all parameters that have external 
>> labels.
> 
> Don't think of it as omitting a parameter

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-03 Thread Matthew Johnson via swift-evolution

> On Jun 3, 2016, at 1:36 PM, John McCall  wrote:
> 
>> On Jun 2, 2016, at 6:48 PM, Matthew Johnson > > wrote:
>> On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
 On Jun 2, 2016, at 4:33 PM, Xiaodi Wu >>> > wrote:
 The IntegerLiteral type idea might be worth exploring. It does seem to 
 provide some additional consistency. For example, wasn't it clarified on 
 this list just recently that literals don't have a type and adopt one 
 based on context? It'd be nice to point out that 42 is an IntegerLiteral 
 when explaining that it's not an Int.
>>> 
>>> I think that's a very promising way of thinking about literals.  Writing a 
>>> literal creates a notional value whose type is the informal, 
>>> infinite-precise type of all integer/FP/collection/etc. literals, which (1) 
>>> can be implicitly converted to any type that implements the appropriate 
>>> protocol and (2) in fact *must* be converted to some such type (possibly 
>>> the default type for that literal) in order for the code to be executable.  
>>> You can then think about this proposal as saying that an explicit 
>>> conversion from that informal type to a literal-convertible type follows 
>>> the same path as an implicit conversion would have.
>> 
>> It sounds like the reason you don't want to remove the label is because it 
>> distinguishes the literal initializer and you don't want it called with a 
>> variable accidentally right?  
>> 
>> What if we do something like this:
>> 
>> init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal)
>> 
>> The idea here is that the IntegerLiteral type and friends are special types 
>> that have no members and cannot be used except by the literal convertible 
>> protocols and their conformances.  There is nothing you can do with the 
>> value at all.  
>> 
>> The trick is that by defaulting it to #literal we are indicating the 
>> compiler synthesizes the logical value, as with #file, #line, etc.  The 
>> compiler would refuse to synthesize this value when a literal is not used.  
>> This means it is never selected when the user provides a variable to a 
>> converting initializer.  If an independent initializer accepting a value of 
>> the same type also exists that would be selected.  However, when a literal 
>> *is* used and the type conforms to the relevant literal convertible protocol 
>> the compiler always synthesized the value making it always the most specific 
>> overload.
>> 
>> Of course no runtime value would actually exist.  This is just a logical 
>> value marking the fact that a literal was used to call the initializer.  
>> 
>> This approach solves the same problem while retaining semantic consistency 
>> with the language (no label elision or short circuit of overload 
>> resolution).  The magic is arguably a lot more restrained - types for which 
>> values can only be supplied by the compiler.  We could artificially restrict 
>> usage of these types if we wanted to, but we wouldn't have to.  Nothing 
>> could be accomplished by using the types anywhere else so nobody do so and 
>> it wouldn't be actively harmful to allow them to be used anywhere other 
>> types can be used.  Only the ability to create values of the type needs to 
>> be restricted and we can already write types like that by marking the 
>> initializers private.
>> 
>> Any thoughts on this approach?
> 
> This is still a special-case type-checking rule, which means that it's still 
> basically my proposal except, instead of just rewriting the call to use a 
> labeled literal initializer, it rewrites the call to use a magic initializer 
> which cannot be used by users because it requires arguments that users cannot 
> create.  I just don't understand the motivation here.  It's not a simpler 
> language model to use, explain, or implement; it purports to be conceptually 
> simpler and less magical while actually inventing two magic new language 
> concepts (IntegerLiteral and #literal) on top of the same special cases.

I understand that this is still a special case and also that the implementation 
is pretty much identical.  But I think the way it is presented to users is 
important. 

 The motivation is to come up with a design that lets us implement your 
proposal without magically eliding a parameter label.  There is no other case 
in Swift where you can directly call any function (initializer or otherwise) 
without including labels for all parameters that have external labels.  
Creating a special case to allow that here is inconsistent.  Why wouldn’t look 
for a way to do this that treats the signature consistently with the rest of 
the language and is more in line with how we handle other compiler magic (i.e. 
#file, #line, etc)?

I am not the only one who feels that way.  Quoting Brent:

"But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
do

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-03 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Jun 3, 2016, at 7:08 AM, Brent Royal-Gordon  wrote:

>> This might be silly, but what if there were a struct with all of the 
>> relevant fields (not sure what the best name would be):
>> 
>> struct MemoryLayout {
>> let size: Int
>> let alignment: Int
>> let stride: Int
>> // etc
>> }
>> 
>> Then you’d only maybe need two functions:
>> 
>> memoryLayout(of:) and memoryLayout(ofType:)
> 
> Could the `memoryLayout` functions just return `(size: Int, alignment: Int, 
> spacing: Int)` tuples? It's hard to tell because it goes into Builtin land, 
> but I get the impression that these values are calculated at compile time 
> anyway, and if you only used one of them the optimizer could throw the others 
> away.

What would be the advantage of this over returning a value of a MemoryLayout 
type?  Obviously tuples can be destructured, but I can't think of any others.  
I would like to see struct destructuring someday.  I'm not sure destructuring 
is a strong enough argument to go with a tuple here.  If there is a good reason 
to have a MemoryLayout type we shouldn't drop it just for destructuring, which 
may eventually be possible anyway (I hope anyway).

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

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

>> On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution 
>>  wrote:
>> 
>> On Jun 2, 2016, at 4:33 PM, Xiaodi Wu  wrote:
>> The IntegerLiteral type idea might be worth exploring. It does seem to 
>> provide some additional consistency. For example, wasn't it clarified on 
>> this list just recently that literals don't have a type and adopt one based 
>> on context? It'd be nice to point out that 42 is an IntegerLiteral when 
>> explaining that it's not an Int.
> 
> I think that's a very promising way of thinking about literals.  Writing a 
> literal creates a notional value whose type is the informal, infinite-precise 
> type of all integer/FP/collection/etc. literals, which (1) can be implicitly 
> converted to any type that implements the appropriate protocol and (2) in 
> fact *must* be converted to some such type (possibly the default type for 
> that literal) in order for the code to be executable.  You can then think 
> about this proposal as saying that an explicit conversion from that informal 
> type to a literal-convertible type follows the same path as an implicit 
> conversion would have.

It sounds like the reason you don't want to remove the label is because it 
distinguishes the literal initializer and you don't want it called with a 
variable accidentally right?  

What if we do something like this:

init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal)

The idea here is that the IntegerLiteral type and friends are special types 
that have no members and cannot be used except by the literal convertible 
protocols and their conformances.  There is nothing you can do with the value 
at all.  

The trick is that by defaulting it to #literal we are indicating the compiler 
synthesizes the logical value, as with #file, #line, etc.  The compiler would 
refuse to synthesize this value when a literal is not used.  This means it is 
never selected when the user provides a variable to a converting initializer.  
If an independent initializer accepting a value of the same type also exists 
that would be selected.  However, when a literal *is* used and the type 
conforms to the relevant literal convertible protocol the compiler always 
synthesized the value making it always the most specific overload.

Of course no runtime value would actually exist.  This is just a logical value 
marking the fact that a literal was used to call the initializer.  

This approach solves the same problem while retaining semantic consistency with 
the language (no label elision or short circuit of overload resolution).  The 
magic is arguably a lot more restrained - types for which values can only be 
supplied by the compiler.  We could artificially restrict usage of these types 
if we wanted to, but we wouldn't have to.  Nothing could be accomplished by 
using the types anywhere else so nobody do so and it wouldn't be actively 
harmful to allow them to be used anywhere other types can be used.  Only the 
ability to create values of the type needs to be restricted and we can already 
write types like that by marking the initializers private.

Any thoughts on this approach?

> 
> John.
> 
>> 
>>> On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> > So, you think that this syntax is enticing to new developers who 
>>> > naturally think that the feature works the way that I'm proposing it 
>>> > should work, and you think that the right solution is to make the syntax 
>>> > illegal so that you can more conveniently tell them it doesn't work that 
>>> > way? :)
>>> 
>>> I think the difference between a cast (which merely reinterprets a value as 
>>> a compatible type) and a fullwidth conversion (which creates a similar 
>>> instance of an incompatible type) is very important to understanding how to 
>>> write Swift, and we shouldn't muddy the waters by creating a magic syntax.
>>> 
>>> > You can still tell them that it's a struct and you're calling an 
>>> > initializer on it; it's just that the initializer chosen is the special 
>>> > literal initializer because the argument is a literal.
>>> 
>>> If you're planning to change `IntegerLiteralConvertible` and friends to 
>>> require a fullwidth conversion initializer like `init(_ value: 
>>> IntegerLiteralType)`, then this is simply an overload resolution rule. In 
>>> that case, I think your proposal is fine.
>>> 
>>> But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
>>> don't think that's a good idea. Parameter labels are supposed to be 
>>> significant; we don't want to lose that.
>>> 
>>> --
>>> 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-evo

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:57 PM, Sean Heber  wrote:
> 
> This might be silly, but what if there were a struct with all of the relevant 
> fields (not sure what the best name would be):
> 
> struct MemoryLayout {
>  let size: Int
>  let alignment: Int
>  let stride: Int
> // etc
> }
> 
> Then you’d only maybe need two functions:
> 
> memoryLayout(of:) and memoryLayout(ofType:)

I like this much better than individual functions.  I do not like the next idea 
that considers using a property.  We moved away from that approach with 
dynamicType and should stick with that direction.  It's not worth bringing up 
that debate again IMO.

> 
> Or perhaps just a single property on all types named “memoryLayout” (or 
> whatever) that returns the MemoryLayout struct:
> 
> Int.memory.size
> type(of: 42).memoryLayout.size
> // etc
> 
> Or just a single property on UnsafePointer if we went that route..
> 
> It seems like this sort of approach would keep namespace pollution down, at 
> least?
> 
> l8r
> Sean
> 
> 
>>> On Jun 2, 2016, at 4:55 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
>>> I don't disagree with the points you make.  But one can argue that this is 
>>> a good thing.  It calls attention to code that requires extra attention and 
>>> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
>>> Verbosity was a deliberate choice in that case.
>> 
>> You know...rather than introducing a new type like MemoryLayout, would it 
>> make sense to do this with static properties on UnsafePointer?
>> 
>>UnsafePointer.pointeeSize
>>UnsafePointer.pointeeAlignment
>>UnsafePointer.pointeeSpacing
>> 
>> If you need this information, 90% of the time you're probably using 
>> UnsafePointer or one of its friends, right?
>> 
>> -- 
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:47 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Isn't this the same argument for .dynamicType over type(of:) though?
> 
> Given that that debate has been settled in favor of the latter, I think the 
> question today is how best to come up with a consistent scheme.
> 
> Earlier in this conversation, it was pointed out (by Matt, I think?) that one 
> key advantage of type(of:) is that it takes on a syntax that is actually 
> possible to write in Swift, since one cannot extend Any.

Yep, IMO we should stick with the strategy that if something *looks* like a 
user-definable construct it should be possible to at least write the 
declaration even if it wouldn't be possible to implement.  That rules out 
static or instance properties or methods that apply to all types.

> 
> If we take this principle to its logical conclusion, properties (of a type or 
> instance) which apply to Any should be global functions.
> 
>> On Thu, Jun 2, 2016 at 16:26 Russ Bishop  wrote:
>> 
>>> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu  wrote:
>>> 
>>> 
>>> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
>>> examples such as Array.size show how this solution can get confusing. And 
>>> even though there aren't fixed-length arrays in Swift, those may come one 
>>> day, making the syntax even more confusing.
>> 
>> 
>> Array.count is a function taking an instance; I’m not sure I agree it would 
>> be terribly confusing… then again I run in Xcode with the quick help pane 
>> open so I see the doc comments for every type, property, and function as I 
>> move around the code. It’s quite handy :)
>> 
>> I could see including memory in the name (or something similar) if we want 
>> to be extra clear about it.
>> 
>> Int.memorySize
>> Int.memoryAlignment
>> 
>> 
>> Ultimately the type’s size in memory is a property of the type so it seems 
>> clear that is where it belongs (being careful not to steal too much of the 
>> namespace of course).
>> 
>> 
>> Russ
> ___
> 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:25 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On the other hand, on its own sizeof() is not unsafe, and so the argument 
> that it should be longer to call attention to itself (by analogy with 
> UnsafePointer) isn't quite apt.

These operations aren't themselves unsafe.  But they are low level details that 
are not useful unless you are doing something that requires special care.  A 
name that stands out more calls attention to the surrounding code.  That is a 
good thing IMO.

> 
> And I'm not sure we really want to encourage anyone else to be defining a 
> global function named size(of:) anyway, so I wouldn't consider vacating that 
> name for end-user purposes to be a meaningful positive.
>> On Thu, Jun 2, 2016 at 16:15 Tony Allevato  wrote:
>> Given that these are fairly low-level values with very specialized uses, I 
>> definitely agree that they should be somehow namespaced in a way that 
>> doesn't cause us to make very common words unusable for our users.
>> 
>> Even size(of:) seems more general to me than I'd like. I'd like to see the 
>> word "memory" as part of the name somehow, whether it's a wrapping type or a 
>> function prefix of some sort. These values are specialized; we don't need to 
>> optimize typing them, IMO.
>> 
>>> On Thu, Jun 2, 2016 at 2:06 PM Xiaodi Wu via swift-evolution 
>>>  wrote:
>> 
>>> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution 
>>>  wrote:
>> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>> I still think the value-based APIs are misleading and that it would be 
>> better to ask people to just use a type explicitly.
>> 
>> John.
> 
> 
> I agree; in fact why aren’t these properties on the type itself? The type 
> is what matters; why can’t the type just tell me it’s size? 
> Having free functions or magic operators seems to be another holdover 
> from C. 
> 
> 
> Int.size
> Int.alignment
> Int.spacing
> 
> let x: Any = 5
> type(of: x).size
> 
> 
> The compiler should be able to statically know the first three values and 
> inline them. The second is discovering the size dynamically.
 
 Two reasons.  The first is that this is a user-extensible namespace via 
 static members, so it's somewhat unfortunate to pollute it with names from 
 the library.  The second is that there's currently no language mechanism 
 for adding a static member to every type, so this would have to be 
 built-in.  But I agree that in the abstract a static property would be 
 preferable.
>>> 
>>> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
>>> examples such as Array.size show how this solution can get confusing. And 
>>> even though there aren't fixed-length arrays in Swift, those may come one 
>>> day, making the syntax even more confusing.
>>> 
>> 
>>> ___
>>> 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: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 3:41 PM, John McCall  wrote:
> 
>>> On Jun 2, 2016, at 12:10 PM, Matthew Johnson  wrote:
>>> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>>>  wrote:
>>> 
>>> +1.
>>> 
>>> The primary advantage is that it aligns the language semantics with how 
>>> most programmers expect this common C-language-family idiom to behave and 
>>> removes a potential source of silently wrong code.
>>> 
>>> The primary disadvantage is that it introduces special-case behavior to 
>>> certain types of initializers (although, to be fair, this special-case 
>>> behavior is easily recognizable: unlabeled one-argument initializer with a 
>>> literal as the argument).
>>> 
>>> I think the advantage outweighs the disadvantage.
>> 
>> Agree.  This change basically means the label isn’t intended to be used by 
>> callers, but is only present to distinguish the initializer used by the 
>> protocol from any other unlabeled initializer accepting the same type.  But 
>> conceptually it is treated as the *most specific* unlabelled initializer 
>> possible, thus winning the overload resolution.
>> 
>> How important is it that we have the ability to distinguish between literals 
>> and non-literals with the same type?  If that isn’t important, maybe the 
>> literal convertible protocols could be reworked such that the label isn’t 
>> necessary.  That would eliminate the special-case elision of the label.
> 
> There is no way to rework the literal protocols so that this behavior just 
> falls out.  It's easy enough to convince yourself of this if you try to work 
> through an actual example.

Ok, I'll trust you on this point.  +1 on the idea as you proposed it.

> 
> John.
> 
>> 
>>> 
>>> This problem should be addressed one way or another. I prefer this 
>>> solution, but if it is rejected for whatever reason we should at least 
>>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>> 
>>> Austin
>>> 
 On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
  wrote:
 The official way to build a literal of a specific type is to write the 
 literal in an explicitly-typed context, like so:
 let x: UInt16 = 7
 or
 let x = 7 as UInt16
 
 Nonetheless, programmers often try the following:
 UInt16(7)
 
 Unfortunately, this does not attempt to construct the value using the 
 appropriate literal protocol; it instead performs overload resolution 
 using the standard rules, i.e. considering only single-argument unlabelled 
 initializers of a type which conforms to IntegerLiteralConvertible.  Often 
 this leads to static ambiguities or, worse, causes the literal to be built 
 using a default type (such as Int); this may have semantically very 
 different results which are only caught at runtime.
 
 In my opinion, using this initializer-call syntax to build an 
 explicitly-typed literal is an obvious and natural choice with several 
 advantages over the "as" syntax.  However, even if you disagree, it's 
 clear that programmers are going to continue to independently try to use 
 it, so it's really unfortunate for it to be subtly wrong.
 
 Therefore, I propose that we adopt the following typing rule:
 
   Given a function call expression of the form A(B) (that is, an expr-call 
 with a single, unlabelled argument) where B is an expr-literal or 
 expr-collection, if A has type T.Type for some type T and there is a 
 declared conformance of T to an appropriate literal protocol for B, then 
 the expression is always resolves as a literal construction of type T (as 
 if the expression were written "B as A") rather than as a general 
 initializer call.
 
 Formally, this would be a special form of the argument conversion 
 constraint, since the type of the expression A may not be immediately 
 known.
 
 Note that, as specified, it is possible to suppress this typing rule by 
 wrapping the literal in parentheses.  This might seem distasteful; it 
 would be easy enough to allow the form of B to include extra parentheses.  
 It's potentially useful to have a way to suppress this rule and get a 
 normal construction, but there are several other ways of getting that 
 effect, such as explicitly typing the literal argument (e.g. writing 
 "A(Int(B))").
 
 A conditional conformance counts as a declared conformance even if the 
 generic arguments are known to not satisfy the conditional conformance.  
 This permits the applicability of the rule to be decided without having to 
 first decide the type arguments, which greatly simplifies the 
 type-checking problem (and may be necessary for soundness; I didn't 
 explore this in depth, but it certainly feels like a very nasty sort of 
 dependence).  We could potentially weaken this for cases where A is a 
 direct type r

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 2:58 PM, Erica Sadun  wrote:
> 
> 
>> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> On Jun 2, 2016, at 1:30 PM, John McCall  wrote:
>> 
>>>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson  
>>>> wrote:
>>>> On Jun 2, 2016, at 12:01 PM, John McCall  wrote:
>>>> 
>>>>>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>>>>>>  wrote:
>>>>>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>> We could have a primary initializer like this:
>> 
>> init(_ type: T.Type)
>> 
>> It would look better than a default initializer that requires the type to be 
>> passed as a generic argument.  The fact that it is not labeled would make it 
>> clear that this is the primary initializer.
>> 
>>> 
>>> I still think the value-based APIs are misleading and that it would be 
>>> better to ask people to just use a type explicitly.
>> 
>> Sure.  I don't necessarily disagree.  But I think it's important to make 
>> clear that this is orthogonal to the struct vs free function discussion.  
>> That was the main point I was trying to make.  :)
>> 
>>> 
>>>> Adding the label will eliminate the potential for confusion about type vs 
>>>> metatype.  Wanting to know the size of the metatype is probably extremely 
>>>> rare, but there is not reason to prohibit it.
>>> 
>>> I agree that the label makes the problem better.
>>> 
>>> John.
> 
> 
> I do want to say that while I'm including this in Alternatives Considered 
> (and will update as soon as we finish lunch), that I stand by the 
> freestanding functions as preferable to this clever but extremely indirect 
> approach.
> 
> I believe the MemoryLayout type introduces a level of indirection that is 
> less helpful in the rare times the user will consume this functionality, that 
> it clutters calls and adds cognitive burden for reading code.
> 
> Let me give you some examples:
> 
> let errnoSize = sizeof(errno.dynamicType)
> return sizeof(UInt) * 8
> sendBytes(from: &address, count: sizeof(UInt.self))
> _class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
> bytesPerIndex: sizeof(IndexType))
> 
> In every example, calling a size function's clarity is simpler than using the 
> Memory Layout approach:
> 
> let errnoSize = MemoryLayout.init(t: errno).size
> return MemoryLayout.size * 8
> sendBytes(from: &address, count: MemoryLayout.size)
> _class_getInstancePositiveExtentSize(bufferClass) == 
> MemoryLayout<_HeapObject.self>.size
> bytesPerIndex: MemoryLayout.size
> 
> The full type specification lends the calls an importance and verbosity they 
> don't deserve compared to their simpler counterparts. The eye is drawn every 
> time to the "MemoryLayout" pattern:
> 
> * Prominence of the type constructor
> * Simplicity of the function call
> * Number of code characters used
> * Swift's adherence to a mantra of concision and clarity.
> 
> It fails all these. To put it in usability terms: it's a big stinking mess 
> compared to the readability and eye tracking of the simpler function. (I've 
> cc'ed in Chris Lattner, who has people who can test this kind of thing on 
> call.)

I don't disagree with the points you make.  But one can argue that this is a 
good thing.  It calls attention to code that requires extra attention and care. 
 In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  Verbosity 
was a deliberate choice in that case.

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 1:55 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I think we should actually go further.
> 
> If this proposal is accepted, disallow "as" as a way of specifying the type 
> to construct from a literal.

I’m not sure.  I agree it would be bad style to use `as` here.  But I’m not 
sure if it should be banned or not.

> 
> If this proposal isn't accepted, disallow using literal values as the 
> argument to one-unlabeled-argument constructors.

I don’t know about this.  It says that if you want users to initialize your 
type with an unlabeled argument that has a type which has a corresponding 
literal you *must* conform to the corresponding literal convertible protocol.  
Do we really want to require that?  Maybe, but maybe not.  We definitely 
*should not* allow such an initializer to be written if it cannot be called 
with a literal.

For example, if I have:

`init(_ a: [String])`

users could call the initializer with an array variable but not a array 
literal.  That would be very bad IMO.  Either this initializer is banned 
altogether, or we allow it to be called with a literal. 

FWIW, there are types in the standard library with overlapping initializers in 
this new model:

public init(_ value: UInt8)
public init(integerLiteral value: UInt8)

I’m not sure whether they actually need to do different things or whether they 
are just provided so you can initialize the type with a variable and also use 
literals in a context expecting that type.

I think it’s important to understand whether overlap like this is necessary or 
not.  If behavior should always be identical I am in favor of refactoring the 
literal convertible protocols as part of this change.

> 
> In either case we should disabuse users of the notion that A(literal) is an 
> initializer that behaves exactly the same as other initializers.
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng  > wrote:
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.
> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.

Agree.  This change basically means the label isn’t intended to be used by 
callers, but is only present to distinguish the initializer used by the 
protocol from any other unlabeled initializer accepting the same type.  But 
conceptually it is treated as the *most specific* unlabelled initializer 
possible, thus winning the overload resolution.

How important is it that we have the ability to distinguish between literals 
and non-literals with the same type?  If that isn’t important, maybe the 
literal convertible protocols could be reworked such that the label isn’t 
necessary.  That would eliminate the special-case elision of the label.

> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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://lis

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 1:30 PM, John McCall  wrote:
> 
>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson  wrote:
>>> On Jun 2, 2016, at 12:01 PM, John McCall  wrote:
>>> 
>>>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>>>>  wrote:
>>>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>>>>> 
>>>>> Well, as I understand it, it's not actually possible to write your own 
>>>>> type(of:), so we're going from a "magic" property to a "magic" function 
>>>>> at least for now.
>>>> 
>>>> No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
>>>> *cannot* write a property that is available for all properties - that 
>>>> would require the ability to write `extension Any`.  This is the 
>>>> distinction I am making.  Of course the implementation is compiler magic 
>>>> no matter how we express it syntactically.  But we can make it *appear* 
>>>> just like it might if the implementation *wasn’t* compiler magic.  That 
>>>> makes it fit into the language better IMO and was the biggest motivator 
>>>> for changing `dynamicType`.
>>>> 
>>>>> 
>>>>> I'm most alarmed that one implication of the MemoryLayout proposal is 
>>>>> loss of the `ofValue` family of functions. These functions don't fit with 
>>>>> the design: imagine, what is `MemoryLayout.size(ofValue: 
>>>>> Float(42))`? But the response seems to be that these functions don't seem 
>>>>> necessary at all and should be removed. "I don't see a use for it" is an 
>>>>> insufficient justification for a feature removal. Looking to other 
>>>>> languages, C# has sizeof as a static property but tellingly offers the 
>>>>> equivalent of sizeofValue (well, strideofValue) as a function in a 
>>>>> different module. Essentially every other C-family language that exposes 
>>>>> pointers to the user offers both of and ofValue equivalents. The question 
>>>>> is, how does a user with existing code using sizeofValue() migrate to 
>>>>> Swift 3? I do not see a viable answer with the MemoryLayout design.
>>>> 
>>>> Going with MemoryLayout *does not* mean we would have to give up the value 
>>>> functions if we don’t want to:
>>>> 
>>>> struct MemoryLayout {
>>>> init() {}
>>>> init(t: T) { /* throw away the value */ }
>>>> 
>>>> // we could omit the static properties and require 
>>>> // writing MemoryLayout() if we don’t like the duplication
>>>> static let size: Int
>>>> static let spacing: Int
>>>> static let alignment: Int
>>>> 
>>>> let size: Int
>>>> let spacing: Int
>>>> let alignment: Int
>>>> }
>>>> 
>>>> let size = MemoryLayout.size
>>>> let sizeOfValue = MemoryLayout(42).size
>>> 
>>> There's no good reason for this type to be generic.  It should be 
>>> non-generic and require the use of the instance properties.
>> 
>> Dave's initial suggestion was generic and Joe suggested static properties.  
>> I suppose it doesn't have to be generic if we pass the type directly to the 
>> initializer, but that design would eliminate the possibility of inferring 
>> the type from a value (which some people seem to want to retain).
>> 
>> I didn't mean to advocate either way about adding a value initializer and 
>> instance properties.  I was only trying to show that it is *possible* to do 
>> that if we want to preserve the ofValue capabilities.
>> 
>>> 
>>> It's actively harmful for this type to appear to be computed from a value.  
>>> The layout is not in any way tied to the dynamic type of the value — for 
>>> example, it is not the instance layout of the most-derived class or the 
>>> value layout of the dynamic type of an existential.  
>> 
>> Understood, but that same problem exists for the current ofValue operations 
>> doesn't it? We can discuss removing them (I am not opposed to that), but 
>> that is independent of whether we should use a MemoryLayout struct as 
>> opposed to free functions.
> 
> I'm not trying to dictate the entire design.  I'm saying that, if you're 
> going to have a layout structure, I 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution
+1 to this.  It seems like a very straightforward thing to do.

Sent from my iPad

> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 12:01 PM, John McCall  wrote:
> 
>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>>> 
>>> Well, as I understand it, it's not actually possible to write your own 
>>> type(of:), so we're going from a "magic" property to a "magic" function at 
>>> least for now.
>> 
>> No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
>> *cannot* write a property that is available for all properties - that would 
>> require the ability to write `extension Any`.  This is the distinction I am 
>> making.  Of course the implementation is compiler magic no matter how we 
>> express it syntactically.  But we can make it *appear* just like it might if 
>> the implementation *wasn’t* compiler magic.  That makes it fit into the 
>> language better IMO and was the biggest motivator for changing `dynamicType`.
>> 
>>> 
>>> I'm most alarmed that one implication of the MemoryLayout proposal is loss 
>>> of the `ofValue` family of functions. These functions don't fit with the 
>>> design: imagine, what is `MemoryLayout.size(ofValue: Float(42))`? 
>>> But the response seems to be that these functions don't seem necessary at 
>>> all and should be removed. "I don't see a use for it" is an insufficient 
>>> justification for a feature removal. Looking to other languages, C# has 
>>> sizeof as a static property but tellingly offers the equivalent of 
>>> sizeofValue (well, strideofValue) as a function in a different module. 
>>> Essentially every other C-family language that exposes pointers to the user 
>>> offers both of and ofValue equivalents. The question is, how does a user 
>>> with existing code using sizeofValue() migrate to Swift 3? I do not see a 
>>> viable answer with the MemoryLayout design.
>> 
>> Going with MemoryLayout *does not* mean we would have to give up the value 
>> functions if we don’t want to:
>> 
>> struct MemoryLayout {
>> init() {}
>> init(t: T) { /* throw away the value */ }
>> 
>> // we could omit the static properties and require 
>> // writing MemoryLayout() if we don’t like the duplication
>> static let size: Int
>> static let spacing: Int
>> static let alignment: Int
>> 
>> let size: Int
>> let spacing: Int
>> let alignment: Int
>> }
>> 
>> let size = MemoryLayout.size
>> let sizeOfValue = MemoryLayout(42).size
> 
> There's no good reason for this type to be generic.  It should be non-generic 
> and require the use of the instance properties.

Dave's initial suggestion was generic and Joe suggested static properties.  I 
suppose it doesn't have to be generic if we pass the type directly to the 
initializer, but that design would eliminate the possibility of inferring the 
type from a value (which some people seem to want to retain).

I didn't mean to advocate either way about adding a value initializer and 
instance properties.  I was only trying to show that it is *possible* to do 
that if we want to preserve the ofValue capabilities.

> 
> It's actively harmful for this type to appear to be computed from a value.  
> The layout is not in any way tied to the dynamic type of the value — for 
> example, it is not the instance layout of the most-derived class or the value 
> layout of the dynamic type of an existential.  

Understood, but that same problem exists for the current ofValue operations 
doesn't it? We can discuss removing them (I am not opposed to that), but that 
is independent of whether we should use a MemoryLayout struct as opposed to 
free functions.

> Furthermore, saying that it is computed from a value means that attempting to 
> compute it from a type will succeed using the layout of the metatype, which 
> seems like a catastrophic failure of API design.

I was a bit hasty with the argument label and my example calling code wouldn't 
have actually worked.  I should have included a clear external label.

This is what we would want to actually do (Erica, can you update again?):

init(ofValue: @autoclosure () -> T) { }

Used like this:

let sizeOfValue = MemoryLayout(ofValue: 42).size

Adding the label will eliminate the potential for confusion about type vs 
metatype.  Wanting to know the size of the metatype is probably extremely rare, 
but there is not reason to prohibit it.

> 
> John.
> 
>> 
>>> 
>>>> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson  
>>>> wrote

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 11:04 AM, Erica Sadun  wrote:
> 
> 
>> On Jun 2, 2016, at 9:48 AM, Matthew Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> struct MemoryLayout {
>> init() {}
>> init(t: T) { /* throw away the value */ }
>> 
>> // we could omit the static properties and require 
>> // writing MemoryLayout() if we don’t like the duplication
>> static let size: Int
>> static let spacing: Int
>> static let alignment: Int
>> 
>> let size: Int
>> let spacing: Int
>> let alignment: Int
>> }
>> 
>> let size = MemoryLayout.size
>> let sizeOfValue = MemoryLayout(42).size
> 
> And amended Alternatives with this. :)

Thanks!  Can you change the init signature with Pyry’s improvement: `init(_: 
@autoclosure () -> T) {}`?

> 
> - E
> 

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 11:04 AM, Pyry Jahkola  wrote:
> 
>> Matthew Johnson wrote:
>> 
>> Going with MemoryLayout *does not* mean we would have to give up the value 
>> functions if we don’t want to:
>> 
>> struct MemoryLayout {
>> init(t: T) { /* throw away the value */ }
>> // …
>> }
>> 
>> let sizeOfValue = MemoryLayout(42).size
> 
> You could also use @autoclosure here to avoid evaluating whatever expression 
> there is:
> 
> struct MemoryLayout {
> init(_: @autoclosure () -> T) {}
> // ...
> }

Brilliant!  Why didn’t I think of that? :-)

> 
> — Pyry
> 

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
> 
> Well, as I understand it, it's not actually possible to write your own 
> type(of:), so we're going from a "magic" property to a "magic" function at 
> least for now.

No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
*cannot* write a property that is available for all properties - that would 
require the ability to write `extension Any`.  This is the distinction I am 
making.  Of course the implementation is compiler magic no matter how we 
express it syntactically.  But we can make it *appear* just like it might if 
the implementation *wasn’t* compiler magic.  That makes it fit into the 
language better IMO and was the biggest motivator for changing `dynamicType`.

> 
> I'm most alarmed that one implication of the MemoryLayout proposal is loss of 
> the `ofValue` family of functions. These functions don't fit with the design: 
> imagine, what is `MemoryLayout.size(ofValue: Float(42))`? But the 
> response seems to be that these functions don't seem necessary at all and 
> should be removed. "I don't see a use for it" is an insufficient 
> justification for a feature removal. Looking to other languages, C# has 
> sizeof as a static property but tellingly offers the equivalent of 
> sizeofValue (well, strideofValue) as a function in a different module. 
> Essentially every other C-family language that exposes pointers to the user 
> offers both of and ofValue equivalents. The question is, how does a user with 
> existing code using sizeofValue() migrate to Swift 3? I do not see a viable 
> answer with the MemoryLayout design.

Going with MemoryLayout *does not* mean we would have to give up the value 
functions if we don’t want to:

struct MemoryLayout {
init() {}
init(t: T) { /* throw away the value */ }

// we could omit the static properties and require 
// writing MemoryLayout() if we don’t like the duplication
static let size: Int
static let spacing: Int
static let alignment: Int

let size: Int
let spacing: Int
let alignment: Int
}

let size = MemoryLayout.size
let sizeOfValue = MemoryLayout(42).size

> 
> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson  > wrote:
> 
> 
> Sent from my iPad
> 
> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith > > wrote:
>> I really like this idea. This IMO is lower level functionality than 
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>> grouped under its own domain, the MemoryLayout type.
>> 
>> Plus MemoryLayout can be extended with new convenience methods.
>> 
>> I’m fine with those old methods being removed, but I never use them so! Is 
>> it the same as calling type(of:) then using that with MemoryLayout? I 
>> imagine they could be fixit’d easily, and that they compile down to the same 
>> underlying code.
>> 
>> I'm actually souring to the idea. It goes in the diametrically opposite 
>> direction from dynamicType. There, something was changed from being 
>> property-like to being function-like. Here, Dave's proposal would take 
>> something that's a function and turn it into a property. Hmm.
> 
> That's not a fair comparison though.  With dynamicType we removed a "magic" 
> property visible on all types, which isn't something you can write and turned 
> it into a function (which is obviously something you can write).  
> 
> Dave's MemoryLayout creates a new type to bundle together related items which 
> makes their semantic relationship more clear.  It also receives the type via 
> a generic argument rather than a function argument and makes the properties 
> static.  That is more representative of what is actually happening and could 
> help to prevent confusion.  
> 
> If we really need an 'ofValue' option that infers T from a value the 
> properties on MemoryLayout could also be made available as instance 
> properties and it could have an initializer that accepts an instance to T and 
> throws the value away.  However, I'm not at all convinced this is necessary.
> 
>>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 2. Dave A. and others expressed the opinion that these should probably not 
>>> be global functions; his preference was for:
>>> 
>>> ```
>>> MemoryLayout.size // currently sizeof()
>>> MemoryLayout.spacing // currently strideof()
>>> MemoryLayout.alignment // currently alignof()
>>> ```
>>> 
>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
>>> are better off removed altogether. I don't know if people are going to be 
>>> happy about this idea.
>> 
>> 
> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinf

Re: [swift-evolution] [Returned for Revision] SE-0095: Replace protocol syntax with Any

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:14 AM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> 
> 
> Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution 
> mailto:swift-evolution@swift.org>>:
> 
>> Excellent.
>> 
>> I put together a PR with a revised proposal containing the core team's 
>> recommended approach. If anyone is curious they can see it here: 
>> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
>>  
>> 
>> 
>> Since this is the de-facto second round discussion thread, I'll start with 
>> my personal opinion (which is *not* reflected in the PR): the '&' separators 
>> in lieu of commas are a good idea, but I would still prefer the types to be 
>> wrapped in "Any<>", at least when being used as existentials.
> 
> I'm very happy with using `&` as I find this very readable.
> I would prefer not having to wrap them into `Any<>`. While I can image 
> `Any<>`, or rather `any<>`, for existentials with `where` clauses, I would 
> absolutely hate having to wrap all existentials into that which would 
> introduce a lot of noise. 
> 
>> 
>> My reasons:
>> 
>> - Jordan Rose brought up a good point in one of the discussion threads 
>> today: a resilience goal is to allow a library to add an associated type to 
>> a protocol that had none and not have it break user code. If this is true 
>> whatever syntax is used for existentials in Swift 3 should be a valid subset 
>> of the generalized existential syntax used to describe protocol compositions 
>> with no associated types.
> 
> If `P` is an existential there is no problem either, isn't it? No need to 
> require `Any`. 
> 
> 
> 
>> 
>> - I would rather have "Any<>" be used consistently across all existential 
>> types eventually than have it only be used for (e.g.) existential types with 
>> `where` constraints, or allowing two different representations of the same 
>> existential type (one with Any, and one without).
> 
> Far too much noise!
> 
> 
>> 
>> - I think any generalized existential syntax without delimiting markers 
>> (like angle braces) is harder to read than syntax with such markers, so I 
>> would prefer a design with those markers.
> 
> I think markers are only needed if a `where` clause is present and probably 
> not even then.

The only reason to require them generally is if they are required for 
disambiguation in specific syntactic positions and it would be too confusing to 
remember where parentheses are required.  If that isn’t the case they should 
not be required.  It would be interesting to hear from someone closer to the 
grammar about whether an enclosing syntactic context would ever be required for 
disambiguation or not.

If we don’t require them, parentheses can still be used for clarity when 
desired.

> 
> -Thorsten 
> 
> 
>> 
>> Best,
>> Austin
>> 
>>> On Jun 1, 2016, at 10:17 PM, Chris Lattner >> > wrote:
>>> 
>>> 
 On Jun 1, 2016, at 9:53 PM, Austin Zheng >>> > wrote:
 
 This was indeed a very thorough review by the core team. I'll prepare a v2 
 proposal with this feedback taken into account so we can continue moving 
 things along.
 
 One quick question - is making whatever syntax is chosen for Swift 3 
 "forward-compatible" with a future generalized existential feature a 
 concern?
>>> 
>>> Yes it is a concern, but we assume that the “X & Y” syntax will always be 
>>> accepted going forward, as sugar for the more general feature that is yet 
>>> to be designed.
>>> 
>>> -Chris
>> 
>> ___
>> 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:01 AM, Charlie Monroe  wrote:
> 
>> Isn’t this a short-term concern?  I thought that requirement was going away.
> 
> AFAIK there are still concerns about ambiguity - [Int] - is it an array with 
> one element (Int.self), or is it [Int].self?

IIRC Joe Groff was going to work on sorting out the remaining issues but the 
plan is to move ahead eventually.

> 
>> 
>>> For this reason, this proposal prefers using no-label calls for types 
>>> (otherwise they would have been ofType) and labeled calls for values:
>>> 
>>> print(sizeof(Int)) // works
>>> print(sizeof(Int.self)) // works
>>> 
>>> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
>>> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
>>> 
>>> 
>>> // Works
>>> print(withoutLabel(Int))
>>> 
>>> // Works
>>> print(withLabel(label: Int.self))
>>> 
>>> // Does not work
>>> // error: cannot create a single-element tuple with an element label
>>> // print(withLabel(label: Int)) 
>>> 
>>> 
>>> So with this in mind:
>>> 
>>> /// Returns the contiguous memory footprint of `T`.
>>> ///
>>> /// Does not include any dynamically-allocated or "remote" storage.
>>> /// In particular, `size(X.self)`, when `X` is a class type, is the
>>> /// same regardless of how many stored properties `X` has.
>>> public func size(_: T.Type) -> Int
>>> 
>>> /// Returns the contiguous memory footprint of  `T`.
>>> ///
>>> /// Does not include any dynamically-allocated or "remote" storage.
>>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>>> /// same regardless of how many stored properties `a` has.
>>> public func size(of: T) -> Int
>>> 
>>> /// Returns the least possible interval between distinct instances of
>>> /// `T` in memory.  The result is always positive.
>>> public func spacing(_: T.Type) -> Int
>>> 
>>> /// Returns the least possible interval between distinct instances of
>>> /// `T` in memory.  The result is always positive.
>>> public func spacing(of: T) -> Int
>>> 
>>> /// Returns the minimum memory alignment of `T`.
>>> public func alignment(_: T.Type) -> Int
>>> 
>>> /// Returns the minimum memory alignment of `T`.
>>> public func alignment(of: T) -> Int
>>> -- 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:03 AM, Xiaodi Wu  wrote:
> 
> That proposal was returned for revision; as far as user ergonomics in Swift 
> 3, .self is going to be a consideration. Best to find a solution that reads 
> nicely regardless of the situation with .self removal.

From the core team decision:

"The core team would definitely like to circle back to this proposal after 
Swift 3 is out the door."

I think we should consider the best long-term design.  If that happens to be 
dropping labels great, but if not, maybe we don’t want to do that just because 
it will look better in Swift 3 at the cost of a better design when “.self” is 
not required.

Dave’s MemoryLayout approach avoids the question of labels entirely.  This is 
another subtle nudge in that direction IMO.

> 
> On Thu, Jun 2, 2016 at 9:57 AM Matthew Johnson  > wrote:
>> On Jun 2, 2016, at 9:43 AM, Erica Sadun > > wrote:
>> 
>> Supporting Dave A, type-based calls are much more likely to be used than 
>> instance calls, unlike with dynamicType/type(of:)
>> 
>> Term stdlib search   gist search Google site:github +swift
>> sizeof   157 169 4880
>> sizeofValue  4   34  584
>> alignof  44  11  334
>> alignofValue 5   5   154
>> strideof 347 19  347
>> strideofValue4   5   163
>> Type-based calls like sizeof() are poor candidates for parameter labels. 
>> While it's acceptable to write sizeof(Int), but one must write size(of: 
>> Int.self) (with the trailing self) when the function has a label.
> 
> Isn’t this a short-term concern?  I thought that requirement was going away.
> 
>> For this reason, this proposal prefers using no-label calls for types 
>> (otherwise they would have been ofType) and labeled calls for values:
>> 
>> print(sizeof(Int)) // works
>> print(sizeof(Int.self)) // works
>> 
>> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
>> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
>> 
>> 
>> // Works
>> print(withoutLabel(Int))
>> 
>> // Works
>> print(withLabel(label: Int.self))
>> 
>> // Does not work
>> // error: cannot create a single-element tuple with an element label
>> // print(withLabel(label: Int)) 
>> 
>> 
>> So with this in mind:
>> 
>> /// Returns the contiguous memory footprint of `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(X.self)`, when `X` is a class type, is the
>> /// same regardless of how many stored properties `X` has.
>> public func size(_: T.Type) -> Int
>> 
>> /// Returns the contiguous memory footprint of  `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>> /// same regardless of how many stored properties `a` has.
>> public func size(of: T) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(_: T.Type) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(of: T) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(_: T.Type) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(of: T) -> Int
>> -- E

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


Re: [swift-evolution] [swift-evolution-announce] [Rejected] SE-0097: Normalizing naming for "negative" attributes

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 9:52 AM, Sean Heber via swift-evolution 
>  wrote:
> 
> In terms of naming, I almost feel like “None” would be a better name for it 
> as then it reads somewhat as the opposite of “Any” and that has a nice 
> symmetry to me.

+ 1.  Although the inverse of “None” is really “All” (as in “all or none”).  
I’m not necessarily suggesting we use “All”, just pointing out the linguistic 
relationship.  

That said, I do believe we should *consider* alternatives names for “Any” as 
part of the discussion of the name for a bottom type.  It would be nice 
symmetry if we found names for the top and bottom types that are inverses of 
each other.

> 
> l8r
> Sean
> 
> 
>> On Jun 2, 2016, at 4:04 AM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
>>> 1) For noreturn, the core team prefers to explore a solution where a 
>>> function can be declared as returning an non-constructable “bottom” type 
>>> (e.g. an enum with zero cases).  This would lead to something like:
>>> 
>>> func abort() -> NoReturn { … }
>>> 
>>> This will require some new support in the compiler, but should flow better 
>>> through the type system than @noreturn in function composition and other 
>>> applications.  Joe Groff offered to write a proposal for this.
>> 
>> Are you thinking in terms of a *real* bottom type—that is, a type which is 
>> the subtype of all types—or a fake bottom type which is simply an empty enum?
>> 
>> If you're thinking about a real bottom type, I wouldn't want to call it 
>> `NoReturn`, because the bottom type may end up playing a larger role in the 
>> language. Given our use of `Any`, the natural names for a bottom type are 
>> probably `All` (as the subtype of all types) or `None` (as a type with no 
>> instances). I do worry that those names are a little too short and 
>> attractive, though. `None` might be mistaken for `Void`; `All` might be 
>> mistaken for `Any`, and wouldn't make much sense when read as the return 
>> value of a function.
>> 
>> My best suggestion is `Never`. A function with a `Never` return type would 
>> read as "never returns":
>> 
>>  func abort() -> Never { … }
>> 
>> If it appeared in, say, a generic type, it would mean "never occurs":
>> 
>>  let result: Result
>> 
>> Flowing from that, we can end up with functions taking a `Never` parameter, 
>> which are never called:
>> 
>>  result.flatMapError { (_: Never) in fatalError("can't happen") }
>> 
>> Or `Never?` values, which are never `some`:
>> 
>>  let _: Never? = Result.error
>> 
>> (By the way, the return type of the force unwrap operator on a `Never?` is 
>> `Never`, which is just right: if you force unwrap a `Never?`, it will always 
>> trap, never return.)
>> 
>> The main issue I see with `Never` is that it's an adverb, not a noun. But 
>> the nouns all seem to have problems. And besides, the bottom type isn't so 
>> much a thing as a lack of a thing, isn't it? That's bound to have a slightly 
>> funky name.
>> 
>> -- 
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 9:43 AM, Erica Sadun  wrote:
> 
> Supporting Dave A, type-based calls are much more likely to be used than 
> instance calls, unlike with dynamicType/type(of:)
> 
> Term  stdlib search   gist search Google site:github +swift
> sizeof157 169 4880
> sizeofValue   4   34  584
> alignof   44  11  334
> alignofValue  5   5   154
> strideof  347 19  347
> strideofValue 4   5   163
> Type-based calls like sizeof() are poor candidates for parameter labels. 
> While it's acceptable to write sizeof(Int), but one must write size(of: 
> Int.self) (with the trailing self) when the function has a label.

Isn’t this a short-term concern?  I thought that requirement was going away.

> For this reason, this proposal prefers using no-label calls for types 
> (otherwise they would have been ofType) and labeled calls for values:
> 
> print(sizeof(Int)) // works
> print(sizeof(Int.self)) // works
> 
> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
> 
> 
> // Works
> print(withoutLabel(Int))
> 
> // Works
> print(withLabel(label: Int.self))
> 
> // Does not work
> // error: cannot create a single-element tuple with an element label
> // print(withLabel(label: Int)) 
> 
> 
> So with this in mind:
> 
> /// Returns the contiguous memory footprint of `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(X.self)`, when `X` is a class type, is the
> /// same regardless of how many stored properties `X` has.
> public func size(_: T.Type) -> Int
> 
> /// Returns the contiguous memory footprint of  `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(of: a)`, when `a` is a class instance, is the
> /// same regardless of how many stored properties `a` has.
> public func size(of: T) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(_: T.Type) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(of: T) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func alignment(_: T.Type) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func alignment(of: T) -> Int
> -- E

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Jun 2, 2016, at 6:26 AM, Brent Royal-Gordon via swift-evolution 
 wrote:

>> /// Returns the contiguous memory footprint of `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: X.self)`, when `X` is a class type, is the
>> /// same regardless of how many stored properties `X` has.
>> public func size(of: T.Type) -> Int
>> 
>> /// Returns the contiguous memory footprint of  `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>> /// same regardless of how many stored properties `a` has.
>> public func size(ofValue: T) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(of: T.Type) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(ofValue: T) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func align(of: T.Type) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func align(ofValue: T) -> Int
> 
> If `type(of:)` takes an instance, then I think `size(of:)`, `spacing(of:)` 
> and `align(of:)` need to do the same, with `size(ofType:)`, 
> `spacing(ofType:)`, and `align(ofType:)` handling the type side of things.

+1 if we stick with the function direction.  But I'm not convinced this is the 
best direction.

> 
> -- 
> 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] [Returned for Revision] SE-0095: Replace protocol syntax with Any

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 12:42 AM, Austin Zheng via swift-evolution 
>  wrote:
> 
> Excellent.
> 
> I put together a PR with a revised proposal containing the core team's 
> recommended approach. If anyone is curious they can see it here: 
> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
> 
> Since this is the de-facto second round discussion thread, I'll start with my 
> personal opinion (which is *not* reflected in the PR): the '&' separators in 
> lieu of commas are a good idea, but I would still prefer the types to be 
> wrapped in "Any<>", at least when being used as existentials.

Thanks for writing up the revision Austin, especially since it does not reflect 
your own opinion.

My opinion is that we should view these as type expressions.  We don't require 
any kind of delimiters around value expressions, allowing optional parentheses 
for clarification and as a matter of style.  I don't see any reason to treat 
type expressions any different than that syntactically.  

> 
> My reasons:
> 
> - Jordan Rose brought up a good point in one of the discussion threads today: 
> a resilience goal is to allow a library to add an associated type to a 
> protocol that had none and not have it break user code. If this is true 
> whatever syntax is used for existentials in Swift 3 should be a valid subset 
> of the generalized existential syntax used to describe protocol compositions 
> with no associated types.
> 
> - I would rather have "Any<>" be used consistently across all existential 
> types eventually than have it only be used for (e.g.) existential types with 
> `where` constraints, or allowing two different representations of the same 
> existential type (one with Any, and one without).
> 
> - I think any generalized existential syntax without delimiting markers (like 
> angle braces) is harder to read than syntax with such markers, so I would 
> prefer a design with those markers.
> 
> Best,
> Austin
> 
>>> On Jun 1, 2016, at 10:17 PM, Chris Lattner  wrote:
>>> 
>>> 
>>> On Jun 1, 2016, at 9:53 PM, Austin Zheng  wrote:
>>> 
>>> This was indeed a very thorough review by the core team. I'll prepare a v2 
>>> proposal with this feedback taken into account so we can continue moving 
>>> things along.
>>> 
>>> One quick question - is making whatever syntax is chosen for Swift 3 
>>> "forward-compatible" with a future generalized existential feature a 
>>> concern?
>> 
>> Yes it is a concern, but we assume that the “X & Y” syntax will always be 
>> accepted going forward, as sugar for the more general feature that is yet to 
>> be designed.
>> 
>> -Chris
> 
> ___
> 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

>> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith  wrote:
>> I really like this idea. This IMO is lower level functionality than 
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>> grouped under its own domain, the MemoryLayout type.
>> 
>> Plus MemoryLayout can be extended with new convenience methods.
>> 
>> I’m fine with those old methods being removed, but I never use them so! Is 
>> it the same as calling type(of:) then using that with MemoryLayout? I 
>> imagine they could be fixit’d easily, and that they compile down to the same 
>> underlying code.
> 
> I'm actually souring to the idea. It goes in the diametrically opposite 
> direction from dynamicType. There, something was changed from being 
> property-like to being function-like. Here, Dave's proposal would take 
> something that's a function and turn it into a property. Hmm.

That's not a fair comparison though.  With dynamicType we removed a "magic" 
property visible on all types, which isn't something you can write and turned 
it into a function (which is obviously something you can write).  

Dave's MemoryLayout creates a new type to bundle together related items which 
makes their semantic relationship more clear.  It also receives the type via a 
generic argument rather than a function argument and makes the properties 
static.  That is more representative of what is actually happening and could 
help to prevent confusion.  

If we really need an 'ofValue' option that infers T from a value the properties 
on MemoryLayout could also be made available as instance properties and it 
could have an initializer that accepts an instance to T and throws the value 
away.  However, I'm not at all convinced this is necessary.

>>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> 2. Dave A. and others expressed the opinion that these should probably not 
>>> be global functions; his preference was for:
>>> 
>>> ```
>>> MemoryLayout.size // currently sizeof()
>>> MemoryLayout.spacing // currently strideof()
>>> MemoryLayout.alignment // currently alignof()
>>> ```
>>> 
>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
>>> are better off removed altogether. I don't know if people are going to be 
>>> happy about this idea.
> 
> ___
> 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] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 12:05 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Wed, Jun 1, 2016 at 11:55 PM, Xiaodi Wu  wrote:
>>> On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution 
>>>  wrote:
>> 
>>> Upon accepting SE-0098, the core team renamed the proposed stdlib function 
>>> from dynamicType() to type(of:).  They write, "The core team recognizes 
>>> that this means that we should probably resyntax the existing 
>>> sizeof/strideof functions, but that should be a follow-on discussion."
>>> 
>>> Follow on discussion started. Have at it.
>> 
>> See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830
> 
> To summarize the previous discussion:
> 
> 1. Per Joe Groff, although sizeof() and friends are treated as terms-of-art, 
> these names were lifted straight from C and do not correspond to anything 
> named "sizeof" in LLVM.
> 
> 2. There are issues with using a name such as stride(of:), because 
> stride(...) already means something else in the stdlib; moreover, size(of:) 
> isn't the best name for something that doesn't do what its C namesake does; 
> therefore, larger changes to the naming were suggested.
> 
> 2. Dave A. and others expressed the opinion that these should probably not be 
> global functions; his preference was for:
> 
> ```
> MemoryLayout.size // currently sizeof()
> MemoryLayout.spacing // currently strideof()
> MemoryLayout.alignment // currently alignof()
> ```

Thanks for the summary.  I missed the original thread.  

I think I like this approach despite its verbosity.  Will give it a little bit 
more thought...

> 
> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
> are better off removed altogether. I don't know if people are going to be 
> happy about this idea.
> 
> * * *
> 
> If we take inspiration from type(of:), then it's actually sizeofValue(), 
> etc., that should be renamed size(of:), etc. Also, a fun tidbit is that 
> what's currently called sizeof(), etc.--the ones that take types rather than 
> values--are actually not very good candidates for having parameter labels, 
> because it's OK to write `sizeof(Int)`, but one must currently write 
> `size(of: Int.self)` when the function has a label.
> 
> 
> 
> ___
> 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] Ad hoc enums / options

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 5:02 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> > in other words, we could consider allowing this:
> >func foo(bar: (.fit | .fill)) {
> >  baz(bar: bar)
> >}
> >func baz(bar: (.fit | .fill | .florp) { ... }
> >
> > In other words, an ad hoc enum T can be used wherever an ad hoc enum U is
> > expected if T ⊆ U.
> 
> Can't agree with this. Just because the same analogue with tuples : 
> differently defined tuples are different types. Tuples with different order 
> of types in declaration - are different types. So I expect here instance of 
> (.fit | .fill) `bar` is not of the same type as (.fit | .fill | .florp)

They are not the same type but there is a structural subtype relationship 
between them.  All values of type (.fit | .fill) are also values of type (.fit 
| .fill | .florp).

> 
> But +1 to be able to 'convert' instance of (.fit | .fill) to instance of 
> (.fit | .fill | .florp). For example(if we'll have init(caseName) and 
> .caseName for enums):
> 
> func foo(bar: (.fit | .fill)) {
>let bazbar = (.fit | .fill | .florp).init(caseName: bar.caseName)
>baz(bar: bazbar)
> }
> func baz(bar: (.fit | .fill | .florp) { ... }
> 
> 
> 
>> On 02.06.2016 0:38, Tony Allevato wrote:
>> I find myself agreeing with the idea that ad hoc enums are to enums as
>> structs are to tuples. Based on that analogy, why should an ad hoc enum
>> *need* a name (autogenerated or otherwise) any more than a tuple needs a
>> name? Would those who dislike ad hoc enums argue that this also shouldn't
>> be allowed:
>> 
>>func foo(bar: (x: Int, y: Int)) {}
>>let t: (x: Int, y: Int) = (x: 5, y: 5)
>> 
>> If someone writes `(.fit | .fill)` (or whatever the hypothetical syntax
>> might be), that should just *be* the type the same way that `(x: Int, y:
>> Int)` is a type without a name, and that type can be used in argument
>> lists, variables, or whatever. There shouldn't be any worry about
>> declarations across multiple functions colliding or being incompatible any
>> more than we would worry about two functions declaring arguments of type
>> `(x: Int, y: Int)` would collide or be incompatible.
>> 
>> One side of ad hoc enums that I'd like to see explored is that, by being
>> unnamed, they're basically anonymous finite sets and we could apply
>> well-defined subset relationships to them: in other words, we could
>> consider allowing this:
>> 
>>func foo(bar: (.fit | .fill)) {
>>  baz(bar: bar)
>>}
>>func baz(bar: (.fit | .fill | .florp) { ... }
>> 
>> In other words, an ad hoc enum T can be used wherever an ad hoc enum U is
>> expected if T ⊆ U.
>> 
>> 
>> On Wed, Jun 1, 2016 at 1:43 PM L. Mihalkovic via swift-evolution
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>>> On Jun 1, 2016, at 6:51 PM, Vladimir.S >> wrote:
>>>
>>> Yes, I also can support the idea of autogenerated type name (like
>>Enum_fit_OR_fill) as long as it allows to do all the things we are
>>discussing here: declare (.fit|.fill) in function, use .fit on calling
>>side, use (.fit|.fill) to declare temporary variable of type compatible
>>with such function parameter etc.
>>>
>> 
>>It all works because the compiler is just being a thoughless scribe
>>that just writes the standard enum we don't bother to write ourselves.
>>Because the heuristic is simple and straightforward then it is
>>predictible. The enum can be used with its long name be ause it is a
>>real enum. And writing the short form of it also works because the
>>compiler knowns uniquely what the long name is everytime it runs into
>>the short name.
>> 
>> 
>>> But how do you suggest to define a type of such function in
>>`typealias` for example? i.e. for func my(option: (.fit|.fill) {..}
>>>
>>> typealias MyFunc = ((.fit|.fill)) -> ()
>>> or as
>>>
>>> typealias MyFunc = (Enum_fit_OR_fill) -> ()
>>>
>> 
>>Ideally there is no difference whatsoever, there is a single enum, it
>>is produced at the module level, and it has the long form name.
>> 
>>There can be rules that would prevent us from doing that with
>>externally visible APIs, if the core team fuges that we should take the
>>time to write our enums manually and cleanly to make them visible to
>>the world, but it is not a necessary rule.
>> 
>> 
>>>
>>> But I still can't support the idea of limiting the usage of such
>>enums - i.e. "To deal with milti site definition, the compiler would
>>simply flag a error/warning, or be silent in the presence of a new
>>annotation:". I really think we need then introduce the same rule for
>>tuples - so no one can use the same tuple declaration in function -
>>they then should declare separate struct type or use @something for
>>such functions. Nobody wants such rule for tuples.
>>>
>> 
>>Multi site thing is not a limitation... Is 

Re: [swift-evolution] Ad hoc enums / options

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 4:38 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> I find myself agreeing with the idea that ad hoc enums are to enums as 
> structs are to tuples. Based on that analogy, why should an ad hoc enum 
> *need* a name (autogenerated or otherwise) any more than a tuple needs a 
> name? Would those who dislike ad hoc enums argue that this also shouldn't be 
> allowed:
> 
> func foo(bar: (x: Int, y: Int)) {}
> let t: (x: Int, y: Int) = (x: 5, y: 5)
> 
> If someone writes `(.fit | .fill)` (or whatever the hypothetical syntax might 
> be), that should just *be* the type the same way that `(x: Int, y: Int)` is a 
> type without a name, and that type can be used in argument lists, variables, 
> or whatever. There shouldn't be any worry about declarations across multiple 
> functions colliding or being incompatible any more than we would worry about 
> two functions declaring arguments of type `(x: Int, y: Int)` would collide or 
> be incompatible.
> 
> One side of ad hoc enums that I'd like to see explored is that, by being 
> unnamed, they're basically anonymous finite sets and we could apply 
> well-defined subset relationships to them: in other words, we could consider 
> allowing this:
> 
> func foo(bar: (.fit | .fill)) {
>   baz(bar: bar)
> }
> func baz(bar: (.fit | .fill | .florp) { ... }
> 
> In other words, an ad hoc enum T can be used wherever an ad hoc enum U is 
> expected if T ⊆ U.

When I said I am very opposed to this feature *unless* these ad-hoc enums have 
structural subtyping this is what I was talking about.  IMO this is absolutely 
essential if we introduce ad-hoc enums (as well as the ability to use the types 
for variables, not just parameters).

> 
> 
>> On Wed, Jun 1, 2016 at 1:43 PM L. Mihalkovic via swift-evolution 
>>  wrote:
>> 
>> 
>> > On Jun 1, 2016, at 6:51 PM, Vladimir.S  wrote:
>> >
>> > Yes, I also can support the idea of autogenerated type name (like 
>> > Enum_fit_OR_fill) as long as it allows to do all the things we are 
>> > discussing here: declare (.fit|.fill) in function, use .fit on calling 
>> > side, use (.fit|.fill) to declare temporary variable of type compatible 
>> > with such function parameter etc.
>> >
>> 
>> It all works because the compiler is just being a thoughless scribe that 
>> just writes the standard enum we don't bother to write ourselves. Because 
>> the heuristic is simple and straightforward then it is predictible. The enum 
>> can be used with its long name be ause it is a real enum. And writing the 
>> short form of it also works because the compiler knowns uniquely what the 
>> long name is everytime it runs into the short name.
>> 
>> 
>> > But how do you suggest to define a type of such function in `typealias` 
>> > for example? i.e. for func my(option: (.fit|.fill) {..}
>> >
>> > typealias MyFunc = ((.fit|.fill)) -> ()
>> > or as
>> >
>> > typealias MyFunc = (Enum_fit_OR_fill) -> ()
>> >
>> 
>> Ideally there is no difference whatsoever, there is a single enum, it is 
>> produced at the module level, and it has the long form name.
>> 
>> There can be rules that would prevent us from doing that with externally 
>> visible APIs, if the core team fuges that we should take the time to write 
>> our enums manually and cleanly to make them visible to the world, but it is 
>> not a necessary rule.
>> 
>> 
>> >
>> > But I still can't support the idea of limiting the usage of such enums - 
>> > i.e. "To deal with milti site definition, the compiler would simply flag a 
>> > error/warning, or be silent in the presence of a new annotation:". I 
>> > really think we need then introduce the same rule for tuples - so no one 
>> > can use the same tuple declaration in function - they then should declare 
>> > separate struct type or use @something for such functions. Nobody wants 
>> > such rule for tuples.
>> >
>> 
>> Multi site thing is not a limitation... Is is a proposed rule to say that we 
>> are able to be lazy twice without being penalized. Yhe compiler does not 
>> like when we define the same thing twice, and thse short form amount to 
>> doing what he does not let us do. But because this is about concise and 
>> lazy, then the compiler can let us get away with it if we use an annotation 
>> that lets it know that "it is not a mistake.. I really dont want to write 
>> that enum myself, even though I am using the same abbreviation twice". 
>> Otherwise, the compiler would let us know that the second time could be a 
>> mistake because there is already something with the same name...
>> 
>> But again this is a separate idea from the core notion of a syntax sugaring 
>> for writing real enums the lazy (clever) way
>> 
>> >> On 01.06.2016 19:04, L. Mihalkovic wrote:
>> >> The only problem with this proposal is to consider them ad-hoc enums... 
>> >> If we view them as having nothing ad-hoc about them and the thing to be a 
>> >> simple sugaring exercise, then I think all the oposition

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0095: Replace protocol syntax with Any

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 4:18 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> After thinking about this topic for the past few days, I'd like to throw in 
> my support for "Any<>" as well. It's one magic construct to learn, looks like 
> a type, has the visual delineation, and shares continuity with both 
> protocol<> and Any today.
> 
> I'd also like to express my support for the proposal to delineate generic and 
> existential syntax: all existentials must be written with Any<...>; generic 
> type constraints cannot use it. I hope this will make it clear to people 
> learning and using the language that, despite their superficial similarities, 
> they are actually two different concepts.

I'm neutral on the syntax.  But I strongly believe removing the ability to use 
protocol / Any in generic constraints *must* be accompanied by the introduction 
of a new (hopefully more robust) mechanism for factoring out common generic 
constraints.

> 
> Austin
> 
> 
>> On Wed, Jun 1, 2016 at 1:59 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> > [Proposal: 
>> > https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
>> >  ]
>> >
>> > I’m late again to this one, but the discussion’s certainly still going. 
>> > I’m pretty strongly against the bare ‘A & B’ syntax, for a few reasons:
>> >
>> > - Swift doesn’t use ‘&’ for anything except bitwise AND. In particular, it 
>> > didn’t get picked for set intersection.
>> 
>> I very, *very* much agree with this point. Thus far, Swift has been very 
>> conservative about overloading. It seems bizarre that we would violate that 
>> policy for these type combinators when much closer matches have been passed 
>> over.
>> 
>> I also think that using `&` absolutely *begs* to have an `|` as well, and as 
>> much as the Ceylon people clamor for them, I don't think union types make 
>> sense in Swift. Unlike Ceylon, Swift uses an algebraic data type for 
>> Optional, doesn't use type-erased generics, and supports overloading. As far 
>> as I can tell, *none* of the reasons cited in the Ceylon language design FAQ 
>>  apply to 
>> Swift.
>> 
>> (P.S. That language design FAQ is a *fantastic* document.)
>> 
>> > - In theory people are allowed to overload ‘&’ to operate on types. That 
>> > doesn’t make sense for all types, but you could probably come up with a 
>> > particular type hierarchy or use of generics where it does make sense.
>> >
>> > - I don’t like types with spaces in them when the spaces aren’t bracketed 
>> > in some way. This is entirely an aesthetic objection, of the form “I don’t 
>> > naturally read that as a type, or even as a single unit, when looking at 
>> > code.” This isn’t a great objection because someone could have said it 
>> > about `[Int]` or `Int?` as well. (It would be a more realistic objection 
>> > if some of our brackets weren’t “<" and “>”.)
>> 
>> To augment this: I think that if we're going to see a lot of little `where` 
>> clauses attached to types, you kind of have to have a bracketing syntax to 
>> put them in. And no, `(Collection where .Element == String)` doesn't count. 
>> `()` is about precedence, and this isn't a question of precedence; it's a 
>> question of making the type read as a single unit.
>> 
>> > And I still support the ‘Any’ syntax, despite the “order doesn’t matter” 
>> > problem:
>> >
>> > - It’s consistent with the existing unconstrained ‘Any’ and with the 
>> > current dedicated wrapper types. If we didn’t think it was a good name for 
>> > those, we wouldn’t use it there either.
>> 
>> One of my concerns with the `&` syntax is that it leaves no good way to 
>> define `Any`. I don't like having a magic `&` operator *and* a magic `Any` 
>> keyword, neither of which derives from anything more general.
>> 
>> > - It’s easily learnable. It’s rare enough that someone wouldn’t be exposed 
>> > to it right away, like Optional, Array, and Dictionary sugar, but when 
>> > they do see it it’ll be obvious that it’s a type, and probably obvious 
>> > that it’s special because of the “Any”.
>> >
>> > - It’s a type; types always start with uppercase letters. (This has been 
>> > said plenty by others.)
>> >
>> > None of these are particularly strong arguments, I know, and I don’t have 
>> > a good alternate suggestion. But I did want to go on record as being in 
>> > favor of ‘Any’ and against a binary operator, even though that seems to 
>> > put me in the minority.
>> 
>> I suspect that at least part of this is simply greater enthusiasm. I know I 
>> checked out of this thread for a few days while the `&` guys ran rampant.
>> 
>> (P.S. A thought I had just now: If `Any` is our top type, then `All` would 
>> be a good name for our bottom type. And `All` would be a good "All 
>> common supertypes of these types" operation. Both of these came up in the 
>> variadic generics thread, where we were talking about h

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 9:48 AM, David Waite via swift-evolution 
>  wrote:
> 
> One thing I did often in Java (and miss in Swift) is using their enums to 
> build state machines or implement command patterns for common commands.
> 
> Java enums are a sealed set of subclasses of the enum base type with 
> (hopefully) immutable, singleton instances. So you can do fun things like:
> - Define the base class constructor to be called to instantiate the 
> subclasses, and declare the cases with the constructor arguments
> - Declare a method on the base type and refine it on 1-2 particular cases
> - Declare the enum implements an interface, and implement that interface 
> separately for each case.
> - Define data accessors specific to the type (such as the planets example 
> above)
> 
> I like the SuitInfo approach below - with extensions, I think I can get close 
> to what I have done in the past with Java. Maybe one day there is syntax to 
> do this in the language directly

This is pretty similar to what we were discussing last week in this thread: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/018799.html

I'm planning to write up a proposal when I have time (hopefully in the next 
week or so).

> 
> -DW
> 
>> On May 31, 2016, at 11:44 AM, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>> I'm not sure about my opinion on this proposal, but I believe you should add 
>> this as alternatives of how we can have the similar features today without 
>> injecting stored properties into enums  :
>> 
>> enum Suit {
>>   case spades
>>   case hearts
>>   case diamonds
>>   case clubs
>> 
>>   struct SuitInfo {
>>   let simpleDescription: String
>>   let color: UIColor
>>   let symbol: String
>>   let bezierPath: UIBezierPath
>>   }
>> 
>>   var info : SuitInfo {
>>   switch self {
>>   case .spades:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "spades",
>>   color: .blackColor(),
>>   symbol: "♠",
>>   bezierPath: path)
>> 
>>   case .hearts:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "hearts",
>>   color: .redColor(),
>>   symbol: "♥",
>>   bezierPath: path)
>> 
>>   case .diamonds:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "diamonds",
>>   color: .redColor(),
>>   symbol: "♦",
>>   bezierPath: path)
>> 
>>   case .clubs:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "clubs",
>>   color: .blackColor(),
>>   symbol: "♣",
>>   bezierPath: path)
>> 
>>   }
>>   }
>> }
>> 
>> and this:
>> 
>> enum Suit  {
>>   case spades
>>   case hearts
>>   case diamonds
>>   case clubs
>> 
>>   struct SuitInfo  {
>>   let simpleDescription: String
>>   let color: UIColor
>>   let symbol: String
>>   let bezierPath: UIBezierPath
>>   }
>> 
>>   static let spadesInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "spades",
>>   color: .blackColor(),
>>   symbol: "♠",
>>   bezierPath: path)
>>   }()
>> 
>>   static let heartsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "hearts",
>>   color: .redColor(),
>>   symbol: "♥",
>>   bezierPath: path)
>>   }()
>> 
>>   static let diamondsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "diamonds",
>>   color: .redColor(),
>>   symbol: "♦",
>>   bezierPath: path)
>>   }()
>> 
>>   static let clubsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "clubs",
>>   color: .blackColor(),
>>   symbol: "♣",
>>   bezierPath: path)
>>   }()
>> 
>> 
>>   var info : SuitInfo {
>>   switch self {
>>   case .spades: return Suit.spadesInfo
>>   case .hearts: return Suit.heartsInfo
>>   case .diamonds: return Suit.diamondsInfo
>>   case .clubs: return Suit.clubsInfo
>>   }
>>   }
>> }
>> 
>> 
>>> On 31.05.2016 17:17, Jānis Kiršteins via swift-evolution wrote:
>>> I wrote a proposal draft:
>>> 
>>> # Enum case stored properties
>>> 
>>> * Proposal: TBD
>>> * Author: [Janis Kirsteins](https://github.com/kirsteins)
>>> * Status: TBD
>>> * Review manager: TBD
>>> 
>>> ## In

Re: [swift-evolution] Variadic generics discussion

2016-06-01 Thread Matthew Johnson via swift-evolution

> On Jun 1, 2016, at 8:29 AM, Joe Groff  wrote:
> 
>> 
>> On Jun 1, 2016, at 6:26 AM, Matthew Johnson  wrote:
>> 
>>> 
>>> On Jun 1, 2016, at 8:18 AM, Joe Groff via swift-evolution 
>>>  wrote:
>>> 
 
 On May 31, 2016, at 6:49 PM, Austin Zheng  wrote:
 
 I agree that this is a better design for Swift than the monstrosity I 
 started out with.
 
 The "biggest" technical challenge I see is being able to type a reduction 
 sort of operator on a heterogenous tuple based on on whatever protocols 
 and constraints are common to its constituent members. For example:
 
 // Every Tn in T... is Fooable and Barrable
 let x : (T...)
 reduce(x, reducer, startingValue)
 
 func reducer(startingValue: U, eachMemberOfT: X) -> U { ... }
 
 How do we bound ??? such that 'reducer' is useful while still being 
 statically type sound? Honestly, that's the most interesting question to 
 me. Generalized existentials might help with that.
>>> 
>>> If every T is Fooable and Barrable, couldn't `eachMemberOfT` be (inout U, 
>>> protocol) -> ()?
>>> 
 Other questions (inherent to any proposal) would be:
 
 - How do we resolve the impedance mismatch between tuples and function 
 argument lists? Is it even worth trying to resolve this mismatch, given 
 that argument lists are intentionally not intended to mirror tuples?
>>> 
>>> The impedance mismatch between function arguments and tuples is 
>>> superficial. You ought to be able to splat and bind tuples into function 
>>> arguments, e.g.:
>>> 
>>> let args = (1, 2)
>>> foo(bar:bas:)(args...)
>>> 
>>> func variadicFn(_ args: T...) { … }
>> 
>> Going this direction is relatively straightforward.  The impedance mismatch 
>> is trickier when you want to do more than that.  For example, it would be 
>> extremely useful to come up with some way to wrap a function that has 
>> parameters with default arguments without requiring callers of the wrapped 
>> function to supply arguments for the defaulted parameters.  Any ideas on how 
>> to solve that?
> 
> As Chris noted, that sounds like a great use case for a macro. Trying to do 
> that with the type system feels like it's on the wrong side of the complexity 
> threshold to me.

Makes sense.  Looking forward to having macros someday… :)

> 
> -Joe
> 
>>> 
 - As you said, how do variadic generics work in the 0- and 1-member cases?
>>> 
>>> What problem are you referring to?
>>> 
>>> -Joe
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Variadic generics discussion

2016-06-01 Thread Matthew Johnson via swift-evolution

> On Jun 1, 2016, at 8:18 AM, Joe Groff via swift-evolution 
>  wrote:
> 
>> 
>> On May 31, 2016, at 6:49 PM, Austin Zheng  wrote:
>> 
>> I agree that this is a better design for Swift than the monstrosity I 
>> started out with.
>> 
>> The "biggest" technical challenge I see is being able to type a reduction 
>> sort of operator on a heterogenous tuple based on on whatever protocols and 
>> constraints are common to its constituent members. For example:
>> 
>> // Every Tn in T... is Fooable and Barrable
>> let x : (T...)
>> reduce(x, reducer, startingValue)
>> 
>> func reducer(startingValue: U, eachMemberOfT: X) -> U { ... }
>> 
>> How do we bound ??? such that 'reducer' is useful while still being 
>> statically type sound? Honestly, that's the most interesting question to me. 
>> Generalized existentials might help with that.
> 
> If every T is Fooable and Barrable, couldn't `eachMemberOfT` be (inout U, 
> protocol) -> ()?
> 
>> Other questions (inherent to any proposal) would be:
>> 
>> - How do we resolve the impedance mismatch between tuples and function 
>> argument lists? Is it even worth trying to resolve this mismatch, given that 
>> argument lists are intentionally not intended to mirror tuples?
> 
> The impedance mismatch between function arguments and tuples is superficial. 
> You ought to be able to splat and bind tuples into function arguments, e.g.:
> 
>   let args = (1, 2)
>   foo(bar:bas:)(args...)
> 
>   func variadicFn(_ args: T...) { … }

Going this direction is relatively straightforward.  The impedance mismatch is 
trickier when you want to do more than that.  For example, it would be 
extremely useful to come up with some way to wrap a function that has 
parameters with default arguments without requiring callers of the wrapped 
function to supply arguments for the defaulted parameters.  Any ideas on how to 
solve that?

> 
>> - As you said, how do variadic generics work in the 0- and 1-member cases?
> 
> What problem are you referring to?
> 
> -Joe
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Ad hoc enums / options

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 6:35 AM, Leonardo Pessoa via swift-evolution 
>  wrote:
> 
> Unions have been discussed earlier in this group and I personally
> think this is an issue better solved using function overloading.
> Despite this, I see how union types could be implemented (hint:
> Optionals) but to use it in code would require you to, at least, test
> for the type of the value at hand for the blocks of different code
> between types. It feels like trying to bend a static typed language to
> work a bit like a dynamic typed and while both have their pros and
> cons I don't really think there is any benefit for the programmer and
> the readability of the code in bending the type checker like this.

Unions are a specialized tool that should be used carefully and precisely.  
That said, I have been uncovering several use cases where they are *exactly* 
what is needed.  Without them you end up with boilerplate of one kind or 
another.

> 
> L
> 
> On 1 June 2016 at 08:06, Haravikk via swift-evolution
>  wrote:
>> I agree the second is much nicer, and a lot clearer on what each of the
>> options does; fitImage: true is pretty clear, but fitImage: false is not,
>> but the ad-hoc enum is clear on both counts. That said, the questions of
>> interoperability are a big issue for ad-hoc enums, as either they’re too
>> strict which becomes inconvenient (a .Fit | .Fill working with one method
>> but not another) or too relaxed to be safe. Of course, in the latter case
>> you’re replacing a Bool, which couldn’t be more relaxed in terms of where it
>> accepts values from.
>> 
>> Still, I think in this case it would be better to fully-define an enum, as
>> it gives you total control over compatibility and reusability of the type,
>> which you can’t really with the ad-hoc form without making it overly
>> complex.
>> 
>> The main type of ad-hoc enum I want to see is a union-type like so:
>> 
>> func someMethod(value:(Int | String)) { … }
>> 
>> This would basically be an ad-hoc enum where each case identifies one of the
>> possible types, and the value bound as that type. This works however because
>> there’s no ambiguity in the meaning; an (Int | String) is the same wherever
>> you use it, whereas a general-purpose ad-hoc enum is less clear, as an other
>> method might also take .Fit and .Fill values, but these may have a slightly
>> different meaning.
>> 
>> So yeah, I like the idea in principle, but I think in practice it has too
>> many headaches to overcome for it to be as simple as it first appears =(
>> 
>> On 31 May 2016, at 17:16, Erica Sadun via swift-evolution
>>  wrote:
>> 
>> Here's a function signature from some code from today:
>> 
>> func scaleAndCropImage(
>> image: UIImage,
>> toSize size: CGSize,
>> fitImage: Bool = true
>> ) -> UIImage {
>> 
>> 
>> And here's what I want the function signature to actually look like:
>> 
>> func scaleAndCropImage(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: (.Fit | .Fill) = .Fit
>> ) -> UIImage {
>> 
>> 
>> where I don't have to establish a separate enumeration to include ad-hoc
>> enumeration-like semantics for the call. A while back, Yong hee Lee
>> introduced anonymous enumerations (and the possibility of anonymous option
>> flags) but the discussion rather died.
>> 
>> I'm bringing it up again to see whether there is any general interest in
>> pursuing this further as I think the second example is more readable,
>> appropriate, and Swifty than the first, provides better semantics, and is
>> more self documenting.
>> 
>> Thanks for your feedback,
>> 
>> -- Erica
>> 
>> ___
>> 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] Ad hoc enums / options

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 1:55 AM, Austin Zheng via swift-evolution 
>  wrote:
> 
> Maybe it's overkill. My personal opinion is that breaking the symmetry of the 
> language like this (are there any other types of function arguments that 
> cannot be passed as either variable values or literals?) is too much a price 
> to pay. Your library thinks it's being clever and vends its functions as 
> taking anonymous enum flags, and now there are a bunch of things I can't do 
> with those functions anymore.

+1.  Total non-starter to allow functions that are pretty much broken by 
design. 

> 
> A regular enum can be declared in one line anyways:
> 
> enum ScaleCropMode { case Fit, Fill }
> 
> Austin 
> 
>> On May 31, 2016, at 11:44 PM, Charles Constant  
>> wrote:
>> 
>> >  It breaks the ability to pass in a variable containing the desired value, 
>> > rather than the literal value itself.
>> 
>> Maybe that's appropriate? If the caller is not passing in a hardcoded enum 
>> case, then that enum is probably general enough that it warrants a normal 
>> enum. But there are also situations where the same function is called from 
>> several files in the same code-base with different flags. Those are 
>> situations where it feels like overkill to clutter up my codebase with 
>> separate enums, only used by a single function. 
>> 
>> 
>> 
>> 
>> 
>>> On Tue, May 31, 2016 at 9:24 PM, Austin Zheng via swift-evolution 
>>>  wrote:
>>> I admire the desire of this proposal to increase the readability of code. 
>>> I'm -1 to the proposal itself, though:
>>> 
>>> - It breaks the ability to pass in a variable containing the desired value, 
>>> rather than the literal value itself. (Unless you actually want a 
>>> not-so-anonymous enum type whose definition happens to live in a function 
>>> signature rather than somewhere you'd usually expect a type definition to 
>>> live.)
>>> - It breaks the ability to store a reference to the function in a variable 
>>> of function type (ditto).
>>> - Almost every time I've wanted to use one of these "anonymous enums" in my 
>>> code, I've ended up needing to use that same enum elsewhere. In my 
>>> experience, 'lightweight enums' don't end up saving much time compared to a 
>>> full-fledged one.
>>> 
>>> Like Brent said, I have to say no to any proposal that tries to make enums 
>>> synonyms for numerical values. What happens if you rearrange your anonymous 
>>> enum cases between library versions? Do you somehow store an opaque 
>>> case-to-UInt8 table somewhere for every anonymous enum you define for 
>>> resilience? What happens when people start bringing back terrible C 
>>> patterns, like doing arithmetic or bitwise ops on the underlying case 
>>> values? At least you have to try pretty hard as it is to abuse Swift's 
>>> enums.
>>> 
>>> Austin
>>> 
 On Tue, May 31, 2016 at 8:25 PM, Brent Royal-Gordon via swift-evolution 
  wrote:
 > And the obvious answer is you can have up to 255 of these babies for the 
 > anonymous enum type, and be able to pass numerical equivalents UInt8 
 > with compile time substitution. That the ad-hoc enumeration is basically 
 > a syntactic shorthand for UInt8, with an enforced upper bound compile 
 > time check simplifies everything including switch statements.
 
 If I wanted a language like that, I'd be writing C, not Swift.
 
 --
 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 31, 2016, at 7:10 PM, Chris Lattner  wrote:
> 
> This is very close to my priority list.  That said, I think that all of these 
> are out of scope for swift 3 sadly.  

Happy to hear these priorities look about right to you also.  (I realized 
afterwards that I left off opening existentials which I would put around 5 or 6)

BTW, generalized existentials is #2 for me if we include things that already 
have proposals as well.  That going to be a game changer.

I've already been assuming we won't see any major new generics features in 
Swift 3.  

> 
> After Swift 3, the priority list will be driven by what the standard library 
> needs to get its APIs realized in their ideal form (eg without any of the _ 
> protocol hacks).  Conditional conformances certainly top the list, but we 
> will have to carefully and ruthlessly prioritize things in order to get to 
> ABI stability.

Makes sense.

> 
> -Chris
> 
>> On May 31, 2016, at 2:16 PM, Matthew Johnson  wrote:
>> 
>> 
>>> On May 31, 2016, at 2:56 PM, Austin Zheng via swift-evolution 
>>>  wrote:
>>> 
>>> This is pretty much where my thinking about the topic has led me as well. 
>>> I'll resign this topic to pursue some other, hopefully more relevant work, 
>>> although anyone who wants to continue the discussion is welcome to.
>> 
>> Seems reasonable to wait until we can at least evaluate the macro approach 
>> properly.
>> 
>> Are you planning to continue work on generics?  FWIW, my top priority list 
>> for items without proposals is roughly:
>> 
>> 1. Conditional conformance 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-)
>> 2. Parameterized extensions 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions)
>> 3. Generic subscripts 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generic-subscripts)
>> 4. Recursive protocol constraints 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics)
>> 5. Nested generics 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics)
>> 6. Default generic arguments 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-generic-arguments)
>> 7. Extensions of structural types 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types)
>> 
>> And this one seems like low hanging fruit:
>> 
>> Default implementations in protocols 
>> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-implementations-in-protocols-)
>> 
>> How does this compare to your priorities for generics?
>> 
>>> 
 On Tue, May 31, 2016 at 12:49 PM, Chris Lattner  wrote:
 
> On May 31, 2016, at 12:17 PM, L Mihalkovic via swift-evolution 
>  wrote:
> 
> well there is no macro system, and for the moment a clear statement from 
> chris that this is not on the table in the short term. the code in the 
> example looked like run-of-the-mill swift, except for the “…". so that 
> leaves us with swift looking code that would be executed by the compiler, 
> but with nothing particular to tell which parts to and which not. just a 
> thought.
 
 Lets be clear though: variadic generics are not in scope for Swift 3 
 either.  
 
 I definitely don’t speak for the rest of the core team, nor have I 
 discussed it with them…  but IMO, this whole feature seems like a better 
 fit for a macro system than it does to complicate the generics system.  
 Unlike C++’s template system, our generics system inherently has runtime / 
 dynamic dispatch properties, and I don’t think that shoehorning variadics 
 into it is going to work out well.
 
 -Chris
 
> 
> 
>> On May 31, 2016, at 7:59 PM, Austin Zheng  wrote:
>> 
>> How so? I'm interested in anything that can get us away from having to 
>> generating code at compile-time.
>> 
>> On Tue, May 31, 2016 at 10:04 AM, L. Mihalkovic 
>>  wrote:
>>> 
>>> What's interesting about the code in the manifesto is that it looks 
>>> very much like "..." is a runtime construct, as opposed to trying the 
>>> get the compiler to do the heavy lifting.
> 
> ___
> 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] Ad hoc enums / options

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 3:46 PM, Vladimir.S  wrote:
> 
> > If you are not allowing callers to store their argument in a variable then
> > I am 100% opposed to this.  That would the first case in Swift where you
> > *MUST* provide a literal argument when calling a function, and *CANNOT*
> > provide a value you store in a variable (possibly something you receive as
> > an argument from somewhere else).  Why would we want to restrict the
> > flexibility of callers in that way?
> 
> Definitely we *must* be able to use a variable in call to function. The 
> problem is how (in case we agreee that the proposed feature could be useful).
> 
> I'm thinking about similarity of tuples and this anonymous enums.. If you 
> have tuple in function parameter - how would you use variable to pass it to 
> function? You'll define a variable of the exact same tuple as required, 
> manually, no some separate type provided for this. Yes, if tuple in function 
> definition changed - you'll need to change tuple on caller side:
> 
> func foo(int: Int, tuple: (Int, String)) {}
> 
> foo(1, tuple: (1, "string"))
> 
> var tupleVar : (Int, String) = (1, "string")
> 
> foo(1, tuple: tupleVar)
> 
> So, why not have the same for such anonymous enums?
> 
> func foo(int: Int, variant: (.one | .two)) {}
> 
> foo(1, variant: .one)
> 
> var enumVar : (.one | .two) = .one
> 
> foo(1, variant: enumVar)
> 
> 
> Seems like consistent solution.

It is consistent with tuples, but using a tuple instead of distinct parameters 
is usually going to be a bad idea.  If we introduce ad-hoc enums people are 
going to use it frequently.  And options like this are the kind of thing that 
*does* change periodically.  

Because those changes are usually additive I’m not too concerned about removing 
options.  But I *am* concerned about re-ordering existing options or adding new 
options impacting existing variable declarations.  For this reason, these would 
need to be order-independent and support structural subtyping.  That way my 
`(.foo | .bar)` variable is still a valid argument when you change the option 
list to `(.baz | .bar | .foo)`.

The existing approach of just defining an enum is really not so bad and removes 
this issue altogether.  IMO it is a reasonable “workaround” for now.

I believe there is a lot of overlap between doing this the right way and 
introducing structural unions like those in Ceylon (fortunately there seems to 
be growing support for this).  For that reason I think it makes sense to wait 
until we have that feature to look at ad-hoc types with enumerated values like 
this.

> 
> 
> On 31.05.2016 22:07, Matthew Johnson via swift-evolution wrote:
>> 
>>> On May 31, 2016, at 2:04 PM, Erica Sadun >> <mailto:er...@ericasadun.com>
>>> <mailto:er...@ericasadun.com <mailto:er...@ericasadun.com>>> wrote:
>>> 
>>>> 
>>>> On May 31, 2016, at 12:35 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>
>>>> <mailto:matt...@anandabits.com <mailto:matt...@anandabits.com>>> wrote:
>>>> 
>>>> I think I'm -1 on this.  It makes things easier for the implementer of
>>>> the function and harder for the caller.
>>>> 
>>>> It's not clear whether the caller could store an argument to pass in a
>>>> variable, but if they could they would need to list out all cases in the
>>>> type of the variable (unless these anonymous enums have structural
>>>> subtyping).  This is fragile.  Any time that list changes all variable
>>>> declarations will have to be updated.
>>>> 
>>>> Functions are implemented once and usually called more many times.  It's
>>>> better for callers if you just write it like this:
>>>> 
>>>> enum FitOrFill { case fit, fill }
>>>> func scaleAndCropImage(
>>>>image: UIImage,
>>>>toSize size: CGSize,
>>>>*operation: FitOrFill = .fit*
>>>>) -> UIImage {
>>>> 
>>>> 
>>>> So unless these anonymous enums are structurally subtyped I think it's a
>>>> bad idea.  And introducing structural subtyping here seems like a pretty
>>>> large hammer for this use case.
>>> 
>>> 
>>> From the caller's point of view, the type must be inferable and exactly
>>> match a token listed in the declaration (which would also appear in Quick
>>> Help):
>>> 
>>> let _ = scaleAndCropImage(image: myImage, toSize: size, operation: .fill)
>>> 
>>> You would not be able 

Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 3:39 PM, Austin Zheng  wrote:
> 
> (inline)
> 
> On Tue, May 31, 2016 at 1:34 PM, Matthew Johnson  > wrote:
> 
>> On May 31, 2016, at 3:25 PM, Austin Zheng > > wrote:
>> 
>> I have a proposal for #6 in the pipe, but there are actually some subtleties 
>> I have to work out (it's not as simple as just slapping a generic type 
>> signature on a let constant).
> 
> Cool.  Looking forward to reviewing a draft when it’s ready.
> 
>> 
>> I think #5 is just considered a 'bug' and doesn't need a proposal (it might 
>> actually be finished already; I saw some commits recently); same with #4. #7 
>> is not very useful without variadic generics (it pretty much exists to allow 
>> tuples to conform to protocols, and tuples are inherently variadic).
>> 
> 
> Good to know 4 and 5 are considered bugs.  I know #4 is important for the 
> standard library so I suppose that will ensure it is a priority soon enough.
> 
> I included #7 because it would still be nice to have for a number of reasons. 
>  Maybe there is a way to pull it off for a handful of types that are known to 
> the compiler.
> 
>> I wanted to take a stab at #2. 
> 
> Are you still thinking about this one or did you decide not to pursue it?
> 
> I think I'd like to try writing something up.
>  
> 
>> The core team has talked so much about #1 that I'd be surprised if they 
>> don't already have an idea as to how they want to do it, plus it's 
>> complicated for a number of reasons to get right. In such a case having the 
>> community push forward an alternate proposal would just be giving everyone 
>> more unneeded work.
> 
> Agree here as well.  I’ve avoided generics proposals mostly because I thought 
> the core team was leading the charge on all them.  It now appears like that 
> may not have been the right assumption across the board.  I wish we had a bit 
> more visibility on this...
> 
> Yes, same. I'm going off this bullet point at the beginning of the generics 
> manifesto:
> 
> "I hope to achieve several things: ... Engage more of the community in 
> discussions of specific generics features, so we can coalesce around designs 
> for public review. And maybe even get some of them implemented."
>  
> 
>> 
>> #3 seems semantically straightforward. AFAIK there's nothing a subscript can 
>> do that a getter and setter method can't do together, and methods can 
>> already be generic. A proposal shouldn't be hard to put together.
> 
> Agree.  Someone just needs to jump in and write it up.  :-)  If it had a 
> chance of making it into Swift 3 I would do it right away, but it’s hard to 
> tell...
> 
> I'd be happy to write up a proposal, especially if it's as straightforward as 
> it seems.

Cool!  I’ll continue to play the role of providing as much feedback as I can…  
:-)


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


Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 3:25 PM, Austin Zheng  wrote:
> 
> I have a proposal for #6 in the pipe, but there are actually some subtleties 
> I have to work out (it's not as simple as just slapping a generic type 
> signature on a let constant).

Cool.  Looking forward to reviewing a draft when it’s ready.

> 
> I think #5 is just considered a 'bug' and doesn't need a proposal (it might 
> actually be finished already; I saw some commits recently); same with #4. #7 
> is not very useful without variadic generics (it pretty much exists to allow 
> tuples to conform to protocols, and tuples are inherently variadic).
> 

Good to know 4 and 5 are considered bugs.  I know #4 is important for the 
standard library so I suppose that will ensure it is a priority soon enough.

I included #7 because it would still be nice to have for a number of reasons.  
Maybe there is a way to pull it off for a handful of types that are known to 
the compiler.

> I wanted to take a stab at #2.

Are you still thinking about this one or did you decide not to pursue it?

> The core team has talked so much about #1 that I'd be surprised if they don't 
> already have an idea as to how they want to do it, plus it's complicated for 
> a number of reasons to get right. In such a case having the community push 
> forward an alternate proposal would just be giving everyone more unneeded 
> work.

Agree here as well.  I’ve avoided generics proposals mostly because I thought 
the core team was leading the charge on all them.  It now appears like that may 
not have been the right assumption across the board.  I wish we had a bit more 
visibility on this...

> 
> #3 seems semantically straightforward. AFAIK there's nothing a subscript can 
> do that a getter and setter method can't do together, and methods can already 
> be generic. A proposal shouldn't be hard to put together.

Agree.  Someone just needs to jump in and write it up.  :-)  If it had a chance 
of making it into Swift 3 I would do it right away, but it’s hard to tell...

> 
> Let me know your thoughts.
> 
> Best,
> Austin
> 
> 
> 
> 
> On Tue, May 31, 2016 at 1:16 PM, Matthew Johnson  > wrote:
> 
>> On May 31, 2016, at 2:56 PM, Austin Zheng via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> This is pretty much where my thinking about the topic has led me as well. 
>> I'll resign this topic to pursue some other, hopefully more relevant work, 
>> although anyone who wants to continue the discussion is welcome to.
> 
> Seems reasonable to wait until we can at least evaluate the macro approach 
> properly.
> 
> Are you planning to continue work on generics?  FWIW, my top priority list 
> for items without proposals is roughly:
> 
> 1. Conditional conformance 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-
>  
> )
> 2. Parameterized extensions 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions
>  
> )
> 3. Generic subscripts 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generic-subscripts
>  
> )
> 4. Recursive protocol constraints 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics
>  
> )
> 5. Nested generics 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics
>  
> )
> 6. Default generic arguments 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-generic-arguments
>  
> )
> 7. Extensions of structural types 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>  
> )
> 
> And this one seems like low hanging fruit:
> 
> Default implementations in protocols 
> (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-implementations-in-protocols-
>  
> )
> 
> How does this compare to your priorities for generics?
> 
>> 
>> On Tue, May 31, 2016 at 12:49 PM, Chris Lattner > > wrote:
>> 
>>> On May 31, 2016, at 12:17 PM, L Mihalkovic via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> well there is no macro system, and for the moment a clear statement

Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 2:56 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> This is pretty much where my thinking about the topic has led me as well. 
> I'll resign this topic to pursue some other, hopefully more relevant work, 
> although anyone who wants to continue the discussion is welcome to.

Seems reasonable to wait until we can at least evaluate the macro approach 
properly.

Are you planning to continue work on generics?  FWIW, my top priority list for 
items without proposals is roughly:

1. Conditional conformance 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-
 
)
2. Parameterized extensions 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions
 
)
3. Generic subscripts 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generic-subscripts
 
)
4. Recursive protocol constraints 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics
 
)
5. Nested generics 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#nested-generics
 
)
6. Default generic arguments 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-generic-arguments
 
)
7. Extensions of structural types 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
 
)

And this one seems like low hanging fruit:

Default implementations in protocols 
(https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#default-implementations-in-protocols-
 
)

How does this compare to your priorities for generics?

> 
> On Tue, May 31, 2016 at 12:49 PM, Chris Lattner  > wrote:
> 
>> On May 31, 2016, at 12:17 PM, L Mihalkovic via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> well there is no macro system, and for the moment a clear statement from 
>> chris that this is not on the table in the short term. the code in the 
>> example looked like run-of-the-mill swift, except for the “…". so that 
>> leaves us with swift looking code that would be executed by the compiler, 
>> but with nothing particular to tell which parts to and which not. just a 
>> thought.
> 
> Lets be clear though: variadic generics are not in scope for Swift 3 either.  
> 
> I definitely don’t speak for the rest of the core team, nor have I discussed 
> it with them…  but IMO, this whole feature seems like a better fit for a 
> macro system than it does to complicate the generics system.  Unlike C++’s 
> template system, our generics system inherently has runtime / dynamic 
> dispatch properties, and I don’t think that shoehorning variadics into it is 
> going to work out well.
> 
> -Chris
> 
>> 
>> 
>>> On May 31, 2016, at 7:59 PM, Austin Zheng >> > wrote:
>>> 
>>> How so? I'm interested in anything that can get us away from having to 
>>> generating code at compile-time.
>>> 
>>> On Tue, May 31, 2016 at 10:04 AM, L. Mihalkovic 
>>> mailto:laurent.mihalko...@gmail.com>> wrote:
>>> 
>>> What's interesting about the code in the manifesto is that it looks very 
>>> much like "..." is a runtime construct, as opposed to trying the get the 
>>> compiler to do the heavy lifting.
>>> 
>> 
>> ___
>> 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] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 2:36 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
>> Exactly.  You are allowed to omit `return` if the entire body only consists 
>> of `return some().expression`
> 
> Thats where the useless example comes in (but we don’t need this behavior at 
> all):
> 
> func foo(boolean: Bool) {
> 
> guard boolean else {}
> 
> print("true“)
> 
> }
> 
> I made some changes to the proposal: 
> https://github.com/DevAndArtist/swift-evolution/blob/single_expression_optional_return/proposals/-single-expression-optional-return.md
>  
> 
> 
> Please review it again. :)

That looks good.  You might want to include more complex expressions just to 
make it clear that this isn’t limited to literal-returning expressions.  
Otherwise I think it covers it.  Thanks for putting this together!  I’ve wanted 
this for a long time… :)

> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 2:13 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
>> Please remove the section on guard as any of the preceding will never have 
>> single expression top level code blocks if they contain a guard clause.
> 
> I didn’t get this at first but now I see your point, it’s because the whole 
> returning scope will need `return` at the very end so `guard` should follow 
> that rule.
> 
> 

Exactly.  You are allowed to omit `return` if the entire body only consists of 
`return some().expression`

> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 31. Mai 2016 um 21:00:43, Matthew Johnson (matt...@anandabits.com 
> ) schrieb:
> 
>> 
> ___
> 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] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 1:11 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> AFAICT compile-time code generation suffers from the C++ templates problem - 
> my understanding is that if you don't have access to the definition of the 
> template you can't specialize. A Swift (regular, non-variadic) generic 
> function can be called with any conforming type without need for 
> specialization through dynamic dispatch, with specialization still existing 
> as an optimization. Having the same apply to variadic generics would be a 
> significant advantage.

I believe there has been some discussion of packaging SIL (or something like 
that) with modules for at least some generic constructs to allow specialization 
across module boundaries.

> 
> On Tue, May 31, 2016 at 11:08 AM, David Sweeris  > wrote:
> Out of curiosity, why?
> 
> - Dave Sweeris
> 
>> On May 31, 2016, at 12:59 PM, Austin Zheng via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> How so? I'm interested in anything that can get us away from having to 
>> generating code at compile-time.
>> 
>> On Tue, May 31, 2016 at 10:04 AM, L. Mihalkovic 
>> mailto:laurent.mihalko...@gmail.com>> wrote:
>> 
>> What's interesting about the code in the manifesto is that it looks very 
>> much like "..." is a runtime construct, as opposed to trying the get the 
>> compiler to do the heavy lifting.
>> 
>> ___
>> 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] Ad hoc enums / options

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 2:04 PM, Erica Sadun  wrote:
> 
>> 
>> On May 31, 2016, at 12:35 PM, Matthew Johnson > > wrote:
>> 
>> I think I'm -1 on this.  It makes things easier for the implementer of the 
>> function and harder for the caller.  
>> 
>> It's not clear whether the caller could store an argument to pass in a 
>> variable, but if they could they would need to list out all cases in the 
>> type of the variable (unless these anonymous enums have structural 
>> subtyping).  This is fragile.  Any time that list changes all variable 
>> declarations will have to be updated.
>> 
>> Functions are implemented once and usually called more many times.  It's 
>> better for callers if you just write it like this:
>> 
>> enum FitOrFill { case fit, fill }
>> func scaleAndCropImage(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: FitOrFill = .fit
>> ) -> UIImage {
>> 
>> So unless these anonymous enums are structurally subtyped I think it's a bad 
>> idea.  And introducing structural subtyping here seems like a pretty large 
>> hammer for this use case.
> 
> 
> From the caller's point of view, the type must be inferable and exactly match 
> a token listed in the declaration (which would also appear in Quick Help):
> 
> let _ = scaleAndCropImage(image: myImage, toSize: size, operation: .fill)
> 
> You would not be able to assign `.fill` to a variable and use that for the 
> operation value.

If you are not allowing callers to store their argument in a variable then I am 
100% opposed to this.  That would the first case in Swift where you *MUST* 
provide a literal argument when calling a function, and *CANNOT* provide a 
value you store in a variable (possibly something you receive as an argument 
from somewhere else).  Why would we want to restrict the flexibility of callers 
in that way?

> 
> -- E

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


Re: [swift-evolution] [Pitch] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 1:59 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
>> +1. This is example *is not* a single expression code block. There are 3 
>> expressions (the condition, the return value in the else block, and the 
>> primary return value). 
> 
> The `else` block is a returning single expression block. I can’t show the 
> `guard` example without any returning scope.
> 
> You said it yourself "everywhere in the language“. It’s not “everywhere“ if 
> we would left out `guards` else-returning block.

I was speaking casually and meant “top level code blocks that return a value”.  
You are right that I wasn’t totally clear about that.  I replied to your 
initial post with the clarification I believe is necessary.

> If we’d allow this we could also write:
> 
> func test(boolean: Bool) {
> guard boolean else {}
> print("true")
> }
> 
> This is useless and less readable.
> 
> But we already can do this with closures:
> 
> let nop = {} // useless
> 
> switch value {
>...
>default: {}() // do nothing
> }
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

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


Re: [swift-evolution] [Pitch] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 12:35 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> Here is the draft proposal: 
> https://github.com/DevAndArtist/swift-evolution/blob/single_expression_optional_return/proposals/-single-expression-optional-return.md
>  
> <https://github.com/DevAndArtist/swift-evolution/blob/single_expression_optional_return/proposals/-single-expression-optional-return.md>
> Did I covered everything case? If you find some mistakes feel free to provide 
> feedback so I can fix the proposal before I submit a PR.
> 
> 

This is a good start.  

"Make return optional and infer return type for single-expressions everywhere 
in the language:”

Everywhere in the language is too strong.  We should be more precise.  I 
believe we are talking about top level code blocks that only contain a single 
expression for the following constructs in the grammar:

function-body
getter-setter-block
getter-clause 
variable-declaration
subscript-declaration

Please remove the section on guard as any of the preceding will never have 
single expression top level code blocks if they contain a guard clause.

-Matthew

> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 31. Mai 2016 um 18:33:09, Leonardo Pessoa via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> +1
>> 
>> L
>> 
>> On 31 May 2016 at 12:47, Matthew Johnson via swift-evolution
>> mailto:swift-evolution@swift.org>> wrote:
>> >
>> >> On May 28, 2016, at 3:09 AM, David Hart via swift-evolution 
>> >>  wrote:
>> >>
>> >> It isn’t a special case because all other single-statement closures in 
>> >> the language work that way. It’s actually inconsistent now.
>> >
>> > Computed properties aren’t closures so it’s not inconsistent in that 
>> > sense. But it is inconsistent in that closures are the *only* 
>> > value-returning code blocks that are able to use this sugar. It would be 
>> > nice to see this sugar consistently allowed everywhere in the language.
>> >
>> >>
>> >>> On 28 May 2016, at 09:03, Brian Christensen via swift-evolution 
>> >>>  wrote:
>> >>>
>> >>> On May 27, 2016, at 13:57, Adrian Zubarev via swift-evolution 
>> >>>  wrote:
>> >>>
>> >>>> The idea is simple:
>> >>>>
>> >>>> • Can we make return keyword optional in cases like this?
>> >>>> • Shouldn’t this behave like @autoclosure or @noescape?
>> >>>> type A {
>> >>>> var characters: [Character] = …
>> >>>> var string: String { String(self.characters) }
>> >>>> var count: Int { 42 }
>> >>>> }
>> >>>>
>> >>>> Is this worth a proposal or Swifty enough, what do you think?
>> >>>>
>> >>>> Sure I could write return, but why do we allow this behavior for 
>> >>>> @noescape functions like map!?
>> >>>
>> >>> While I am not necessarily against this idea, I do wonder if it’s worth 
>> >>> making what’s going on here less obvious simply for the sake of being 
>> >>> able to omit a six character keyword. As I understand it, one of the 
>> >>> reasons ++/-- were removed was due to the increased "burden to learn 
>> >>> Swift as a first programming language.” This is the sort of thing that 
>> >>> becomes another one of those special cases that has to be explained to 
>> >>> someone new to Swift.
>> >>>
>> >>> /brian
>> >>>
>> >>> ___
>> >>> 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 
>> >> <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] [Pitch] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 1:16 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> I really like the proposal in case of properties and functions, but I really 
> don't want to have
> guard boolean else { "false” }

+1.  This is example *is not* a single expression code block.  There are 3 
expressions (the condition, the return value in the else block, and the primary 
return value).

> 
> I feel like `return` is very important part of `guard` statement.
> I understand the requirement for consistency with 
> properties/closures/functions, but I'll prefer to have some inconsistency in 
> language in this case and require `return` for `guard`. And in case I'll have 
> to choose all-or-nothig, I'll give -1 for the proposal.
> 
> I.e. IMO current `return` in properties and functions is less evil than 
> absent of `return` in `guard`.
> 
> On 31.05.2016 20:35, Adrian Zubarev via swift-evolution wrote:
>> Here is the draft proposal:
>> https://github.com/DevAndArtist/swift-evolution/blob/single_expression_optional_return/proposals/-single-expression-optional-return.md
>> 
>> Did I covered everything case? If you find some mistakes feel free to
>> provide feedback so I can fix the proposal before I submit a PR.
>> 
>> 
>> 
>> --
>> Adrian Zubarev
>> Sent with Airmail
>> 
>> Am 31. Mai 2016 um 18:33:09, Leonardo Pessoa via swift-evolution
>> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
>> 
>>> +1
>>> 
>>> L
>>> 
>>> On 31 May 2016 at 12:47, Matthew Johnson via swift-evolution
>>>  wrote:
>>> >
>>> >> On May 28, 2016, at 3:09 AM, David Hart via swift-evolution 
>>> >>  wrote:
>>> >>
>>> >> It isn’t a special case because all other single-statement closures in 
>>> >> the language work that way. It’s actually inconsistent now.
>>> >
>>> > Computed properties aren’t closures so it’s not inconsistent in that 
>>> > sense.  But it is inconsistent in that closures are the *only* 
>>> > value-returning code blocks that are able to use this sugar.  It would be 
>>> > nice to see this sugar consistently allowed everywhere in the language.
>>> >
>>> >>
>>> >>> On 28 May 2016, at 09:03, Brian Christensen via swift-evolution 
>>> >>>  wrote:
>>> >>>
>>> >>> On May 27, 2016, at 13:57, Adrian Zubarev via swift-evolution 
>>> >>>  wrote:
>>> >>>
>>> >>>> The idea is simple:
>>> >>>>
>>> >>>> • Can we make return keyword optional in cases like this?
>>> >>>> • Shouldn’t this behave like @autoclosure or @noescape?
>>> >>>> type A {
>>> >>>>   var characters: [Character] = …
>>> >>>>   var string: String { String(self.characters) }
>>> >>>>   var count: Int { 42 }
>>> >>>> }
>>> >>>>
>>> >>>> Is this worth a proposal or Swifty enough, what do you think?
>>> >>>>
>>> >>>> Sure I could write return, but why do we allow this behavior for 
>>> >>>> @noescape functions like map!?
>>> >>>
>>> >>> While I am not necessarily against this idea, I do wonder if it’s worth 
>>> >>> making what’s going on here less obvious simply for the sake of being 
>>> >>> able to omit a six character keyword. As I understand it, one of the 
>>> >>> reasons ++/-- were removed was due to the increased "burden to learn 
>>> >>> Swift as a first programming language.” This is the sort of thing that 
>>> >>> becomes another one of those special cases that has to be explained to 
>>> >>> someone new to Swift.
>>> >>>
>>> >>> /brian
>>> >>>
>>> >>> ___
>>> >>> 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
>> 
>> 
>> 
>> ___
>> 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] Ad hoc enums / options

2016-05-31 Thread Matthew Johnson via swift-evolution
I think I'm -1 on this.  It makes things easier for the implementer of the 
function and harder for the caller.  

It's not clear whether the caller could store an argument to pass in a 
variable, but if they could they would need to list out all cases in the type 
of the variable (unless these anonymous enums have structural subtyping).  This 
is fragile.  Any time that list changes all variable declarations will have to 
be updated.

Functions are implemented once and usually called more many times.  It's better 
for callers if you just write it like this:

enum FitOrFill { case fit, fill }
func scaleAndCropImage(
image: UIImage,
toSize size: CGSize,
operation: FitOrFill = .fit
) -> UIImage {

So unless these anonymous enums are structurally subtyped I think it's a bad 
idea.  And introducing structural subtyping here seems like a pretty large 
hammer for this use case.

Sent from my iPad

> On May 31, 2016, at 12:44 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> Big +1. I had similar thoughts a while back when I was writing some C++ or 
> Java code that had boolean arguments, and I found myself hating how 
> non-documenting they were and I would contrive two-valued enums to make call 
> sites look better. Having a crisp clean syntax for this would be fantastic 
> and encourage people to write self-documenting APIs.
> 
> Having argument labels solves some of the problems that come along with 
> boolean arguments, but "fitImage" is a great example where the false case 
> ("not fit?") doesn't really convey enough information (or can convey 
> misleading information).
> 
> 
>> On Tue, May 31, 2016 at 9:17 AM Erica Sadun via swift-evolution 
>>  wrote:
>> Here's a function signature from some code from today:
>> 
>> func scaleAndCropImage(
>> image: UIImage,
>> toSize size: CGSize,
>> fitImage: Bool = true
>> ) -> UIImage {
>> 
>> 
>> And here's what I want the function signature to actually look like:
>> 
>> func scaleAndCropImage(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: (.Fit | .Fill) = .Fit
>> ) -> UIImage {
>> 
>> 
>> where I don't have to establish a separate enumeration to include ad-hoc 
>> enumeration-like semantics for the call. A while back, Yong hee Lee 
>> introduced anonymous enumerations (and the possibility of anonymous option 
>> flags) but the discussion rather died.
>> 
>> I'm bringing it up again to see whether there is any general interest in 
>> pursuing this further as I think the second example is more readable, 
>> appropriate, and Swifty than the first, provides better semantics, and is 
>> more self documenting.
>> 
>> Thanks for your feedback,
>> 
>> -- Erica
>> 
>> ___
>> 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] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 10:46 AM, L. Mihalkovic  
> wrote:
> 
> 
> 
> On May 31, 2016, at 5:29 PM, Matthew Johnson  <mailto:matt...@anandabits.com>> wrote:
> 
>> 
>>> On May 31, 2016, at 10:17 AM, L Mihalkovic >> <mailto:laurent.mihalko...@gmail.com>> wrote:
>>> 
>>>> 
>>>> On May 31, 2016, at 4:26 PM, Matthew Johnson >>> <mailto:matt...@anandabits.com>> wrote:
>>>> 
>>>> 
>>>>> On May 31, 2016, at 9:16 AM, L Mihalkovic >>>> <mailto:laurent.mihalko...@gmail.com>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>>> On May 31, 2016, at 3:57 PM, Matthew Johnson via swift-evolution 
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> Austin,
>>>>>> 
>>>>>> One very useful possibility opened up by variadic generics that you 
>>>>>> don’t mention is the ability to write extensions for structural types 
>>>>>> (tuple, function, maybe union in the future), including conforming them 
>>>>>> to protocols.  This would be a separate proposal building on the 
>>>>>> capability of variadic generics but might be worth mentioning in “future 
>>>>>> directions”.
>>>>>> 
>>>>> 
>>>>> It might be worth reading again the generics manifesto’s comment about 
>>>>> how the runtime cost of chasing up the protocol chain might turn it into 
>>>>> a performance nightmare.
>>>> 
>>>> Are you talking about providing conditional conformance in a protocol 
>>>> extension: 
>>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions
>>>>  
>>>> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions>
>>>>  ?
>>>> 
>>>> That is not what I was talking about.  I was talking about extensions of 
>>>> structural types: 
>>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>>>>  
>>>> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types>
>>>> 
>>> 
>>> the two sections are linked. My point is just to keep in mind what they say 
>>> about the conformances that can be established at compile time, versus the 
>>> scenarios that wind-up hitting the runtime reflection system to resolve a 
>>> question (dynamic casts). 
>> 
>> There are no performance concerns noted in Doug’s manifesto.  Extensions, 
>> including conformances for structural types is listed under “minor 
>> extensions”, not “maybe” or “unlikely”.  Providing extensions and 
>> conformances for structural types shouldn’t be any more difficult than doing 
>> so for any other variadic type.
> 
> Good... my moment of doubt came from reading the code involved in the 
> differed initialization og metadata for the case of non fixed size tuples. I 
> will play more with the compiler and see if I can trigger it. 

It sounds like you’re more familiar with the implementation than I am.  I don’t 
know how much work has been done to support general variadic types yet.  It’s 
possible there is still a lot of work to be done.  But I can’t imagine any 
reason variadic conformance would be more difficult for built-in structural 
types than it is for user-defined variadic types.

> 
> 
> 
>> 
>>> 
>>>> 
>>>>> 
>>>>> 
>>>>>> Matthew
>>>>>> 
>>>>>>> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> I significantly rewrote the proposal to take into account as much 
>>>>>>> feedback as I could. (Many things, like syntax, haven't been changed 
>>>>>>> yet, but will be in a forthcoming version.)
>>>>>>> 
>>>>>>> What I did change:
>>>>>>> 
>>>>>>> - Renamed 'packs' to 'vectors'
>>>>>>> - Discussed variadic typealiases a bit, including things like "variadic 
>>>>>>> String" for holding the results of vector computations
>>>>>>> - There's a &

Re: [swift-evolution] [Pitch] Make `return` optional in computed properties for a single case

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 28, 2016, at 3:09 AM, David Hart via swift-evolution 
>  wrote:
> 
> It isn’t a special case because all other single-statement closures in the 
> language work that way. It’s actually inconsistent now.

Computed properties aren’t closures so it’s not inconsistent in that sense.  
But it is inconsistent in that closures are the *only* value-returning code 
blocks that are able to use this sugar.  It would be nice to see this sugar 
consistently allowed everywhere in the language.

> 
>> On 28 May 2016, at 09:03, Brian Christensen via swift-evolution 
>>  wrote:
>> 
>> On May 27, 2016, at 13:57, Adrian Zubarev via swift-evolution 
>>  wrote:
>> 
>>> The idea is simple:
>>> 
>>> • Can we make return keyword optional in cases like this?
>>> • Shouldn’t this behave like @autoclosure or @noescape?
>>> type A {
>>>   var characters: [Character] = …
>>>   var string: String { String(self.characters) }
>>>   var count: Int { 42 }
>>> }
>>> 
>>> Is this worth a proposal or Swifty enough, what do you think?
>>> 
>>> Sure I could write return, but why do we allow this behavior for @noescape 
>>> functions like map!?
>> 
>> While I am not necessarily against this idea, I do wonder if it’s worth 
>> making what’s going on here less obvious simply for the sake of being able 
>> to omit a six character keyword. As I understand it, one of the reasons 
>> ++/-- were removed was due to the increased "burden to learn Swift as a 
>> first programming language.” This is the sort of thing that becomes another 
>> one of those special cases that has to be explained to someone new to Swift.
>> 
>> /brian
>> 
>> ___
>> 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] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 10:17 AM, L Mihalkovic  
> wrote:
> 
>> 
>> On May 31, 2016, at 4:26 PM, Matthew Johnson > <mailto:matt...@anandabits.com>> wrote:
>> 
>> 
>>> On May 31, 2016, at 9:16 AM, L Mihalkovic >> <mailto:laurent.mihalko...@gmail.com>> wrote:
>>> 
>>> 
>>> 
>>>> On May 31, 2016, at 3:57 PM, Matthew Johnson via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Austin,
>>>> 
>>>> One very useful possibility opened up by variadic generics that you don’t 
>>>> mention is the ability to write extensions for structural types (tuple, 
>>>> function, maybe union in the future), including conforming them to 
>>>> protocols.  This would be a separate proposal building on the capability 
>>>> of variadic generics but might be worth mentioning in “future directions”.
>>>> 
>>> 
>>> It might be worth reading again the generics manifesto’s comment about how 
>>> the runtime cost of chasing up the protocol chain might turn it into a 
>>> performance nightmare.
>> 
>> Are you talking about providing conditional conformance in a protocol 
>> extension: 
>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions
>>  
>> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions>
>>  ?
>> 
>> That is not what I was talking about.  I was talking about extensions of 
>> structural types: 
>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>>  
>> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types>
>> 
> 
> the two sections are linked. My point is just to keep in mind what they say 
> about the conformances that can be established at compile time, versus the 
> scenarios that wind-up hitting the runtime reflection system to resolve a 
> question (dynamic casts). 

There are no performance concerns noted in Doug’s manifesto.  Extensions, 
including conformances for structural types is listed under “minor extensions”, 
not “maybe” or “unlikely”.  Providing extensions and conformances for 
structural types shouldn’t be any more difficult than doing so for any other 
variadic type.

> 
>> 
>>> 
>>> 
>>>> Matthew
>>>> 
>>>>> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> I significantly rewrote the proposal to take into account as much 
>>>>> feedback as I could. (Many things, like syntax, haven't been changed yet, 
>>>>> but will be in a forthcoming version.)
>>>>> 
>>>>> What I did change:
>>>>> 
>>>>> - Renamed 'packs' to 'vectors'
>>>>> - Discussed variadic typealiases a bit, including things like "variadic 
>>>>> String" for holding the results of vector computations
>>>>> - There's a "every variadic associated type must be equal" constraint 
>>>>> that can be defined now
>>>>> - I added a section discussing a "fold" operation, to reduce a value 
>>>>> pack/value vector into a single scalar with the help of a user-defined 
>>>>> function.
>>>>> - I changed the proposal so that making a tuple out of a vector now 
>>>>> requires surrounding the vector with #tuple(), to get rid of the 
>>>>> 'implicit' rules that plx brought up
>>>>> - I added a section briefly discussing how this feature might be 
>>>>> implemented.
>>>>> 
>>>>> Some thoughts:
>>>>> 
>>>>> - Things like indexing into a value vector by an integer value would be 
>>>>> extremely powerful. But as far as I can tell they'd require a great deal 
>>>>> of macro-like functionality to go along with them. A way to define 
>>>>> constant expressions would be required, so we could define "#index = 
>>>>> #count(T...)" or something. Then we'd need ways to manipulate that value 
>>>>> (increment or decrement) if we wanted to work with the previous or next 
>>>>> elements in a chain, we'd need compile-time conditional checking so that 
>>

Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution

> On May 31, 2016, at 9:16 AM, L Mihalkovic  
> wrote:
> 
> 
> 
>> On May 31, 2016, at 3:57 PM, Matthew Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Austin,
>> 
>> One very useful possibility opened up by variadic generics that you don’t 
>> mention is the ability to write extensions for structural types (tuple, 
>> function, maybe union in the future), including conforming them to 
>> protocols.  This would be a separate proposal building on the capability of 
>> variadic generics but might be worth mentioning in “future directions”.
>> 
> 
> It might be worth reading again the generics manifesto’s comment about how 
> the runtime cost of chasing up the protocol chain might turn it into a 
> performance nightmare.

Are you talking about providing conditional conformance in a protocol 
extension: 
https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions
 
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions>
 ?

That is not what I was talking about.  I was talking about extensions of 
structural types: 
https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
 
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types>


> 
> 
>> Matthew
>> 
>>> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I significantly rewrote the proposal to take into account as much feedback 
>>> as I could. (Many things, like syntax, haven't been changed yet, but will 
>>> be in a forthcoming version.)
>>> 
>>> What I did change:
>>> 
>>> - Renamed 'packs' to 'vectors'
>>> - Discussed variadic typealiases a bit, including things like "variadic 
>>> String" for holding the results of vector computations
>>> - There's a "every variadic associated type must be equal" constraint that 
>>> can be defined now
>>> - I added a section discussing a "fold" operation, to reduce a value 
>>> pack/value vector into a single scalar with the help of a user-defined 
>>> function.
>>> - I changed the proposal so that making a tuple out of a vector now 
>>> requires surrounding the vector with #tuple(), to get rid of the 'implicit' 
>>> rules that plx brought up
>>> - I added a section briefly discussing how this feature might be 
>>> implemented.
>>> 
>>> Some thoughts:
>>> 
>>> - Things like indexing into a value vector by an integer value would be 
>>> extremely powerful. But as far as I can tell they'd require a great deal of 
>>> macro-like functionality to go along with them. A way to define constant 
>>> expressions would be required, so we could define "#index = #count(T...)" 
>>> or something. Then we'd need ways to manipulate that value (increment or 
>>> decrement) if we wanted to work with the previous or next elements in a 
>>> chain, we'd need compile-time conditional checking so that a variadic 
>>> generic could behave correctly for the first or last item in a vector, and 
>>> so forth. Omitting these expensive features is going to limit the number of 
>>> uses variadic generics have; is this tradeoff going to be worth it? Could 
>>> we push off those features to a later date, if/when Swift gets an actual 
>>> compile time metaprogramming design?
>>> 
>>> - The more I think about things, the more I'm leaning towards the idea that 
>>> tuples are the only construct necessary. We could get rid of most of the 
>>> features of value packs/vectors, and allow them to only serve two roles: 
>>> defining a variadic generic function, and spreading out a tuple in order to 
>>> call a variadic generic function. (I think I prefer a spreading operator to 
>>> bringing back the magic compiler tuple splat functionality.) They could 
>>> also be "spread out" to define or specialize a different variadic generic 
>>> type. Thoughts?
>>> 
>>> - With the existence of 'fold', might it be worth it to remove #tail() (and 
>>> maybe #head), at least from v1? This would represent a slight loss of 
>>> expressive power for common use cases in exchange for a considerable 
>>> decrease in complexity.
>>> 
>>> Alternatively, s

Re: [swift-evolution] Variadic generics discussion

2016-05-31 Thread Matthew Johnson via swift-evolution
Austin,

One very useful possibility opened up by variadic generics that you don’t 
mention is the ability to write extensions for structural types (tuple, 
function, maybe union in the future), including conforming them to protocols.  
This would be a separate proposal building on the capability of variadic 
generics but might be worth mentioning in “future directions”.

Matthew

> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I significantly rewrote the proposal to take into account as much feedback as 
> I could. (Many things, like syntax, haven't been changed yet, but will be in 
> a forthcoming version.)
> 
> What I did change:
> 
> - Renamed 'packs' to 'vectors'
> - Discussed variadic typealiases a bit, including things like "variadic 
> String" for holding the results of vector computations
> - There's a "every variadic associated type must be equal" constraint that 
> can be defined now
> - I added a section discussing a "fold" operation, to reduce a value 
> pack/value vector into a single scalar with the help of a user-defined 
> function.
> - I changed the proposal so that making a tuple out of a vector now requires 
> surrounding the vector with #tuple(), to get rid of the 'implicit' rules that 
> plx brought up
> - I added a section briefly discussing how this feature might be implemented.
> 
> Some thoughts:
> 
> - Things like indexing into a value vector by an integer value would be 
> extremely powerful. But as far as I can tell they'd require a great deal of 
> macro-like functionality to go along with them. A way to define constant 
> expressions would be required, so we could define "#index = #count(T...)" or 
> something. Then we'd need ways to manipulate that value (increment or 
> decrement) if we wanted to work with the previous or next elements in a 
> chain, we'd need compile-time conditional checking so that a variadic generic 
> could behave correctly for the first or last item in a vector, and so forth. 
> Omitting these expensive features is going to limit the number of uses 
> variadic generics have; is this tradeoff going to be worth it? Could we push 
> off those features to a later date, if/when Swift gets an actual compile time 
> metaprogramming design?
> 
> - The more I think about things, the more I'm leaning towards the idea that 
> tuples are the only construct necessary. We could get rid of most of the 
> features of value packs/vectors, and allow them to only serve two roles: 
> defining a variadic generic function, and spreading out a tuple in order to 
> call a variadic generic function. (I think I prefer a spreading operator to 
> bringing back the magic compiler tuple splat functionality.) They could also 
> be "spread out" to define or specialize a different variadic generic type. 
> Thoughts?
> 
> - With the existence of 'fold', might it be worth it to remove #tail() (and 
> maybe #head), at least from v1? This would represent a slight loss of 
> expressive power for common use cases in exchange for a considerable decrease 
> in complexity.
> 
> Alternatively, some tuple-based designs might make this point obsolete. 
> Imagine something like this:
> 
> func head(input: (T, U...)) -> T { ... }
> func tail(input: (T, U...)) -> (U...) { ... }
> 
> Again, any comments are welcome. I hope to continue evolving this proposal as 
> the community decides what they want and don't want to see.
> 
> 
>> On May 28, 2016, at 1:03 PM, Austin Zheng > > wrote:
>> 
>> Hello swift-evolution,
>> 
>> I put together a draft proposal for the variadic generics feature described 
>> in "Completing Generics" as a major objective for Swift 3.x. It can be found 
>> here:
>> 
>> https://github.com/austinzheng/swift-evolution/blob/az-variadic-generics/proposals/-variadic-generics.md
>>  
>> 
>> 
>> It adopts the syntax and semantics that are described in Completing 
>> Generics, and attempts to remain as simple as possible while still being 
>> useful for certain use cases (although I think there is still room to 
>> simplify). The proposal contains sample implementations for four use cases:
>> 
>> - Arbitrary-arity 'zip' sequence
>> - Arbitrary-arity tuple comparison for equality
>> - Tuple splat/function application
>> - Multiple-arity Clojure-style 'map' function
>> 
>> There is a lot of scope for design refinements, and even for alternative 
>> designs. With enhanced existentials, there was already an informal consensus 
>> that the feature would involve composing some protocols and class 
>> requirements, and placing constraints on the associated types, and most 
>> everything else was working out the various implications of doing so. That's 
>> not true for this feature.
>> 
>> In particular, I'm interested to see if there are similarly expressive 
>> designs that use exclusively tuple-based patterns and no par

Re: [swift-evolution] [Pitch] Tuple Destructuring in Parameter Lists

2016-05-30 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On May 30, 2016, at 8:01 AM, Brent Royal-Gordon via swift-evolution 
 wrote:

>> // Allowed today:
>> func takesATuple(tuple: (Int, Int)) {
>>  let valueA = tuple.0
>>  let valueB = tuple.1
>>  // ...
>> }
>> 
>> // Proposed syntax:
>> func takesATuple(tuple (valueA, valueB): (Int, Int)) {
>>  // use valueA
>>  // use valueB
>> }
> 
> Personally, I find this example confusing because the label is "tuple", which 
> kind of reads like a keyword, and because you're using the same name for the 
> label and variable. If I understand the semantics you're proposing correctly, 
> I think it would be clearer to write this example like:
> 
> // Allowed today:
> func takes(a tuple: (Int, Int)) {
>  let valueA = tuple.0
>  let valueB = tuple.1
>  // ...
> }
> 
> // Proposed syntax:
> func takes(a (valueA, valueB): (Int, Int)) {
>  // use valueA
>  // use valueB
> }
> 
> Incidentally, it may also be a good idea to define what happens if you write:
> 
> func takes((valueA, valueB): (Int, Int))
> 
> Normally, if there's no separate label and variable name, they're the same, 
> but you can't have a label like `(valueA, valueB)`. I see two reasonably 
> sensible answers here:
> 
> 1. It's equivalent to writing `_ (valueA, valueB)`.
> 2. It's illegal. You have to write a label, or `_` if you don't want one.
> 
> My preference would be for #2, but you're the designer, not me.

I agree.  #2 is more consistent with Swift 3 where all arguments have external 
names by default.  I don't think this should change just because there is no 
direct internal name that can also serve as an external name.

I like the idea of allowing destructuring everywhere we bind a name very much.  
My only (minor) concern with doing this for tuples right now is that it might 
encourage overuse of them where a struct would be a better choice.  

I have been thinking about destructuring of structs and classes and wonder if 
it might be best to introduce that first.  That would avoid any temptation to 
abuse tuples just because they can be destructured.  This is probably an 
overblown concern but it is something to consider.   

Another option would be to just introduce a related proposal to destructure 
structs and classes at roughly the same time as the parameter destructuring 
proposal...

> 
> -- 
> 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] Enhanced existential types proposal discussion

2016-05-30 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 10:22 PM, Charles Srstka  wrote:
> 
>> On May 29, 2016, at 10:13 PM, Matthew Johnson  wrote:
>> 
>> On May 29, 2016, at 9:43 PM, Charles Srstka  wrote:
>> 
 On May 29, 2016, at 9:20 PM, Matthew Johnson  
 wrote:
 
 On May 29, 2016, at 5:43 PM, Charles Srstka via swift-evolution 
  wrote:
 
>> On May 29, 2016, at 5:16 PM, Austin Zheng  wrote:
>> 
>> I think the problem here is that P == P is true, but P : P is not (a 
>> protocol does not conform to itself).
> 
> But if you have a variable, parameter, etc. typed as P, that’s *not* the 
> protocol, since protocols aren’t concrete entities. What you have there, 
> by definition, is something that conforms to P. Similarly, something like 
> [P] is just a collection of things, perhaps of various types, which all 
> have the common feature that they conform to P.
 
 You have an existential value of type P.  It is a well known frustration 
 in Swift that the existential type corresponding to a protocol does not 
 conform to the protocol.  This has been discussed off and on at different 
 times.  
 
 There are a couple of reasons this is the case.  IIRC in some cases it 
 actually isn't possible for the existential to conform to the protocol in 
 a sound way.  And even when it is possible, I believe it has been said 
 that it is more difficult to implement than you might think.  Hopefully 
 the situation will improve in the future but I'm not aware of any specific 
 plans at the moment.
>>> 
>>> It’s been my understanding that a variable typed P in swift is equivalent 
>>> to what we would have called id  in Objective-C—that is, an object of 
>>> unknown type that conforms to P. Is this not the case? I am curious what 
>>> the conceptual difference would be, as well as the rationale behind it.
>> 
>> Existentials have their own type in Swift.  The problem you are running into 
>> is because the generic constraint is looking at the existential type of P 
>> and asking if that type conforms to P (which it does not - you can't write 
>> the conformance and the compiler does not provide it for you).  It is not 
>> asking if the type of the object underlying the existential value conforms 
>> to P (which it necessarily does).  When you have a value of type P you have 
>> already erased the type of the underlying object.
> 
> Have we not also erased the type of the underlying object with id , 
> though? The only thing we get from the “id” is that it’s an Objective-C 
> object of some type, which it would have to have been anyway in order to 
> conform to the protocol in the first place. Thus the type of the object is 
> erased, and the only thing we know about it is that it conforms to the 
> protocol—just like something typed P in Swift.

In Swift values with the existential type P are not necessarily objects, they 
could be values.  Because of this existentials are implemented a bit 
differently.

> 
> What I’m trying to figure out is whether there’s any positive benefit or 
> rationale to the reason things work the way they do here, or whether it’s 
> just bugs / implementation details.

I think it's a bit of both.  As I mentioned, IIRC there are cases where values 
of existential type *cannot* correctly conform to the protocol that they were 
derived from (I believe this is when Self or associated type requirements are 
involved).  There are also cases where it is possible but is more difficult to 
implement than you might expect.  I think we'll see progress eventually, but 
not in Swift 3.

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


Re: [swift-evolution] Variadic generics discussion

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 10:14 PM, Austin Zheng  wrote:
> 
> 
>> On May 29, 2016, at 8:04 PM, Matthew Johnson  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>>>  wrote:
>>> 
>>> I significantly rewrote the proposal to take into account as much feedback 
>>> as I could. (Many things, like syntax, haven't been changed yet, but will 
>>> be in a forthcoming version.)
>>> 
>>> What I did change:
>>> 
>>> - Renamed 'packs' to 'vectors'
>> 
>> What is the rationale here?  Vector makes some sense for the parameter packs 
>> because they only consist of types and are thus homogenous.  But value packs 
>> and argument packs will consist of values or arguments that might all have 
>> different types.  They are heterogeneous.  So vector doesn't seem like the 
>> right term.  It's not a huge deal, but something to consider anyway.
> 
> The intended meaning is that a value vector is homogeneous in the sense that 
> all its members are values.

Makes sense when you look at just the fact that they are values and don't 
consider what kind of value I guess.

> 
> That being said, I don't feel much at all about the naming either way. The 
> "rationale" was that maybe changing 'pack' to a different word would help 
> avoid scaring off people still scarred by C++ templates :). Not really a 
> compelling reason to be honest.
> 
> Austin
> 
> 
>> By the way, the multiMap example is basically the same as the applicative 
>> functor for ZipList in Haskell 
>> (http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors).
>>   You can probably find several more good examples by looking at other 
>> applicative functors.
>> 
>> Still thinking about more robust function forwarding but not making much 
>> progress...
>> 
>>> - Discussed variadic typealiases a bit, including things like "variadic 
>>> String" for holding the results of vector computations
>>> - There's a "every variadic associated type must be equal" constraint that 
>>> can be defined now
>>> - I added a section discussing a "fold" operation, to reduce a value 
>>> pack/value vector into a single scalar with the help of a user-defined 
>>> function.
>>> - I changed the proposal so that making a tuple out of a vector now 
>>> requires surrounding the vector with #tuple(), to get rid of the 'implicit' 
>>> rules that plx brought up
>>> - I added a section briefly discussing how this feature might be 
>>> implemented.
>>> 
>>> Some thoughts:
>>> 
>>> - Things like indexing into a value vector by an integer value would be 
>>> extremely powerful. But as far as I can tell they'd require a great deal of 
>>> macro-like functionality to go along with them. A way to define constant 
>>> expressions would be required, so we could define "#index = #count(T...)" 
>>> or something. Then we'd need ways to manipulate that value (increment or 
>>> decrement) if we wanted to work with the previous or next elements in a 
>>> chain, we'd need compile-time conditional checking so that a variadic 
>>> generic could behave correctly for the first or last item in a vector, and 
>>> so forth. Omitting these expensive features is going to limit the number of 
>>> uses variadic generics have; is this tradeoff going to be worth it? Could 
>>> we push off those features to a later date, if/when Swift gets an actual 
>>> compile time metaprogramming design?
>>> 
>>> - The more I think about things, the more I'm leaning towards the idea that 
>>> tuples are the only construct necessary. We could get rid of most of the 
>>> features of value packs/vectors, and allow them to only serve two roles: 
>>> defining a variadic generic function, and spreading out a tuple in order to 
>>> call a variadic generic function. (I think I prefer a spreading operator to 
>>> bringing back the magic compiler tuple splat functionality.) They could 
>>> also be "spread out" to define or specialize a different variadic generic 
>>> type. Thoughts?
>>> 
>>> - With the existence of 'fold', might it be worth it to remove #tail() (and 
>>> maybe #head), at least from v1? This would represent a slight loss of 
>>> expressive power for common use cases in exchange for a considerable 
>>> decrease in complexity.
>>> 
>>> Alternatively, some tuple-based designs might make this point obsolete. 
>>> Imagine something like this:
>>> 
>>> func head(input: (T, U...)) -> T { ... }
>>> func tail(input: (T, U...)) -> (U...) { ... }
>>> 
>>> Again, any comments are welcome. I hope to continue evolving this proposal 
>>> as the community decides what they want and don't want to see.
>>> 
>>> 
 On May 28, 2016, at 1:03 PM, Austin Zheng  wrote:
 
 Hello swift-evolution,
 
 I put together a draft proposal for the variadic generics feature 
 described in "Completing Generics" as a major objective for Swift 3.x. It 
 can be found here:
 
 https://github.com/austinzheng/swift-evolution/blob/a

Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 9:43 PM, Charles Srstka  wrote:
> 
>> On May 29, 2016, at 9:20 PM, Matthew Johnson  wrote:
>> 
>> On May 29, 2016, at 5:43 PM, Charles Srstka via swift-evolution 
>>  wrote:
>> 
 On May 29, 2016, at 5:16 PM, Austin Zheng  wrote:
 
 I think the problem here is that P == P is true, but P : P is not (a 
 protocol does not conform to itself).
>>> 
>>> But if you have a variable, parameter, etc. typed as P, that’s *not* the 
>>> protocol, since protocols aren’t concrete entities. What you have there, by 
>>> definition, is something that conforms to P. Similarly, something like [P] 
>>> is just a collection of things, perhaps of various types, which all have 
>>> the common feature that they conform to P.
>> 
>> You have an existential value of type P.  It is a well known frustration in 
>> Swift that the existential type corresponding to a protocol does not conform 
>> to the protocol.  This has been discussed off and on at different times.  
>> 
>> There are a couple of reasons this is the case.  IIRC in some cases it 
>> actually isn't possible for the existential to conform to the protocol in a 
>> sound way.  And even when it is possible, I believe it has been said that it 
>> is more difficult to implement than you might think.  Hopefully the 
>> situation will improve in the future but I'm not aware of any specific plans 
>> at the moment.
> 
> It’s been my understanding that a variable typed P in swift is equivalent to 
> what we would have called id  in Objective-C—that is, an object of unknown 
> type that conforms to P. Is this not the case? I am curious what the 
> conceptual difference would be, as well as the rationale behind it.

Existentials have their own type in Swift.  The problem you are running into is 
because the generic constraint is looking at the existential type of P and 
asking if that type conforms to P (which it does not - you can't write the 
conformance and the compiler does not provide it for you).  It is not asking if 
the type of the object underlying the existential value conforms to P (which it 
necessarily does).  When you have a value of type P you have already erased the 
type of the underlying object.

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


Re: [swift-evolution] Variadic generics discussion

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I significantly rewrote the proposal to take into account as much feedback as 
> I could. (Many things, like syntax, haven't been changed yet, but will be in 
> a forthcoming version.)
> 
> What I did change:
> 
> - Renamed 'packs' to 'vectors'

What is the rationale here?  Vector makes some sense for the parameter packs 
because they only consist of types and are thus homogenous.  But value packs 
and argument packs will consist of values or arguments that might all have 
different types.  They are heterogeneous.  So vector doesn't seem like the 
right term.  It's not a huge deal, but something to consider anyway.

By the way, the multiMap example is basically the same as the applicative 
functor for ZipList in Haskell 
(http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors).
  You can probably find several more good examples by looking at other 
applicative functors.

Still thinking about more robust function forwarding but not making much 
progress...

> - Discussed variadic typealiases a bit, including things like "variadic 
> String" for holding the results of vector computations
> - There's a "every variadic associated type must be equal" constraint that 
> can be defined now
> - I added a section discussing a "fold" operation, to reduce a value 
> pack/value vector into a single scalar with the help of a user-defined 
> function.
> - I changed the proposal so that making a tuple out of a vector now requires 
> surrounding the vector with #tuple(), to get rid of the 'implicit' rules that 
> plx brought up
> - I added a section briefly discussing how this feature might be implemented.
> 
> Some thoughts:
> 
> - Things like indexing into a value vector by an integer value would be 
> extremely powerful. But as far as I can tell they'd require a great deal of 
> macro-like functionality to go along with them. A way to define constant 
> expressions would be required, so we could define "#index = #count(T...)" or 
> something. Then we'd need ways to manipulate that value (increment or 
> decrement) if we wanted to work with the previous or next elements in a 
> chain, we'd need compile-time conditional checking so that a variadic generic 
> could behave correctly for the first or last item in a vector, and so forth. 
> Omitting these expensive features is going to limit the number of uses 
> variadic generics have; is this tradeoff going to be worth it? Could we push 
> off those features to a later date, if/when Swift gets an actual compile time 
> metaprogramming design?
> 
> - The more I think about things, the more I'm leaning towards the idea that 
> tuples are the only construct necessary. We could get rid of most of the 
> features of value packs/vectors, and allow them to only serve two roles: 
> defining a variadic generic function, and spreading out a tuple in order to 
> call a variadic generic function. (I think I prefer a spreading operator to 
> bringing back the magic compiler tuple splat functionality.) They could also 
> be "spread out" to define or specialize a different variadic generic type. 
> Thoughts?
> 
> - With the existence of 'fold', might it be worth it to remove #tail() (and 
> maybe #head), at least from v1? This would represent a slight loss of 
> expressive power for common use cases in exchange for a considerable decrease 
> in complexity.
> 
> Alternatively, some tuple-based designs might make this point obsolete. 
> Imagine something like this:
> 
> func head(input: (T, U...)) -> T { ... }
> func tail(input: (T, U...)) -> (U...) { ... }
> 
> Again, any comments are welcome. I hope to continue evolving this proposal as 
> the community decides what they want and don't want to see.
> 
> 
>> On May 28, 2016, at 1:03 PM, Austin Zheng  wrote:
>> 
>> Hello swift-evolution,
>> 
>> I put together a draft proposal for the variadic generics feature described 
>> in "Completing Generics" as a major objective for Swift 3.x. It can be found 
>> here:
>> 
>> https://github.com/austinzheng/swift-evolution/blob/az-variadic-generics/proposals/-variadic-generics.md
>> 
>> It adopts the syntax and semantics that are described in Completing 
>> Generics, and attempts to remain as simple as possible while still being 
>> useful for certain use cases (although I think there is still room to 
>> simplify). The proposal contains sample implementations for four use cases:
>> 
>> - Arbitrary-arity 'zip' sequence
>> - Arbitrary-arity tuple comparison for equality
>> - Tuple splat/function application
>> - Multiple-arity Clojure-style 'map' function
>> 
>> There is a lot of scope for design refinements, and even for alternative 
>> designs. With enhanced existentials, there was already an informal consensus 
>> that the feature would involve composing some protocols and class 
>> requirements, and placing constraints on the associated types, and most 
>> eve

Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 5:43 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> On May 29, 2016, at 5:16 PM, Austin Zheng  wrote:
>> 
>> I think the problem here is that P == P is true, but P : P is not (a 
>> protocol does not conform to itself).
> 
> But if you have a variable, parameter, etc. typed as P, that’s *not* the 
> protocol, since protocols aren’t concrete entities. What you have there, by 
> definition, is something that conforms to P. Similarly, something like [P] is 
> just a collection of things, perhaps of various types, which all have the 
> common feature that they conform to P.

You have an existential value of type P.  It is a well known frustration in 
Swift that the existential type corresponding to a protocol does not conform to 
the protocol.  This has been discussed off and on at different times.  

There are a couple of reasons this is the case.  IIRC in some cases it actually 
isn't possible for the existential to conform to the protocol in a sound way.  
And even when it is possible, I believe it has been said that it is more 
difficult to implement than you might think.  Hopefully the situation will 
improve in the future but I'm not aware of any specific plans at the moment.

> 
>> I think there was some discussion about it on the original "Completing 
>> Generics" thread from March. I'd probably ask on the swift-users list why P 
>> can't be made to conform to P, and then put together a proposal if there's 
>> no good reason.
> 
> Will do.
> 
> 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] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 9:12 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
>> On 27.05.2016 18:37, plx via swift-evolution wrote:
>> 
>>> On May 26, 2016, at 1:00 PM, T.J. Usiyan via swift-evolution
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> A `deriving` keyword, at the very least, is pretty explicitly *not* an
>>> all-or-nothing situation. If you want to define equality/hashability for
>>> your type manually, don't use `deriving`. This should leave the simplest
>>> cases to auto generation and anything more complex should be handled by
>>> the developer.
>> 
>> It’s all-or-nothing in the sense you can’t use a naive `deriving`
>> implementation to assist in any case where what you need is *almost* the
>> trivial implementation, but not quite.
> 
> I support that we need a way to exclude some fields from participate in 
> auto-derived code. It is not handy if we'll have just one-two excluded 
> properties (of 10 for example) and we'll need to implement the boilerplate 
> code because of this. Probably, this should be another proposal for this 
> feature.
> 
> Just some thoughts: such a method to decorate some fields as 
> `nonequatable`/`nonhashable` has no meaning *if* Equatable/Hashable is later 
> implemented manually. So, to remove confusion, it seems like such 'method' to 
> exclude should be disallowed(by compiler) if protocols are implemented 
> manually by coder.
> I.e., I don't want to see a code where we have *both* explicit 
> implementations of protocols *and* some decorators/special functions to 
> exclude some fields as this will no any sense.
> 
> Also for me it seems like we need to be able to define such attribute near 
> the field itself, to prevent later errors when you define new field but 
> forgot to add it to some 'special list' of excluded field somewhere in code.
> So, probably I'd prefer some kind of @nonequatable and @nonhashable :
> @nonequatable var field = 0

The same members should be considered by both Equatable and Hashable so there 
would be no need for two separate annotations.  A more general annotation 
(maybe "nonessential"?) is what we want.

> 
> 
>> 
>> Consider a case like this:
>> 
>>  class QuxEvaluator  {
>> 
>>let foo: Foo // Equatable
>>let bar: Bar // Equatable
>>let baz: Baz // Equatable
>> 
>>private var quxCache: [QuxIdentifier:Qux] // [Equatable:Equatable] = [:]
>> 
>>// pure function of `foo`, `bar`, `baz`, and `identifier`
>>// expensive, and uses `quxCache` for memoization
>>func qux(for identifier: QuxIdentifier) -> Qux
>> 
>>  }
>> 
>> …if it weren’t for `quxCache` we could easily synthesize `==` for
>> `QuxEvaluator`, but the trivial synthesis will yield invalid results due to
>> `[QuxIdentifier:Qux]` also being `Equatable` (really: it *will* also be
>> equatable once conditional conformances are in place).
>> 
>> So we’re back to e.g. writing this:
>> 
>>  extension QuxEvaluator : Equatable {
>> 
>>  }
>> 
>>  func ==(lhs: QuxEvaluator, rhs: QuxEvaluator) -> Bool {
>>return (lhs === rhs) || (lhs.foo == rhs.foo && lhs.bar == rhs.bar &&
>> lhs.baz == rhs.baz)
>>  }
>> 
>> …just to omit a single field from the `==` consideration; this is another
>> sense in which you can say deriving is an all-or-none; there’s just no way
>> to invoke the synthesis mechanism other than for "all fields”.
>> 
>> On the one hand, it’s possible to imagine a finer-grained form of this
>> synthesis that’d allow you to e.g. indicate a certain field should be
>> omitted (and also perhaps specialize how fields are compared, customize the
>> synthesized comparison ordering to put cheaper comparisons earlier, and an
>> endless list of other possible requests…).
>> 
>> On the other hand, the memberwise-init proposal had a very similar
>> situation: the naive approach was arguably too narrow, but it proved very
>> difficult to find a workable balance between customization and
>> implementation complexity (leaving it postponed for the foreseeable
>> future); it’d be a pity if synthesis like this fell into the same trap.
>> 
>> But, on the gripping hand, I highly suspect that a naive
>> `deriving`/synthesis will wind up being too narrowly-useful to really
>> justify; that’s just my opinion, of course.
>> 
>>> 
>>> On Thu, May 26, 2016 at 11:20 AM, L. Mihalkovic
>>> mailto:laurent.mihalko...@gmail.com>> wrote:
>>> 
>>>what i care about is to have a choice about what DEFINES the identity
>>>of my values, not just an all-or-nothing situation.
>>> 
>>>On May 26, 2016, at 5:18 PM, T.J. Usiyan via swift-evolution
>>>mailto:swift-evolution@swift.org>> wrote:
>>> 
+1 to a `deriving` keyword
 
On Thu, May 26, 2016 at 3:58 AM, Michael Peternell via
swift-evolution >>>> wrote:
 
Can we just copy&paste the solution from Haskell instead of
creating our own? It's just better in every aspect. Deriving
`Equatable` 

Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 8:41 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> Saw `class` in examples and want to clarify.. Are we discussing auto-deriving 
> for *value types only*. Or for classes also?
> As I understand, there could be some additional questions/issues for this 
> feature because of class inheritance. But probably this feature could be 
> discussed for `final` classes also?

Classes usually have reference semantics.  In that case reference identity is 
the appropriate definition of equality.  Other kinds of equivalence tests are 
possible but should not have the name ==.

Immutable classes can have value semantics.  In that case a memberwise equality 
is as likely to be correct as it is for structs.  So it is possible we could 
allow synthesis to be requested for classes, it would just result in an error 
more frequently than with structs.


> 
>> On 27.05.2016 22:41, plx via swift-evolution wrote:
>> 
>>> On May 27, 2016, at 10:48 AM, Matthew Johnson >> > wrote:
>>> 
 
 On May 27, 2016, at 10:37 AM, plx via swift-evolution
 mailto:swift-evolution@swift.org>> wrote:
 
 
> On May 26, 2016, at 1:00 PM, T.J. Usiyan via swift-evolution
> mailto:swift-evolution@swift.org>> wrote:
> 
> A `deriving` keyword, at the very least, is pretty explicitly *not* an
> all-or-nothing situation. If you want to define equality/hashability
> for your type manually, don't use `deriving`. This should leave the
> simplest cases to auto generation and anything more complex should be
> handled by the developer.
 
 It’s all-or-nothing in the sense you can’t use a naive `deriving`
 implementation to assist in any case where what you need is *almost* the
 trivial implementation, but not quite.
 
 Consider a case like this:
 
  class QuxEvaluator  {
 
let foo: Foo // Equatable
let bar: Bar // Equatable
let baz: Baz // Equatable
 
private var quxCache: [QuxIdentifier:Qux] // [Equatable:Equatable] = [:]
 
// pure function of `foo`, `bar`, `baz`, and `identifier`
// expensive, and uses `quxCache` for memoization
func qux(for identifier: QuxIdentifier) -> Qux
 
  }
 
 …if it weren’t for `quxCache` we could easily synthesize `==` for
 `QuxEvaluator`, but the trivial synthesis will yield invalid results due
 to `[QuxIdentifier:Qux]` also being `Equatable` (really: it *will* also
 be equatable once conditional conformances are in place).
 
 So we’re back to e.g. writing this:
 
  extension QuxEvaluator : Equatable {
 
  }
 
  func ==(lhs: QuxEvaluator, rhs: QuxEvaluator) -> Bool {
return (lhs === rhs) || (lhs.foo == rhs.foo && lhs.bar == rhs.bar &&
 lhs.baz == rhs.baz)
  }
 
 …just to omit a single field from the `==` consideration; this is
 another sense in which you can say deriving is an all-or-none; there’s
 just no way to invoke the synthesis mechanism other than for "all fields”.
>>> 
>>> I don’t see why this must necessarily be the case.  Annotations such as
>>> you describe below could be taken into account by `deriving`.  `deriving`
>>> is just a way to invoke the synthesis mechanism.
>> 
>> Different people are using it differently I think; I agree with you if it’s
>> just the name of the invocation, but I think at least some people are using
>> it as a shorthand for the “naive” implementation (all fields equatable =>
>> equatable).
>> 
>> That is, I meant "naive deriving” to refer to something like this (quoting
>> Patrick):
>> 
>>> It would fail if not all members were Equatable or Hashable. If it was
>>> automatic, you wouldn’t get any warning or sign at all. If you have to
>>> explicitly conform to the protocols, then your intention is clear, and if
>>> an automatic implementation cannot be made (because not all members were
>>> Equatable or Hashable), then you will get an error that you need to
>>> implement the protocol yourself like you do now (i.e. implement == and
>>> hashValue).
>> 
>> …but I could’ve been clearer!
>> 
>>> 
 
 On the one hand, it’s possible to imagine a finer-grained form of this
 synthesis that’d allow you to e.g. indicate a certain field should be
 omitted (and also perhaps specialize how fields are compared, customize
 the synthesized comparison ordering to put cheaper comparisons earlier,
 and an endless list of other possible requests…).
>>> 
>>> If you don’t trust the compiler to optimize this well and therefore want
>>> control over order of comparisons you should probably just implement it
>>> manually.  As you note below, this is a convenience feature that needs to
>>> strike a fine balance.
>> 
>> I agree, but at the same time i think that scenarios like this:
>> 
>>  struct RevisionInfo {
>>let contentID: NSUUID
>>let revisionID: NSUUID
>>let contentDa

Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 8:50 AM, Thorsten Seitz  wrote:
> 
> 
>>> Am 28.05.2016 um 22:08 schrieb Matthew Johnson :
>>> 
>>> 
>>> On May 28, 2016, at 2:31 PM, Thorsten Seitz via swift-evolution 
>>>  wrote:
>>> 
>>> I’m not happy with that restriction in the proposal:
>>> 
>>> Existentials cannot be used with generics in the following ways:
>>> 
>>> In generic declarations, with the requirements composed out of generic type 
>>> variables:
>>> 
>>> // NOT ALLOWED
>>> func foo(x: A, y: B) -> Any { ... }
>>> 
>>> Why is that not allowed?
>>> 
>>> I would have hoped to be able to write something like
>>> 
>>> func union(x: Set, y: Set) -> Set> { … }
>> 
>> I think what you’re looking for is an anonymous union type `A | B`, not an 
>> existential made of the two of them.  
> 
> Sorry, I of course meant
> 
> func intersection(x: Set, y: Set) -> Set> { … }
> 
> I guess I will forever confuse this until we write existentials with `&`…
> 
> You are right, for the union I want the union type `A | B`. But that is stuff 
> for another proposal.

This makes a lot more sense!  So you want to be able to use uninhabitable types 
in the contexts of things like collection elements (such collections must 
always be empty but are inhabitable by a single empty instance).  It is a great 
example of why it might make sense to allow types like this.  

What you are really asking for is the ability to drop the restriction that only 
a single superclass constraint is allowed and no value type constraints are 
allowed.  It might be useful in cases like your intersection example.  But it 
could also be a source of error confusing error messages when people form such 
a type and it doesn't work the way they expect.  If the type is disallowed as 
under the current proposal the error message might be more straightforward.  
This is a topic that probably deserves further consideration.  But I have to 
say I find your intersection example to be reasonably compelling.

Austin, what do you think about this example?

> 
> -Thorsten
> 
> 
>> 
>> To write this `union` and have it behave in the usual way you need `Any> B>` to be a supertype of `A` and of `B`.  The existential doesn’t actually 
>> do that so it would not be possible for this union function to guarantee the 
>> result would have all of the members of `x` and all the members of `y` the 
>> way that a `union` usually would.  
>> 
>> The anonymous union type `A | B` *is* a supertype of `A` and a supertype of 
>> `B` so you would have no trouble writing this:
>> 
>> func union(x: Set, y: Set) -> Set { … }
>> 
>> And returning the expected result.
>> 
>>> 
>>> 
>>> -Thorsten
>>> 
>>> 
>>> 
>>>> Am 26.05.2016 um 07:53 schrieb Austin Zheng via swift-evolution 
>>>> :
>>>> 
>>>> The inimitable Joe Groff provided me with an outline as to how the design 
>>>> could be improved. I've taken the liberty of rewriting parts of the 
>>>> proposal to account for his advice.
>>>> 
>>>> It turns out the runtime type system is considerably more powerful than I 
>>>> expected. The previous concept in which protocols with associated types' 
>>>> APIs were vended out selectively and using existentials has been discarded.
>>>> 
>>>> Instead, all the associated types that belong to an existential are 
>>>> accessible as 'anonymous' types within the scope of the existential. These 
>>>> anonymous types are not existentials - they are an anonymous 
>>>> representation of whatever concrete type is satisfying the existential's 
>>>> value's underlying type's associated type.
>>>> 
>>>> This is an enormous step up in power - for example, an existential can 
>>>> return a value of one of these anonymous associated types from one 
>>>> function and pass it into another function that takes the same type, 
>>>> maintaining perfect type safety but without ever revealing the actual 
>>>> type. There is no need anymore to limit the APIs exposed to the user, 
>>>> although there may still exist APIs that are semantically useless without 
>>>> additional type information.
>>>> 
>>>> A set of conversions has also been defined. At compile-time 'as' can be 
>>>> used to turn values of these anonymous associated types back int

Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-29 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 29, 2016, at 8:25 AM, Vladimir.S  wrote:
> 
> 
> Should 'deriving' allows us to manually implement protocol requirements? For 
> example
> struct A : deriving Hashable {
>  var hasValue : Int {...}
> }
> 
> Or there should be a compilation error in this case?

This should be an error.  If you want to implement it manually your should use 
the usual conformance declaration syntax.

> 
> Right now I feel that if we can have auto-deriving by using current syntax 
> for protocol conformance - we sholdn't introduce new keyword and new rules 
> for this.

We've already covered the reasons why this is problematic.  It's better to be 
explicit about the request for synthesized conformance.

> The requirement to explicitly conform your type to protocol for auto-deriving 
> is IMO reasonable compromise between separate 'deriving' decoration and 
> implicit derivation(when your type is Hashable without any conformance to 
> protocol, just if each property is Hashable).
> 
>> On 29.05.2016 14:42, Matthew Johnson via swift-evolution wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On May 29, 2016, at 12:28 AM, Patrick Smith > <mailto:pgwsm...@gmail.com>> wrote:
>> 
>>> Yeah I don’t see a problem. It’s the same way that protocol extensions
>>> just work. Think of this automatic synthesis as a really flexible
>>> protocol extension:
>>> 
>>> extension Hashable where Members : Hashable {
>>>  var hashValue : Int {
>>>return self.allMembers.reduce(^) // Or whatever combiner is best
>>>  }
>>> }
>> 
>> Protocol extensions require you to declare conformance before your type
>> receives their implementation and it must be identical for all do
>> conforming types.
>> 
>> You should have to declare conformance to receive Equatable conformance and
>> synthesis.  IMO it makes sense to do that with 'deriving' which makes it
>> clear that you are requesting synthesized rather than manual conformance.
>> 
>>> 
>>> 
>>>> On 29 May 2016, at 1:19 PM, Jon Shier via swift-evolution
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> The problem with this is that it doesn’t differentiate between
>>>>> synthesized and manual conformance.  You won’t get error messages you
>>>>> otherwise would when you intend to supply manual conformance.  It is
>>>>> also less clear to a reader of the code that the default, compiler
>>>>> synthesized implementation is being generated.
>>>> 
>>>> I don’t think it’s reasonable to force the language down the path where
>>>> developers don’t have to be familiar with its features in order to use
>>>> them correctly. If types in Swift were to automatically gain Equatable
>>>> and Hashable conformances whenever they were used by something that
>>>> required them, that would be a core language feature, like type
>>>> inference, that even junior developers in the language would need to
>>>> know. Yet few (though not none) would insist that all types be manually
>>>> declared, despite otherwise not knowing when our type inference goes
>>>> wrong. It’s just a basic feature of the language that anyone using the
>>>> language should know about, otherwise it can bite them in the ass when
>>>> weird compiler errors start popping up.
>>>> Frankly, IMO, this is an obvious case of 80/20 optimization. In the vast
>>>> majority of cases where my types are trivially equatable, I should just
>>>> be able to declare them as such and gain the compiler-synthesized ==. In
>>>> the cases where that’s not possible, the compiler can emit an error. And
>>>> in the cases where I want a custom == implementation I can provide it.
>>>> Requiring a new keyword and not making this feature as simple as
>>>> possible because the rare developer with a custom type who doesn’t want
>>>> the synthesized == they just said they did by declaring Equatable
>>>> conformance is an unnecessary defaulting to the rare case.
>>>> 
>>>> 
>>>> 
>>>> Jon Shier
>>>> ___
>>>> 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
>> 

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


<    5   6   7   8   9   10   11   12   13   14   >