Re: [swift-evolution] [Pitch] Nested types in protocols (and nesting protocols in types)

2016-11-02 Thread Slava Pestov via swift-evolution

> On Nov 2, 2016, at 8:32 AM, Paul Cantrell  wrote:
> 
> 
>> On Oct 24, 2016, at 4:43 PM, Slava Pestov  wrote:
>> 
>> 
>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell  wrote:
>>> 
>>> 
>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>>  wrote:
>>>> 
>>>> However protocols nested inside types and types nested inside protocols is 
>>>> still not supported, because protocols introduce a separate series of 
>>>> issues involving associated types and the ’Self’ type.
>>>> 
>>>> The hard part of getting nested generics right is what to do if a nested 
>>>> type ‘captures’ generic parameters of the outer type. For non-protocol 
>>>> types, the behavior here is pretty straightforward.
>>>> 
>>>> If we allow protocols to be nested inside other types, we have to decide 
>>>> what to do if the protocol ‘closes over’ generic parameters of the outer 
>>>> type. For example,
>>>> 
>>>> struct A {
>>>> protocol P {
>>>>  func requirement() -> T
>>>> }
>>>> }
>>>> 
>>>> Presumably A.P and A.P are distinct types, and A.P has a 
>>>> hidden associated type corresponding to the type parameter ’T’?
>>>> 
>>>> The other case is problematic too — the nested type might refer to an 
>>>> associated type of the outer protocol:
>>>> 
>>>> protocol P {
>>>> associatedtype A
>>>> 
>>>> struct T {
>>>>  var value: A
>>>> }
>>>> }
>>>> 
>>>> Now writing P.T does not make sense, for the same reason that we cannot 
>>>> form an existential of type P.A. We could prohibit references to outer 
>>>> associated types of this form, or we could figure out some way to give it 
>>>> a meaning. If C is a concrete type conforming to P, then certainly C.T 
>>>> makes sense, for instance. Internally, the nested type A.T could have a 
>>>> hidden ‘Self’ generic type parameter, so that writing C.T is really the 
>>>> same as P.T.
>>>> 
>>>> Protocols nested inside protocols also have the same issue.
>>> 
>>> FWIW, in almost all the situations where I’ve wanted to nest types inside 
>>> protocols and generic types, it’s only as a namespacing convenience. Most 
>>> often, it’s an enum type that’s used only by a single method, and having it 
>>> at the top of the module namespace adds clutter.
>>> 
>>> Here’s a real life example pared down. I wish I could do this:
>>> 
>>>  public struct ResponseContentTransformer>> OutputContentType>: ResponseTransformer {
>>> 
>>>public init(onInputTypeMismatch mismatchAction: InputTypeMismatchAction 
>>> = .error) {
>>>  ...
>>>}
>>> 
>>>public enum InputTypeMismatchAction {  // Does not depend on generic 
>>> types above
>>>  case error
>>>  case skip
>>>  case skipIfOutputTypeMatches
>>>}
>>> 
>>>  }
>>> 
>>> InputTypeMismatchAction is tightly associated with 
>>> ResponseContentTransformer, and is confusing as a top-level type.
>>> 
>>> What do you think about providing a “no captures” modifier for nested types 
>>> — like static inner classes in Java? Then Swift could provide the namespace 
>>> nesting I wish for this without having to resolve the trickier type capture 
>>> questions yet.
>>> 
>>> Alternatively, what if (1) outer types aren’t capture unless they’re 
>>> referenced, and (2) nesting is only illegal if there’s a capture? Then my 
>>> code above would compile, as would this:
>>> 
>>>  public struct S {
>>>public enum Foo {
>>>  case yin
>>>  case yang
>>>}
>>>  }
>>> 
>>> …but this wouldn’t:
>>> 
>>>  public struct S {
>>>public enum Foo {
>>>  case yin(thing: T)  // capture of T illegal (for now)
>>>  case yang
>>>}
>>>  }
>>> 
>>> Either of these approaches would allow hygienic namespacing now while 
>>> leaving the door open to outer type capture in the future.
>> 
>> Yeah, this makes sense for a first cut at this feature.
>> 
>> Slava
> 
> Should I take a crack at writing up a proposal for this? Now? After ABI work 
> is done? (Probably the latter “OK if no captures” approach?) Eager to help; 
> don’t want to be in the way.

Just speaking for myself and not the whole team — I think you can submit the 
proposal at any time, we’re unlikely to get around to doing it, if you want to 
take a crack that would be great (again, with ‘no captures’ it’s “trivial”).

Slava

> 
> P
> 

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


Re: [swift-evolution] "with" operator a la O'Caml?

2016-12-25 Thread Slava Pestov via swift-evolution

> On Dec 17, 2016, at 8:40 PM, Andy Chou via swift-evolution 
>  wrote:
> 
> I like that structs are value types in Swift, this encourages the use of 
> immutable data. O'Caml has an operator "with" that allows for copying an 
> existing struct with a change to one field. I looked at Lenses for this 
> functionality and it seems like a lot to digest for something so simple. I 
> also tried to implement this using a constructor, or a function, and it was 
> not obvious how to do so without a lot of code duplication.
> 
> What's I'm looking for is something like this (not necessarily with this 
> syntax):
> 
> struct Person {
>let name: String
>let address: String
>let phone: String
> }
> 
> func f() {
>let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, 
> CA", phone: "1234567")
>let chris = andy.with(name: "Chris")
>let dave = andy.with(address: "50 Townsend St., San Francisco, CA")
> }
> 
> I tried to implement a "with" function like this but default arguments cannot 
> reference properties of self. Same problem trying to do this in a constructor.
> 
> Obviously it's possible to create an entirely new Person specifying the 
> values from an existing Person, but this is very tedious with structures with 
> many properties.
> 
> Anyone taken a look at this before? Any suggestions?
> 
> Andy

What’s the advantage of this over declaring the stored properties of the struct 
‘var’ and then doing this?

var chris = andy
chris.name = “Chris"

Slava

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

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


Re: [swift-evolution] [Pitch] Tweak `Self` and introduce `Current`

2017-01-08 Thread Slava Pestov via swift-evolution

> On Jan 7, 2017, at 10:02 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> True, but there are a few edge cases where Self simply does not work. 
> 
> On classes the return type has the contract to return self.
> Even if we get SE–0068, will Self work in generic context like showed in OP 
> with Current?
> #1 Using value semantics on classes means that the returned instance is a new 
> instance different from self.
> 
> Assume this small protocol:
> 
> // Follow value semantics == immutability
> protocol Cloned : class {
>   func cloned() -> Self
> }
> 
> class A : Cloned {
>  func cloned() -> Self {
>return /* copy of self */ <— ERROR
>  }
> }
> One could workaround the problem and use final, but what if the class meant 
> to be subtypeable? Self simply does not work in this scenario. The only 
> workaround here would be associatedtype T as the return type instead of Self, 
> but is this really what we wanted to describe in our protocol. T could be 
> anything else and we cannot constrain it like: associatedtype T : Self.
> 
> Either a static Self is needed or we need to remove the restriction that on 
> the conforming non-final class we cannot overrider Self with the TypeName, 
> like on any of it’s subtype.
> 
> 

Actually it is possible to construct values of type “Self” inside a class that 
are not “self”. type(of: self) returns a metatype of type Self.Type, which you 
can then invoke required initializers on to get a new instance of type ‘Self’.

> \2# On non-final classes from the generic context something like this 
> following snippet seems to be odd if Self is dynamic.
> 
> // What is the constraint here? `Self` is dynamic.  
> // I might want to cast to `A` where `Self` in this case would be 
> e.g.`NSObject`
> // but the dynamic type of the current instance is `B`.
> // The relationship might look like this: B : A : NSObject
> // `Self` would refer to `B`, but `A` is not a subclass of `B`.
> extension AReallyLongNonFinalClassName {
> func casted() -> T { ... }
> }
> 
> // In contrast the proposed static `Self` as `Current`
> extension AReallyLongNonFinalClassName {
> func casted() -> T { ... }
> }
> 

Using the dynamic “Self” like that would not be allowed even with SE-0068, 
because of implementation constraints — only a static class name can appear in 
a superclass constraint like that, not a type parameter.

Slava

> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 7. Januar 2017 um 18:34:38, Xiaodi Wu (xiaodi...@gmail.com 
> ) schrieb:
> 
>> `Self` _always_ refers to the dynamic type of `self`. It just happens to be 
>> that in the case of structs the dynamic type is the same as the static type. 
>> The idea of having a shorthand for the containing type (spelled #Self or 
>> StaticSelf) was discussed during consideration of SE-0068. The accepted 
>> version of the proposal rejects that idea, having adopted the position that 
>> "You will continue to specify full type names for any other use. Joe Groff 
>> writes, 'I don't think it's all that onerous to have to write ClassName.foo 
>> if that's really what you specifically mean.'"
>> 
>> 
>> On Sat, Jan 7, 2017 at 11:14 AM, thislooksfun via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> I like this idea, however, if I understand the proposal correctly, I think 
>> that the naming would make more sense the other way around. `Self` is, at 
>> least in my head, tied directly and statically to the enclosing type, where 
>> as `Current` sounds more dynamic, and could change from place-to-place.
>> 
>> -thislooksfun (tlf)
>> 
>>> On Jan 7, 2017, at 4:38 AM, Adrian Zubarev via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi Swift community,
>>> 
>>> I’d like to talk to about current Self keyword. If I’m not totally mistaken 
>>> then the current Self has a few meanings:
>>> 
>>> Refer to the current type, or refer to the dynamic type for non-final 
>>> classes inside containing type (SE–0068 - not yet implemented).
>>> For non-final class types use Self as return type on the conforming super 
>>> type (or return an instance of receiver Self).
>>> Let me visualize the behaviors quickly in some short code snippet:
>>> 
>>> protocol Foo {
>>> func foo(_ f: Self) -> Self
>>> }
>>> 
>>> class A : Foo {
>>> // forced to use `A` as parameter type and `Self` as return type
>>> func foo(_ f: A) -> Self { return self }
>>> // Returning `A()` would cause an error: Cannot convert return 
>>> expression of type 'A' to return type 'Self'
>>> func bar() -> A { return A() /* or self */ }
>>> func zoo() -> Self { return /* only */ self }
>>> }
>>> 
>>> class B : A {
>>> // Both is fine `B` or `Self` as the return type
>>> // If `B` is used you can return a different instance like `B()`
>>> // `Self` does only allow `self` to be used here
>>> override func foo(_ f: A) -> B { return self }
>>> }
>>> 
>>> struct

Re: [swift-evolution] Generic Subscripts

2017-01-11 Thread Slava Pestov via swift-evolution

> On Jan 11, 2017, at 10:53 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On Jan 11, 2017, at 12:32 PM, Erica Sadun via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> [Forgot to CC swift-evolution the first time]
> 
> When this came up last, it was seen as more so a bug in the current 
> implementation, rather than an explicit choice. There's no need for a 
> proposal, just a JIRA: 
> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>  
> 
>  
 
 It’s a nontrivial new user-facing feature with new syntax in the language, 
 so it’ll need a proposal. ‘twould be good for the proposal to link to the 
 JIRA ticket.
 
 I’ve only heard positive reactions toward this feature, and it’s something 
 that the standard library could make good use of.
>>> 
>>> +1, this would be clearly great to happen.
>>> 
>>> -Chris
>> 
>> 
>> I apologize for adding to this topic rather than starting a new one, but I 
>> figure people interested in subscripts would be more likely to see my 
>> question:
>> 
>> Is there a good reason subscripts cannot throw? Right now you can create a 
>> [safe: index] subscript to return an optional but you can't create one that 
>> returns an unwrapped value or throws.
> 
> These topics do tend to come up together they are the two unnecessary 
> limitations subscripts have right now.  I hope both make it into Swift 4.  
> I’m sure we’ll see a proposal after phase 2 opens up.

Another limitation is that subscripts cannot have default arguments. I don’t 
believe this even requires an evolution proposal, it’s a quirk of the 
implementation and can be fixed by cleaning up some duplicated code paths in 
SILGen. If anyone is interested in looking at this I can point you to the code 
in question.

Slava

> 
>> 
>> Thanks, -- 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 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-12 Thread Slava Pestov via swift-evolution

> On Jan 12, 2017, at 9:56 AM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> Hello Chris, thanks for this draft!
> 
> May I suggest that the introduction mentions genericity on return type as 
> well?
> 
> subscript(_ index: Int) -> T
> 
> (I have database rows in mind.)

Yeah, there’s no reason to restrict it to either just the index or element type.

Slava

> 
> Gwendal
> 
>> Le 12 janv. 2017 à 18:53, Chris Eidhof via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> Ok, I've got a draft up as a gist: 
>> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
>> 
>> 
>> Before I submit it, could someone let me know if adding generics to 
>> subscripts would influence the ABI? ( still feel pretty clueless in that 
>> area).
>> 
>> Thanks!
>> 
>> On Thu, Jan 12, 2017 at 8:57 AM, Douglas Gregor via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> Sent from my iPhone
>> 
>> On Jan 11, 2017, at 11:05 PM, Chris Eidhof via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> Okay,
>>> 
>>> I agree that throwing subscripts would be great to have. Likewise, 
>>> generic(and maybe even throwing) properties could be useful. However, I 
>>> think that for this proposal, it makes more sense to focus on just generic 
>>> subscripts, and mention throwing subscripts as "future improvements"? 
>> 
>> There's already a draft proposal covering throwing subscripts. You can 
>> mention it's existence, but I don't see a reason to say much. 
>> 
>>  - Doug
>> 
>> 
>>> 
>>> On Wed, Jan 11, 2017 at 8:52 PM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
 On Jan 11, 2017, at 1:32 PM, Erica Sadun via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
> On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>>> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> [Forgot to CC swift-evolution the first time]
>>> 
>>> When this came up last, it was seen as more so a bug in the current 
>>> implementation, rather than an explicit choice. There's no need for a 
>>> proposal, just a JIRA: 
>>> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>>>  
>>> 
>>>  
>> 
>> It’s a nontrivial new user-facing feature with new syntax in the 
>> language, so it’ll need a proposal. ‘twould be good for the proposal to 
>> link to the JIRA ticket.
>> 
>> I’ve only heard positive reactions toward this feature, and it’s 
>> something that the standard library could make good use of.
> 
> +1, this would be clearly great to happen.
> 
> -Chris
 
 
 I apologize for adding to this topic rather than starting a new one, but I 
 figure people interested in subscripts would be more likely to see my 
 question:
 
 Is there a good reason subscripts cannot throw? Right now you can create a 
 [safe: index] subscript to return an optional but you can't create one 
 that returns an unwrapped value or throws.
>>> 
>>> Throwing accessors are mostly straightforward, but there is a big 
>>> conceptual question: what happens if an accessor is called during error 
>>> propagation?  For example:
>>> 
>>>   objectWithThrowingSubscriptSetter[index].mutatingMethodThatCanThrow()
>>> 
>>> If the method throws, we currently still call the setter in order to finish 
>>> the access.  If the setter can throw, then, we might end up with multiple 
>>> errors being thrown at the same time, which isn't good — the language is 
>>> put in the awkward position of having to invent an arbitrary resolution 
>>> mechanism.
>>> 
>>> You might ask: why do we call the setter if an error is thrown?  Well, it's 
>>> complicated.  One reason is that the implementation technique we use for 
>>> generic access to subscripts and properties — accesses where we don't know 
>>> how the subscript/property is implemented — doesn't know how to distinguish 
>>> between *finishing* an access normally and *aborting* an access abnormally. 
>>>  Some kinds of property/subscript implementation — ones currently reserved 
>>> for the standard library, but likely to be eventually offered to users in 
>>> some form — depend on doing extra work no matter how the access is 
>>> terminated, e.g. to release a buffer pointer.  (In fact, in general this 
>>> applies even to get/set implementations, because even if we decided not to 
>>> call the setter when an error was thrown, we would at least need to destroy 
>>> the index argument tha

Re: [swift-evolution] Generic Subscripts

2017-01-12 Thread Slava Pestov via swift-evolution

> On Jan 12, 2017, at 9:53 AM, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Ok, I've got a draft up as a gist: 
> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
> 
> 
> Before I submit it, could someone let me know if adding generics to 
> subscripts would influence the ABI? ( still feel pretty clueless in that 
> area).

It won’t change the ABI of existing subscript calls, but if the standard 
library introduces new generic subscripts that replace older non-generic 
subscripts, it will impact ABI.

Slava

> 
> Thanks!
> 
> On Thu, Jan 12, 2017 at 8:57 AM, Douglas Gregor via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
> Sent from my iPhone
> 
> On Jan 11, 2017, at 11:05 PM, Chris Eidhof via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> Okay,
>> 
>> I agree that throwing subscripts would be great to have. Likewise, 
>> generic(and maybe even throwing) properties could be useful. However, I 
>> think that for this proposal, it makes more sense to focus on just generic 
>> subscripts, and mention throwing subscripts as "future improvements"? 
> 
> There's already a draft proposal covering throwing subscripts. You can 
> mention it's existence, but I don't see a reason to say much. 
> 
>  - Doug
> 
> 
>> 
>> On Wed, Jan 11, 2017 at 8:52 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> On Jan 11, 2017, at 1:32 PM, Erica Sadun via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
 On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
>> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> [Forgot to CC swift-evolution the first time]
>> 
>> When this came up last, it was seen as more so a bug in the current 
>> implementation, rather than an explicit choice. There's no need for a 
>> proposal, just a JIRA: 
>> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>>  
>> 
>>  
> 
> It’s a nontrivial new user-facing feature with new syntax in the 
> language, so it’ll need a proposal. ‘twould be good for the proposal to 
> link to the JIRA ticket.
> 
> I’ve only heard positive reactions toward this feature, and it’s 
> something that the standard library could make good use of.
 
 +1, this would be clearly great to happen.
 
 -Chris
>>> 
>>> 
>>> I apologize for adding to this topic rather than starting a new one, but I 
>>> figure people interested in subscripts would be more likely to see my 
>>> question:
>>> 
>>> Is there a good reason subscripts cannot throw? Right now you can create a 
>>> [safe: index] subscript to return an optional but you can't create one that 
>>> returns an unwrapped value or throws.
>> 
>> Throwing accessors are mostly straightforward, but there is a big conceptual 
>> question: what happens if an accessor is called during error propagation?  
>> For example:
>> 
>>   objectWithThrowingSubscriptSetter[index].mutatingMethodThatCanThrow()
>> 
>> If the method throws, we currently still call the setter in order to finish 
>> the access.  If the setter can throw, then, we might end up with multiple 
>> errors being thrown at the same time, which isn't good — the language is put 
>> in the awkward position of having to invent an arbitrary resolution 
>> mechanism.
>> 
>> You might ask: why do we call the setter if an error is thrown?  Well, it's 
>> complicated.  One reason is that the implementation technique we use for 
>> generic access to subscripts and properties — accesses where we don't know 
>> how the subscript/property is implemented — doesn't know how to distinguish 
>> between *finishing* an access normally and *aborting* an access abnormally.  
>> Some kinds of property/subscript implementation — ones currently reserved 
>> for the standard library, but likely to be eventually offered to users in 
>> some form — depend on doing extra work no matter how the access is 
>> terminated, e.g. to release a buffer pointer.  (In fact, in general this 
>> applies even to get/set implementations, because even if we decided not to 
>> call the setter when an error was thrown, we would at least need to destroy 
>> the index argument that we were going to pass to the setter.)  In order to 
>> get consistent behavior between generic and non-generic accesses, we've just 
>> generally been finishing the access all the time.
>> 
>> I think it would be possible to teach this generic mechanism the difference 
>> between finishing and aborting an access, and thus to avo

Re: [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Slava Pestov via swift-evolution

> On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Another possibility, other than generics, would be to drop rethrows all 
> together and have the compiler infer if a throw is possible or not, including:
> 
> struct FStore {
> let f: () throws -> Void
> func call() throws { try f() }
> }
> 
> The compiler can make two versions, one if f can throw and one if it 
> definitely doesn't. 

It seems that this approach is impractical, because you either have to compile 
two versions of every function, or make all function bodies available for 
inlining, which is a non-starter for a stable ABI.

Slava

> 
> Just a thought. 
> 
> On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch  > wrote:
> Moving to swift-users list.
> 
> No, there's no way to do this today. The point of rethrows is that within one 
> call site, "f(block)" can be treated as throwing if the block throws, or not 
> throwing if the block doesn't throw. In your example, once the FStore object 
> is constructed, the information about the original passed-in function is 
> lost, so the caller has no way to know whether call() can throw or not.
> 
> If this *were* possible, the information would somehow need to be encoded in 
> the type system when creating FStore(f: block). That would require something 
> like dependent typing, or generic-param-based-rethrows, e.g.
> 
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function 
> depends on throws-ness of T
> }
> 
> 
> 
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Hi,
> 
> If I have an escaping function that I store and then call, I need to declare 
> the calling function as throwing, not rethrowing. EG:
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have to 
> use throws
> }
> 
> Is there a better solution?
> 
> Thanks for any suggestions,
> 
>   -- Howard.
> 
> 
> 
> 
> 
> ___
> 
> 
> swift-evolution mailing list
> 
> 
> swift-evolution@swift.org 
> 
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 
> 
> 
> 
> 
> -- 
> -- Howard.
> ___
> 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] Generic Subscripts

2017-01-12 Thread Slava Pestov via swift-evolution

> On Jan 12, 2017, at 7:05 PM, Karl Wagner  wrote:
> 
> 
>> On 12 Jan 2017, at 22:37, Slava Pestov via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Jan 12, 2017, at 9:53 AM, Chris Eidhof via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Ok, I've got a draft up as a gist: 
>>> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
>>> <https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25>
>>> 
>>> Before I submit it, could someone let me know if adding generics to 
>>> subscripts would influence the ABI? ( still feel pretty clueless in that 
>>> area).
>> 
>> It won’t change the ABI of existing subscript calls, but if the standard 
>> library introduces new generic subscripts that replace older non-generic 
>> subscripts, it will impact ABI.
>> 
>> Slava
> 
> Why are subscripts so different, anyway? One would think they are basically 
> sugared functions, but they don’t support so many things that regular 
> functions support. Not just syntax stuff, either - they also don’t support 
> @inline(__always) for some reason…

Nice catch with @inline(__always). Please file a JIRA issue, since I’m actively 
working on this stuff now.

Subscripts are a bit different from ordinary functions because they’re lvalues. 
You can call mutating members on the result of a subscript, or chain it with 
another property access or subscript. So the code path in SILGen is a little 
different than ordinary function calls. This is the reason subscripts cannot 
have default arguments also. With a bit of refactoring we can unify the code 
path for forming call arguments in ordinary calls and subscripts, and hopefully 
the default argument and generic cases will fall out naturally also.

> 
> Where generic subscripts are concerned, there are a couple of different 
> things to express:
> - Generic parameter  (I can understand various co-ordinates for the data)
> - Generic return type (I can construct your preferred representation of the 
> data)
> - Generic setter type (I can set the data using various compatible types):

I think all of these should be expressed with a single generic signature on the 
subscript itself. The element type passed to the setter and returned from the 
getter should be the same IMO, otherwise it’s not clear how it will work.

> 
> protocol MeaningfulToFoo {}
> protocol ConstructableFromFoo {}
> 
> struct Foo {
> subscript(index: Index) where Index: SignedInteger {
> get where T: ConstructableFromFoo { return T(self) }
> set where T: MeaningfulToFoo  { self.someProperty = 
> newValue.someData }
> }
> }
> 
> The syntax looks a bit awkward, though, IMO. I’m wondering if it might be 
> better to have some kind of combined subscript + property behaviours 
> (remember those?) and allow those to be generic instead. Subscripts and 
> properties are very similar anyway - they are both bundles of functions to 
> represent getting and setting data (not just regular-old “get” and “set”, 
> either, but also magic stuff like “mutableAddressWithPinnedNativeOwner”). The 
> only difference is that property getters can’t have parameters — which is 
> something I would also like to see lifted one day (I believe I’ve even seen 
> people asking for “named subscripts” due to the lack of this =P)
> 
> - Karl
> 

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


Re: [swift-evolution] Equatability for enums with associated values

2017-01-13 Thread Slava Pestov via swift-evolution

> On Jan 13, 2017, at 1:15 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> This is a request that comes up frequently; I wrote an early draft proposal 
> for it several months ago, with it covering all value types, not just enums, 
> and also including Hashable as well as Equatable:
> 
> https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
> 
> 
> Since it's purely additive, it won't get much attention until phase 2 at the 
> earliest, but I'd like to revisit it then. Most of the discussion before 
> revolved around to what degree users should have to opt-in or opt-out of this 
> functionality.

I think if someone were to implement this though, we would be happy to merge it 
in. The code for deriving Equatable and Hashable conformances is in these files:

lib/Sema/CodeSynthesis.cpp
lib/Sema/DerivedConformances.cpp
lib/Sema/DerivedConformanceEquatableHashable.cpp

I agree it should be opt-in though (I would also argue that even the no-payload 
enum behavior should be opt-in, but that ship has sailed).

> 
> Re: generics, I don't think there's anything on the roadmap that goes into 
> such deep detail as "if every associated value of every enum case is 
> Equatable, then X is also Equatable", and I don't think there would be a 
> clean way to express that with the generics syntax. This would probably have 
> to be something that's baked into the compiler to synthesize == and hashValue 
> for types that satisfy the constraints.

The generics feature people are thinking of is conditional conformances:

extension Array : Equatable where Element == Equatable { … }

However it does not solve the problem for enums with associated values because 
as you said there’s no way to quantify over ‘all associated values’ in the 
language, and this is not planned.

Slava

> 
> 
> On Fri, Jan 13, 2017 at 12:31 PM David Sweeris via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
> 
> Sent from my iPhone
> On Jan 13, 2017, at 13:51, Adam Shin via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> When using enums with associated values, it's often necessary to check for 
>> equality between two enum objects in some way. That can lead to boilerplate 
>> code like this:
>> 
>> enum Option {
>> case foo(String)
>> case bar(Int)
>>  case zip
>> }
>> 
>> func ==(lhs: Option, rhs: Option) -> Bool {
>> switch (lhs, rhs) {
>> case (.foo(let a), .foo(let b)) where a == b: return true
>> case (.bar(let a), .bar(let b)) where a == b: return true
>> case (.zip, .zip): return true
>> default: return false
>> }
>> }
>> 
>> ..which results in code duplication and opens the door to potential logic 
>> errors.
>> 
>> Instead, what if enums with associated values were automatically Equatable 
>> when all their associated values were Equatable? That would remove the need 
>> for such boilerplate code.
>> 
>> The Swift language guide states that custom classes and structs don't 
>> receive a default implementation of the == operator because the compiler 
>> can't guess what "equality" means for them. However, I think this could make 
>> sense for enums. An enum case, even with associated values, seems closer to 
>> a value itself than an object with logic and state.
>> 
>> I'd be interested to hear any thoughts on this. Would this be a beneficial 
>> addition?
> 
> I think it makes more sense to come up with some syntax for reducing that 
> kind of boilerplate code in general. In "pseudo-english", I'd write the == 
> function as "if lhs and rhs are the same case && their associated values are 
> the equal, return true, else return false".
> 
> What about doing something with the reflection system? Isn't that supposed to 
> get overhauled for Swift 4? I'm not sure what the performance implications 
> would be, though.
> 
> - Dave Sweeris 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Equatability for enums with associated values

2017-01-13 Thread Slava Pestov via swift-evolution

> On Jan 13, 2017, at 12:14 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I think the “when all their associated values were Equatable” is the 
> technical issue holding this type of thing up.  The ability to spell that 
> type of thing is on the generics roadmap, but I don’t know when it will 
> actually happen.  There seem to be a lot of things on hold because of it.

The proposal for conditional conformances was accepted. However, right now the 
generics feature being worked on is recursive conformances, together with a 
large overall cleanup of the generics implementation to fix bugs and improve 
correctness. Conditional conformances will come at some point after that.

Slava

> 
> Thanks,
> Jon
> 
>> On Jan 13, 2017, at 11:51 AM, Adam Shin via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> When using enums with associated values, it's often necessary to check for 
>> equality between two enum objects in some way. That can lead to boilerplate 
>> code like this:
>> 
>> enum Option {
>> case foo(String)
>> case bar(Int)
>>  case zip
>> }
>> 
>> func ==(lhs: Option, rhs: Option) -> Bool {
>> switch (lhs, rhs) {
>> case (.foo(let a), .foo(let b)) where a == b: return true
>> case (.bar(let a), .bar(let b)) where a == b: return true
>> case (.zip, .zip): return true
>> default: return false
>> }
>> }
>> 
>> ..which results in code duplication and opens the door to potential logic 
>> errors.
>> 
>> Instead, what if enums with associated values were automatically Equatable 
>> when all their associated values were Equatable? That would remove the need 
>> for such boilerplate code.
>> 
>> The Swift language guide states that custom classes and structs don't 
>> receive a default implementation of the == operator because the compiler 
>> can't guess what "equality" means for them. However, I think this could make 
>> sense for enums. An enum case, even with associated values, seems closer to 
>> a value itself than an object with logic and state.
>> 
>> I'd be interested to hear any thoughts on this. Would this be a beneficial 
>> addition?
>> ___
>> 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] Equatability for enums with associated values

2017-01-13 Thread Slava Pestov via swift-evolution

> On Jan 13, 2017, at 2:30 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> On Jan 13, 2017, at 15:10, Anton Zhilin via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> That seems pretty close to Rust’s derive. Why not invent a similar syntax in 
>> Swift? Otherwise it will make us look through all the sources to make sure 
>> deriving is used.
>> 
>> enum Option: @derive Equatable {
>> ...
>> }
>> Also, we can get better looking compilation errors, like:
>> 
>> ERROR at line 1, col 14: could not derive Equatable for Option
>> enum Option: @derive Equatable {
>>  ^
> 
> I think that idea came up once before... can't remember where, though, or 
> what we thought of it at the time.
> 
> As far as reducing enum boilerplate, what about borrowing the generic 
> system's syntax and looking at it from the switch's PoV?
> func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
> switch  (lhs, rhs) {
> case (c(let lVal), c(let rVal)): // both lhs and rhs are "c" and the same 
> case
> return lVal == rVal //syntax error if `==` isn't defined for the 
> associated value types of every case
> default: return false
> }
> }

I think initially, we would like to implement deriving these witnesses directly 
in the compiler, instead of trying to come up with a metaprogramming syntax for 
them.

Slava

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

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


Re: [swift-evolution] Will existentials ever conform to their protocols?

2017-01-17 Thread Slava Pestov via swift-evolution

> On Jan 17, 2017, at 9:33 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> On Jan 17, 2017, at 22:30, Braeden Profile via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> Hello Swift Community!
>> 
>> I know that I’ve seen this mentioned before, but what with Enhanced 
>> Existentials being brought up, I think this is worth mentioning now.  What 
>> is the plan regarding letting existentials conform to their protocols?  
>> Currently, in Swift 3, it is impossible to write code like this:
>> protocol Updatable
>>  { func update() }
>> 
>> struct UpdatePool
>>  { /* ... */ }
>> 
>> let heterogenousPool = UpdatePool()
>> Error on the last line:  “Using ‘Updatable’ as a concrete type conforming to 
>> protocol ‘Updatable’ is not supported.”
>> 
>> 
>> Although my most common use case of this behavior has actually been solved 
>> (using ‘AnyObject’ as a concrete type conforming to ‘AnyObject’), I wonder 
>> why this can’t be extended to any protocol existential (a field which is 
>> about to explode, if we succeed in Enhancing them).
>> 
>> What do you guys think?
> 
> +1, but I think there's a compiler limitation preventing it at the moment.

See my recent post: 
https://www.mail-archive.com/swift-users@swift.org/msg03427.html

Slava


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


Re: [swift-evolution] Will existentials ever conform to their protocols?

2017-01-18 Thread Slava Pestov via swift-evolution
Yes, there’s already logic to detect and diagnose this case in fact (@objc 
protocols are self-conforming, except when they contain static members or 
initializers).

Slava

> On Jan 18, 2017, at 12:10 AM, Anton Zhilin via swift-evolution 
>  wrote:
> 
> There is also a caveat with static members:
> 
> protocol P {
> static func foo()
> }
> 
> struct S : P {
> static func foo() { }
> }
> 
> func bar(x: T) {
> T.foo()
> }
> 
> let p = S() as P
> bar(p)  // P.foo() does not exist
> ___
> 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] Nested types in protocols (and nesting protocols in types)

2017-01-18 Thread Slava Pestov via swift-evolution
I left some review comments here:

https://github.com/apple/swift-evolution/commit/ff654e4

Slava

> On Jan 18, 2017, at 12:17 AM, Karl Wagner  wrote:
> 
> 
>> On 18 Jan 2017, at 01:07, Douglas Gregor > <mailto:dgre...@apple.com>> wrote:
>> 
>> 
>>> On Nov 5, 2016, at 2:44 AM, Karl via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> 
>>>> On 2 Nov 2016, at 20:54, Slava Pestov >>> <mailto:spes...@apple.com>> wrote:
>>>> 
>>>>> 
>>>>> On Nov 2, 2016, at 8:32 AM, Paul Cantrell >>>> <mailto:cantr...@pobox.com>> wrote:
>>>>> 
>>>>> 
>>>>>> On Oct 24, 2016, at 4:43 PM, Slava Pestov >>>>> <mailto:spes...@apple.com>> wrote:
>>>>>> 
>>>>>> 
>>>>>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell >>>>>> <mailto:cantr...@pobox.com>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>> 
>>>>>>>> However protocols nested inside types and types nested inside 
>>>>>>>> protocols is still not supported, because protocols introduce a 
>>>>>>>> separate series of issues involving associated types and the ’Self’ 
>>>>>>>> type.
>>>>>>>> 
>>>>>>>> The hard part of getting nested generics right is what to do if a 
>>>>>>>> nested type ‘captures’ generic parameters of the outer type. For 
>>>>>>>> non-protocol types, the behavior here is pretty straightforward.
>>>>>>>> 
>>>>>>>> If we allow protocols to be nested inside other types, we have to 
>>>>>>>> decide what to do if the protocol ‘closes over’ generic parameters of 
>>>>>>>> the outer type. For example,
>>>>>>>> 
>>>>>>>> struct A {
>>>>>>>> protocol P {
>>>>>>>> func requirement() -> T
>>>>>>>> }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> Presumably A.P and A.P are distinct types, and A.P has a 
>>>>>>>> hidden associated type corresponding to the type parameter ’T’?
>>>>>>>> 
>>>>>>>> The other case is problematic too — the nested type might refer to an 
>>>>>>>> associated type of the outer protocol:
>>>>>>>> 
>>>>>>>> protocol P {
>>>>>>>> associatedtype A
>>>>>>>> 
>>>>>>>> struct T {
>>>>>>>> var value: A
>>>>>>>> }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> Now writing P.T does not make sense, for the same reason that we 
>>>>>>>> cannot form an existential of type P.A. We could prohibit references 
>>>>>>>> to outer associated types of this form, or we could figure out some 
>>>>>>>> way to give it a meaning. If C is a concrete type conforming to P, 
>>>>>>>> then certainly C.T makes sense, for instance. Internally, the nested 
>>>>>>>> type A.T could have a hidden ‘Self’ generic type parameter, so that 
>>>>>>>> writing C.T is really the same as P.T.
>>>>>>>> 
>>>>>>>> Protocols nested inside protocols also have the same issue.
>>>>>>> 
>>>>>>> FWIW, in almost all the situations where I’ve wanted to nest types 
>>>>>>> inside protocols and generic types, it’s only as a namespacing 
>>>>>>> convenience. Most often, it’s an enum type that’s used only by a single 
>>>>>>> method, and having it at the top of the module namespace adds clutter.
>>>>>>> 
>>>>>>> Here’s a real life example pared down. I wish I could do this:
>>>>>>> 
>>>>>>> public struct ResponseContentTransformer>>>>>> OutputContentType>: ResponseTransformer {
>>>>>>> 
>>>>>>>   public init(onInputTypeMismatch mismat

Re: [swift-evolution] Swift Evolution Status Page Now Available

2017-01-18 Thread Slava Pestov via swift-evolution
This looks great, thanks!

SE-0080 was recently implemented by a contributor and will be available in 
Swift 4:

https://github.com/apple/swift/pull/4314

Slava

> On Jan 18, 2017, at 2:04 PM, Kyle Murray via swift-evolution 
>  wrote:
> 
> Hi everyone,
> 
> We've just launched a new status page 
>  for keeping track of Swift 
> Evolution proposals. See the announcement in a post on the swift.org blog 
> . 
> 
> A few of the benefits to the new page are:
> Search for proposals by criteria such as the proposal's author or Swift 
> version number.
> See which proposals have implementations in progress via the associated JIRA 
> issues.
> The status of a proposal is read directly from its Markdown source. The 
> separate XML file is no longer needed.
> 
> The status page displays progress and information about proposals as they go 
> through the evolution process. As always, please follow the standard proposal 
> template 
>  to 
> keep to process running efficiently. Formatting your proposal correctly also 
> ensures that it's picked up and displayed correctly on the status page. 
> 
> If you're interested in contributing to the status page's implementation, see 
> the steps for doing so in CONTRIBUTING.md 
> . 
> 
> We're looking forward to your feedback!
> 
> Thanks,
> Kyle
> ___
> 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 Status Page Now Available

2017-01-18 Thread Slava Pestov via swift-evolution
Actually it’s available in swift-3.1-branch also.

Kyle, do you mind updating this, or is there a way we can submit updates?

Slava

> On Jan 18, 2017, at 2:06 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> This looks great, thanks!
> 
> SE-0080 was recently implemented by a contributor and will be available in 
> Swift 4:
> 
> https://github.com/apple/swift/pull/4314 
> <https://github.com/apple/swift/pull/4314>
> 
> Slava
> 
>> On Jan 18, 2017, at 2:04 PM, Kyle Murray via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hi everyone,
>> 
>> We've just launched a new status page 
>> <https://apple.github.io/swift-evolution/> for keeping track of Swift 
>> Evolution proposals. See the announcement in a post on the swift.org blog 
>> <https://swift.org/blog/swift-evolution-status-page/>. 
>> 
>> A few of the benefits to the new page are:
>> Search for proposals by criteria such as the proposal's author or Swift 
>> version number.
>> See which proposals have implementations in progress via the associated JIRA 
>> issues.
>> The status of a proposal is read directly from its Markdown source. The 
>> separate XML file is no longer needed.
>> 
>> The status page displays progress and information about proposals as they go 
>> through the evolution process. As always, please follow the standard 
>> proposal template 
>> <https://github.com/apple/swift-evolution/blob/master/-template.md> to 
>> keep to process running efficiently. Formatting your proposal correctly also 
>> ensures that it's picked up and displayed correctly on the status page. 
>> 
>> If you're interested in contributing to the status page's implementation, 
>> see the steps for doing so in CONTRIBUTING.md 
>> <https://github.com/apple/swift-evolution/blob/master/CONTRIBUTING.md>. 
>> 
>> We're looking forward to your feedback!
>> 
>> Thanks,
>> Kyle
>> ___
>> 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


Re: [swift-evolution] Availability checking of libraries (weak linking?)

2017-01-18 Thread Slava Pestov via swift-evolution
Extending availability to support library versioning would be a great proposal.

You should also take a look at the library evolution proposal, where this 
functionality will be required to implement the resilience model: 
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst

Slava

> On Jan 18, 2017, at 4:24 PM, Swizzlr via swift-evolution 
>  wrote:
> 
> Say I have an awesome type, and I provide some extensions that makes it work 
> really well with a few other packages.
> 
> I don't want to force those packages on my users, but if they have them, I 
> want to extend them with my awesome type/function/whatever convenience.
> 
> What can be done in code and package manager to weakly link (not literally, I 
> just mean have that behaviour) my awesome type with all these other libraries?
> 
> This is a prelude to a pitch, if there isn't a decent alternative.
> 
> Tom
> 
> Sent from my iPhone
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0148 Generic Subscripts

2017-01-19 Thread Slava Pestov via swift-evolution
Can we also add mention that default arguments on subscripts should work as 
well? This will force whoever implements this to do it properly and rip out the 
old RValue-based argument tuple emission that’s only used for subscripts in 
favor the argument emission logic.

Slava

> On Jan 19, 2017, at 1:39 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0148 “Generic Subscripts" begins now and runs through 
> January 24, 2017. The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0148-generic-subscripts.md
>  
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> Proposal link:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0148-generic-subscripts.md
>  
> 
> Reply text
> 
> Other replies
>  What 
> goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
> What is your evaluation of the proposal?
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> Does this proposal fit well with the feel and direction of Swift?
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> More information about the Swift evolution process is available at
> 
> https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> Thank you,
> 
> -Doug
> 
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Closures from methods with default args

2017-01-19 Thread Slava Pestov via swift-evolution

> On Jan 19, 2017, at 9:07 PM, David Sweeris via swift-evolution 
>  wrote:

> It causes other issues, too. For instance, if we have
> protocol Initable { init() }
> And
> struct Foo { init(_ x: Int = 0) {} }
> We're left in an odd situation where `Foo`  can't meaningfully conform to 
> `Initable` because while "init(_: Int = 0)" is not the same as "init()", if 
> you add a "init()" to `Foo`
> you'll get an ambiguous somethingerather error because there's no mechanism 
> for the compiler to know whether you want the actual "0 argument" function or 
> the "1 argument with 1 default value" function.
> 
> Aside from re-architecting the default argument system (which I'm not even 
> sure is possible, let alone a good idea), I think I see couple ways forward 
> for the protocol conformance issue. Both have downsides, though.
> 
> 1) Require any potentially conflicting protocol functions to be in an 
> extension so the compiler knows what's going on, have "Foo()" call the one 
> defined in the type, and use "(Foo as Initable)()" for the protocol version 
> defined in an extension. This could get real confusing real fast if people 
> don't realize there's two functions with, as far as they can tell, the same 
> signature.
> 
> 2) Add default argument support to protocols. The syntax that makes sense to 
> me would be something like
> protocol Bar {
> func baz(_: Int = _)
> }
> On the downside, I suspect this would necessarily add a phantom "Self or 
> associated type requirement" so that the compiler could have a way to get at 
> each implementation's default value. It's not ideal... You'd get an error 
> kinda out of the blue if you tried to use the function non-generically, but 
> at least you couldn't have a function change out from under you.

I think in this specific example, the best solution is to allow init(_ x: Int = 
0) to witness the init() requirement, and have the compiler emit the necessary 
glue in-between so that a call to the init() requirement calls init(_) with the 
appropriate default value. This will address the ‘ambiguous reference’ issue, 
and should not require too much work to implement. I am also inclined to 
believe this is (mostly) a source-compatible change. It also fits in with the 
current default argument model, but Doug Gregor can correct me if I’m wrong.

If anyone is interested, the code for matching protocol requirements to 
witnesses is in lib/Sema/TypeCheckProtocol.cpp, matchWitness() and surrounding 
functions, and the code for emitting a protocol witness thunk (where you would 
actually apply the default arguments) is in lib/SILGen/SILGenPoly.cpp, 
emitProtocolWitness(). It would be a good not-quite-starter-project ;-)

Slava

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


Re: [swift-evolution] Assigning to 'self' in protocol extensions

2017-01-19 Thread Slava Pestov via swift-evolution

> On Jan 19, 2017, at 10:52 PM, rintaro ishizaki via swift-evolution 
>  wrote:
> 
> From the perspective of the caller, I think, this behavior is 
> counterintuitive because we use "reference types" with an expectation: the 
> referencing address would never be changed unless we explicitly replace the 
> object by re-assigning to the variable in call sites, e.g.,
> 
> 

Well, there’s no real difficulty here, other than potential user confusion. The 
‘self’ parameter for a mutating method is passed inout, so this behaves as if 
you called a global function with an inout argument. The difference is of 
course when you pass a non-self inout argument, the compiler requires you to 
use the explicit & syntax at the call site.

Is your proposal to ban calls to such mutating methods on a type that is known 
to be a reference type at compile time altogether? This will create an 
inconsistency between code that operates on concrete types and code that 
operates on generic parameters (in the latter case the compiler of course has 
no way to statically guarantee that the value is not a reference type).

The last time this quirk came up in internal discussions, the thought some of 
us had was that it might be worthwhile to prohibit classes from conforming to 
protocols with mutating requirements altogether. If you think about it, this 
makes some amount of sense — it seems like it would be quite hard to write code 
that can operate on both mutable values and mutable references generically, 
since the latter do not have value semantics:

var x = y
x.mutatingProtocolRequirement()
// did y change too?

However the discussion sort of fizzled out.

Perhaps we can resurrect it as a proposal, but the bar is pretty high for 
removing features at this point, since there’s no actual type soundness issue, 
just possible confusion.

> var ref: Foo = Foo()
> ref = Foo()
>  
> Default
>  implementation for initializers
> 
> Similar to methods, initializers also have this issue:
> 
In the specific case of initializers, my opinion here is the opposite in fact — 
I think assigning to ‘self’ should be permitted in all convenience 
initializers, even initializers defined directly classes, without the protocol 
extension trick. Also, we should lower this more efficiently than we do today, 
without creating a self ‘carcass’ that is allocated and immediately freed, to 
be replaced by the ‘real’ self.

We already have something like this in fact, it’s called ‘factory 
initializers', but it’s not directly exposed through the language. It is 
possible to import a static method or C function as a convenience initializer 
on a type. The Dispatch overlay uses this for example — DispatchQueue.init 
actually calls dispatch_queue_create(), which returns a new instance of the 
type, and not [[OS_dispatch_queue alloc] init] as you would expect if this was 
a vanilla Objective-C class. The code that gets generated here is similar to 
the protocol extension initializer example you show that assigns to ‘self’.

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


Re: [swift-evolution] Swift 3 Generics

2015-12-17 Thread Slava Pestov via swift-evolution

> On Dec 15, 2015, at 8:45 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
>> - nesting (per Slava's email)
>>  - ** Generic types nested inside generic functions
>>  - ** Generic types nested inside generic types
>>  - ** Generic functions nested inside generic functions which capture 
>> values or outer generic types
> 
> I think Slava and I disagree on this one ;)

I think mostly we agree actually. :-) Your list of generics ABI tasks makes 
sense to me.

I don’t have any strong opinions about specific features going in now or later 
to be honest. I think in the long term we will likely end up implementing most 
of the features on Matthew's list, in one form or another. To keep things 
manageable we need to keep simplifying the conceptual model and paying off 
technical debt along the way.

So what I’d like to contribute to this effort is helping brainstorm what 
refactoring work needs to be done, and how to break down into manageable chunks 
since we can’t realistically fix everything. Also, in general I feel we haven’t 
nailed down the full conceptual model for the implementation of generics yet, 
but this is hard to quantify.

> 
> I don't consider this critical for Swift 3. The compiler will greatly improve 
> simply by making this work (because the dumb assumptions that block this 
> feature likely trigger additional bugs), but we don't need to allow it for 
> ABI stability.

I’m just happy now that nested generics don’t crash as much in Sema. It always 
bothered me when forgetting a ‘}’ could make the compiler crash just because 
you accidentally introduced nested generic context. :-)

> I suspect I'll remember other small things, but that's the "big" list... and 
> it's size perhaps illustrates why we need to choose carefully to maintain 
> focus. 

Not ABI obviously, but what are your thoughts of adding a new ‘assoctype’ 
keyword instead of overloading ‘typealias’ in protocols? This has come up 
several times on this list and on Twitter. I’m quite like the idea.

Also, a frequent user request is self-conforming protocols. Personally I have 
mixed feelings about this — the implementation Joe and I came up with would 
require double-dispatching through a per-protocol witness table that opened 
existentials, which creates some conceptual difficulties which may or may not 
be possible to fix with some hacks, eg if T : P and T is bound to P, 
existential erasure of T to P would produce a double-wrapped existential P, 
which would create problems for casts among other things. I haven’t thought 
about if this impacts the ABI or not.

Slava

> 
>   - Doug
> 
> 
>> Thanks,
>> Matthew
>> 
>> 
>> 
>>> On Dec 11, 2015, at 11:24 PM, Douglas Gregor >> > wrote:
>>> 
>>> 
 On Dec 10, 2015, at 3:45 PM, Matthew Johnson via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 One of the stated focus areas for Swift 3 is to complete the generics 
 system.  
 
 How far along is the design for the “complete” generics system?  
>>> 
>>> There’s a loose shared understanding of the pieces we need among the 
>>> compiler and standard library developers that have been co-evolving the 
>>> generics system, but it’s not written down in any single place.
>>> 
 Is there appetite among the core team to involve the community in 
 evaluating planned features or submitting proposals to complement existing 
 plans?
>>> 
>>> Yes, absolutely. I feel like we (the core team) need to articulate our 
>>> vision here—what we feel we need to accomplish (in features, in the 
>>> standard library API, in the implementation) in Swift 3 vs. what we believe 
>>> we can introduce later on, how the pieces all fit together, etc.—to help 
>>> facilitate those discussions.
>>> 
 Also, is there any documentation other than 
 https://github.com/apple/swift/blob/master/docs/Generics.rst 
  describing 
 in detail what the complete vision for the generics system is and what new 
 features will be added in Swift 3 (as well as any generics features that 
 have been decided against for Swift or version 3 specifically)?
>>> 
>>> No, that document is the best overall documentation for the vision of the 
>>> generics system, despite being mostly untouched for more than two years and 
>>> lacking newer features (protocol extensions, anyone?).
>>> 
>>> So, we need to write up a document describing our vision here. It’s going 
>>> to take a little time, both because it’s a nontrivial task and because the 
>>> likely principal authors are also engaged in other large Swift 3 tasks 
>>> (e.g., 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md
>>>  
>>> )
>>> 
>>> - Doug
>>> 
>>> 
>> 
>  __

Re: [swift-evolution] Swift 3 Generics

2015-12-17 Thread Slava Pestov via swift-evolution

> On Dec 17, 2015, at 7:57 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> I’ve been going through some notes and realized I missed a couple of things 
> when I put my list together:
> 
> * access control for extensions declaring protocol conformances 
> * memberwise deriving of protocol implementations
> 
> I also found an example of the “same type constraints” item I mentioned and 
> it is different than discussed so far:
> 
> struct S {}
> extension S where T == U {} // error
> 
> Are you considering any of these for Swift 3?  

I’ve been picking Doug’s brain about this kind of stuff lately.

This one is somewhat similar to a same type requirement making a generic type 
parameter concrete, in the sense that the number of ‘primary archetypes’ 
becomes smaller than the number of generic parameters, which isn’t handled 
everywhere yet. For example, SIL walks the list of primary archetypes in order 
to map a generic type parameter’s depth/index to an archetype in several places.

With ‘secondary archetypes’, things are more flexible so this works:

protocol P { typealias X }
func foo()

However, as Doug explained to me in person today, we’re still not doing a great 
job here. The list of requirements in a generic signature line up with the 
lists of primary and secondary archetypes in a tricky way. Also, type sugar 
allowing us to distinguish T.X from U.X is lost here since both types are 
mapped to the same identical type while building the generic signature, which 
you can imagine leads to poor diagnostics in more complex examples. Instead 
they need to have the same canonical type but still print differently, much 
like (X) and X, or [X] and Array.

Slava

> 
> Access control for extensions declaring protocol conformances seems is the 
> highest priority out of this group IMO.
> 
> Matthew
> 
> 
>> On Dec 15, 2015, at 10:45 PM, Douglas Gregor > > wrote:
>> 
>> Hi Matthew,
>> 
>> Sent from my iPhone
>> 
>> On Dec 15, 2015, at 7:25 PM, Matthew Johnson > > wrote:
>> 
>>> Dmitri, Slava and Doug thank you for taking the time to respond.  I 
>>> apologize for not thanking you sooner.  
>>> 
>>> Since the core team has a loosely shared understanding of the goals but 
>>> hasn't had time to write it down yet I thought it might be helpful if I put 
>>> together a summary of the features that seem to me like obvious candidates 
>>> for completing the current generic system.  If I have missed anything 
>>> significant please point that out. 
>> 
>> This is helpful, thank you!
>> 
>> Lots of comments below. An overarching theme here is that I'm trying to 
>> scope down the list to what we need to achieve ABI stability and an 
>> expressive library  fewer features means we're more likely to succeed with 
>> better quality. 
>> 
>>> I'm placing a "**" next to items that I beleive I have seen mentioned by 
>>> the core team as desired features.  This is based on memory and may be 
>>> innacurate or may be based on desires expressed, but not necessarily pinned 
>>> to the Swift 3 timeline.  
>>> 
>>> I'm hoping the core team might be able to indicate which items are likely 
>>> to be part of the work you're doing on Swift 3, which items you might be 
>>> interested in the community contributing to, and which items are unliekly 
>>> to be considered during the Swift 3 timeframe even with community 
>>> involvement.  This could help interested contributors start thinking about 
>>> what they might be interested in working on while we wait for a more 
>>> complete document describing the vision.
>>> 
>>> - ** generic typealias
>> 
>> This isn't high on my list. It's a good feature, and I want it someday, but 
>> introducing generic typealiases won't have any impact on the ABI and 
>> therefore can wait IMO. 
>> 
>>> 
>>> - allow protocols to specify a non-covarying Self in static method 
>>> declarations (a possible solution to the problem of conforming non-final 
>>> classes in Cocoa to protocols containing factory methods)
>> 
>> Maybe. This isn't terribly high on my list, but in also behind on the 
>> discussion. 
>>> 
>>> - extensions
>>> - ** allow same type constraints
>> 
>> I'm assuming you mean an extension like 
>> 
>>   extension Array where Element == String  {}
>> 
>> Yes, it's something we want to support 
>> 
>>> - ** allow protocol conformance in constrained extensions
>> 
>> This is something like:
>> 
>>   extension Array : Equatable where Element : Equatable {}
>> 
>> It is very very high priority for Swift 3.
>> 
>>> - allow protocol conformance in protocol extensions
>> 
>> This is something like:
>> 
>>   extension CollectionType : Equatable where Generator.Element : Equatable {}
>> 
>> This is probably not a priority for Swift 3. It seems very cool, and I've 
>> advocated for similar features in the past (in more static generics 
>> systems), but the potential for ambiguities with such definitions is very 
>> high and the r

Re: [swift-evolution] Bool vs. Optional

2015-12-17 Thread Slava Pestov via swift-evolution

> On Dec 17, 2015, at 11:01 AM, Pyry Jahkola via swift-evolution 
>  wrote:
> (Possibly related to this is that Bool is a struct and not an enum in Swift.)

This is an artifact of the current implementation more than anything. IIRC 
there are missed optimization opportunities with an enum implementation, but 
the goal is to move to that.

Slava

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


Re: [swift-evolution] Proposal: Add syntactic sugar for iterating over an Optional

2015-12-18 Thread Slava Pestov via swift-evolution

> On Dec 16, 2015, at 6:17 AM, Marco Masser via swift-evolution 
>  wrote:
> 
> In Objective-C, I liked that fast enumeration over an NSArray that was nil 
> and one that was empty could be handled with the exact same code:
> 
> NSArray *strings = nil;
> for (NSString *string in strings) {
> …
> }

One thing we've discussed is adding attributes to import nil values of NSArray 
and such as empty arrays in Swift, rather than optionals of arrays. Would this 
solve your problem? Where are these optional arrays coming from in the first 
place, is it imported Cocoa APIs?

> Handling a sequence that is empty or one that is nil is often the same, at 
> least in my experience. Granted, this points to an API that could be improved 
> to return empty sequences instead of nil in many cases, but that is not 
> always in one’s control. For example in AppKit, NSView’s subviews property is 
> declared as [NSView], while NSWindow’s childWindows property is [NSWindow]?, 
> an optional Array.

Yeah, exactly. We want to be able to fix this.

> Also, this is not a proposal to make the Optional type conform to 
> SequenceType as was also discussed previously. If that were to be 
> implemented, my proposal would be pointless, but you’d lose the distinction 
> between iterating over an Optional and a SequenceType. 
> Therefore, I’d prefer a specialized syntax to make a clear distinction 
> between iterating over a SequenceType and an Optional.

Actually it depends on how the conformance was defined. If Optional was a 
sequence iff T is a sequence, then yes it supersedes your proposal. Another way 
to imagine Optional as a sequence is to make it a zero- or one-element 
sequence, depending on if it is None or Some, respectively. I'm not sure which, 
if either, is more useful.

> 
> Cheers,
> 
> Marco
> 
> ___
> 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@swift.org

2015-12-18 Thread Slava Pestov via swift-evolution

> On Dec 18, 2015, at 5:23 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> For Swift 3, we're planning to phase out 'var' parameters in functions, and 
> we're also making it so that language keywords are valid argument labels. 
> With both of these changes pending, I have a hard time not reading:
> 
> func foo(inout x: Int)
> 
> as an argument labeled `inout` instead of an unlabeled argument bound to `x`. 
> Once `var` is phased out, `inout` would also be the only remaining case where 
> quoting is necessary to use a name as an argument label. The `inout` keyword 
> has always struck me as weird, since it violates definition-follows-use—maybe 
> we should replace it with the `&` sigil, mirroring its usage in call sites.

what about @inout?

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

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


swift-evolution@swift.org

2015-12-18 Thread Slava Pestov via swift-evolution

> On Dec 18, 2015, at 5:30 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Dec 18, 2015, at 5:27 PM, Matthew Johnson  wrote:
>> 
>> +1.  Can you provide an example showing where you would place it though?
> 
> Good question. Three options I see:
> 
> - Before the label and binding names, where inout appears today, and where 
> other argument modifiers like `@autoclosure` go: func foo(&label x: Int)
> 
> which is the minimal change.
> 
> - Before the binding name: func foo(label &x: Int)
> 
> which is problematic for implicitly-labeled arguments.
> 
> - Before the type name: func foo(label x: &Int)
> 
> This is the most definition-follows-use-y, but would be inconsistent with 
> other argument modifiers.

It seems the latter is the only one of the three that would also make sense for 
function types. We still need to be able to write down a function type 
containing an inout parameter right?

Also your ideas for lenses involved inout return types — how would these fit in?

> 
> -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] Abstract methods

2017-11-02 Thread Slava Pestov via swift-evolution
Abstract methods and classes seem like they will introduce a fair amount of 
complexity in the type checker, particularly around metatypes and constructors, 
because now we have this new concept of a class that cannot be directly 
instantiated. I’m not sure the cost is worth the benefit.

Slava

> On Nov 2, 2017, at 12:45 PM, C. Keith Ray via swift-evolution 
>  wrote:
> 
> How many "subclass must override" assertions or comments in base class 
> methods do we need to see, to want to add "abstract" to the Swift language? 
> 5? 50? 500?
> 
> It's a not uncommon idiom in Objective-C.
> 
> I'm about to port a substantial amount of C++ code to swift, and compiler 
> help to enforce abstract classes would be very useful.
> 
> 
> --
> C. Keith Ray
> Senior Software Engineer / Trainer / Agile Coach
> * http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf 
> 
> 
> 
> 
> ___
> 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] Extending trailing closure sugar similar to property accessors

2017-11-02 Thread Slava Pestov via swift-evolution


> On Nov 2, 2017, at 4:04 PM, Eric Summers via swift-evolution 
>  wrote:
> 
> // A sugar similar to property accessors for multiple trailing closures:
> foobar(a: 1, b: 2) {
> completionBlock { x, y in
> // ...
> }
> failureBlock { i, j in
> // ...
> }
> }

This syntax is ambiguous. Are you passing in two trailing closures to foobar(), 
or a single trailing closure, inside which you call two top-level functions, 
completionBlock and failureBlock?

Slava

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


Re: [swift-evolution] Extending trailing closure sugar similar to property accessors

2017-11-02 Thread Slava Pestov via swift-evolution


> On Nov 2, 2017, at 5:58 PM, Eric Summers  wrote:
> 
> A similar problem exists with property accessors.  Although you could call 
> those keywords, they will probably be extensible when behaviors are 
> introduced leading to a similar situation.  It can be worked around by making 
> the priority of argument labels higher then function calls within the curly 
> brackets.

This is not possible in general, since we want the parser to be able to parse 
code without having knowledge of declarations and their types (which might come 
from other modules). Overloaded declarations complicate this further.

I agree that the existing property syntax already has this issue, which is 
unfortunate, but we should not introduce features that make the problem worse.

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


Re: [swift-evolution] Abstract methods

2017-11-03 Thread Slava Pestov via swift-evolution


> On Nov 2, 2017, at 8:29 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Nov 2, 2017, at 1:57 PM, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Swift architectures use much less inheritance (and class types) in general 
>> than equivalent c++ architectures. personally i have never been in a 
>> situation where i didn’t need a pure abstract method that was better 
>> declared as a protocol requirement.
> 
> 
> I think we should beef up protocols a little bit so that they can serve the 
> role of abstract classes. That would make for a nice, clean separation: 
> anything abstract is a protocol, while anything concrete is a class (or 
> struct or enum).
> 
> What would protocols need in order to support everything abstract classes can 
> do? First, we'd probably need to extend class constraints to allow a protocol 
> to require you to subclass a given base class:
> 
>   // Hypothetical replacement for UIControl.
>   protocol UIControl: UIView {
>   func sendAction(_ action: Selector, to target: Any?, for event: 
> UIEvent)
>   }

This is planned, and in fact was part of the “subclass existentials” proposal 
that was otherwise implemented in Swift 4. The absence of this feature should 
be considered a bug, and something I’d like to fix eventually.

> Maybe allow them to declare automatically-added storage, perhaps even private 
> to the protocol:

I’m not sure this really fits with the conceptual model of what a protocol is. 
Protocols define requirements, they don’t “add” things to the conforming type. 
It seems that allowing protocols to declare stored properties would bring many 
of the complications of multiple inheritance from an implementation standpoint. 
Also how would retroactive conformance work? Would you just be able to change 
the size of any public type in any other framework? This would have major 
implications for code generation and the optimizer.

In general I’m not convinced this is a useful feature.

> Probably something like `super` for when you want to override a default 
> implementation but still call it:

This is a good idea. I think it would be pretty straightforward to implement, 
and it’s something that keeps coming up. We haven’t come up with a nice 
unambiguous syntax for it yet.

Slava

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


Re: [swift-evolution] Proposal: Allow operators to have parameters with default values

2017-11-03 Thread Slava Pestov via swift-evolution


> On Nov 3, 2017, at 9:16 PM, Swift via swift-evolution 
>  wrote:
> 
> It’s possible I missed something, but my attempt at implementing it only 
> touched 3 files. One was the actual implementation, another was adapting the 
> diagnostics messages, and the third was the tests. 
> 
> I’m still new to building swift myself, but the tests all passed...
> 
> https://github.com/davedelong/swift/commit/c65c634a59b63add0dc9df1ac8803e9d70bfa697
>  
> 
If you’re looking to move forward with this proposal, you should also add a 
SILGen test, and an executable test too.

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


Re: [swift-evolution] Proposal: Allow operators to have parameters with default values

2017-11-03 Thread Slava Pestov via swift-evolution


> On Nov 3, 2017, at 8:40 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> That’s cool, but a hygienic macro system isn’t anywhere on the Swift roadmap.
> 
> Chris has mentioned in interviews that such a system is "a big feature that’s 
> open-ended and requires a huge design process” which makes off-the-table for 
> Swift 5, and (I’m guessing) unlikely for Swift 6 too.
> 
> Personally I’d like to be able to better debug my apps in Swift 4.1 rather 
> than waiting another 2 or 3 years for a magical macro system to somehow solve 
> this.

Heh. I sort of feel that adding procedural macros to a language with a complex 
syntax and semantics like Swift doesn’t make much sense at all. I would be 
pretty strongly opposed to any macro system proposal unless a compelling case 
could be made that it would improve implementation quality by significantly 
simplifying the code (for example, by moving parts of the type checker into the 
standard library).

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


Re: [swift-evolution] Abstract methods

2017-11-04 Thread Slava Pestov via swift-evolution


> On Nov 4, 2017, at 1:32 AM, Goffredo Marocchi  wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On 4 Nov 2017, at 05:26, Slava Pestov via swift-evolution 
>>  wrote:
>> 
>> Protocols define requirements, they don’t “add” things to the conforming type
> 
> I agree with this, but then this warrants a change for protocol extensions 
> too. Would you be happy with the restriction that default method 
> implementations are only available for value types and not for classes (as 
> structs cannot share code any other way, it is the argument for that I seem 
> to recall)?

Protocol extensions are in some sense just syntax sugar for defining new 
functions. Having a protocol conformance add storage to the conforming type is 
fundamentally different.

Slava

> 
> 

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


Re: [swift-evolution] Abstract methods

2017-11-05 Thread Slava Pestov via swift-evolution
At least SR-103 is a legitimate bug that we would like to fix one day.

Slava

> On Nov 5, 2017, at 1:27 AM, Goffredo Marocchi  wrote:
> 
> I would say that you kind of already entered a slippery slope when the 
> extension to a protocol can add code / not just declare a behavioural 
> contract and how it changes OOP approach (hence: 
> https://bugs.swift.org/plugins/servlet/mobile#issue/SR-302 
> <https://bugs.swift.org/plugins/servlet/mobile#issue/SR-302>  and 
> https://bugs.swift.org/browse/SR-103 <https://bugs.swift.org/browse/SR-103>  
> and  https://bugs.swift.org/plugins/servlet/mobile#issue/SR-584 
> <https://bugs.swift.org/plugins/servlet/mobile#issue/SR-584>)
> 
> References:
> https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future 
> <https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future> 
> https://www.raizlabs.com/dev/2016/12/swift-method-dispatch 
> <https://www.raizlabs.com/dev/2016/12/swift-method-dispatch/>
> 
> Sent from my iPhone
> 
> On 5 Nov 2017, at 01:08, Slava Pestov  <mailto:spes...@apple.com>> wrote:
> 
>> 
>> 
>>> On Nov 4, 2017, at 1:32 AM, Goffredo Marocchi >> <mailto:pana...@gmail.com>> wrote:
>>> 
>>> 
>>> 
>>> Sent from my iPhone
>>> 
>>>> On 4 Nov 2017, at 05:26, Slava Pestov via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Protocols define requirements, they don’t “add” things to the conforming 
>>>> type
>>> 
>>> I agree with this, but then this warrants a change for protocol extensions 
>>> too. Would you be happy with the restriction that default method 
>>> implementations are only available for value types and not for classes (as 
>>> structs cannot share code any other way, it is the argument for that I seem 
>>> to recall)?
>> 
>> Protocol extensions are in some sense just syntax sugar for defining new 
>> functions. Having a protocol conformance add storage to the conforming type 
>> is fundamentally different.
>> 
>> Slava
>> 
>>> 
>>> 
>> 

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


[swift-evolution] Pitch: Remove default initialization of optional bindings

2017-11-06 Thread Slava Pestov via swift-evolution
Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional!) 
always have a default value of ‘nil’. This feature increases the surface area 
of the language for no good reason, and I would like to deprecate it in 
-swift-version 5 with a short proposal. Does anyone feel strongly about giving 
it up? I suspect most Swift users don’t even know it exists.

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


Re: [swift-evolution] Pitch: Remove default initialization of optional bindings

2017-11-06 Thread Slava Pestov via swift-evolution
It sounds like several people rely on this behavior and are actually aware that 
it exists, so I won’t pursue the issue further.

Thanks for the feedback!

> On Nov 6, 2017, at 3:07 PM, Alejandro Martinez  wrote:
> 
> I won’t complain a lot if it’s decided to be removed but I would prefer it to 
> stay. I use it constantly.
> 
> Sent from my iPad
> 
>> On 6 Nov 2017, at 22:41, Jon Shier via swift-evolution 
>>  wrote:
>> 
>>   I use this on all of my mutable optional properties, when I have to use 
>> them. It’s just that little extra bit of code I don’t need to write, and it 
>> feels a lot like parameter defaults in use. By surface area, I assume you 
>> mean the fact that it’s an implicit behavior people may need to remember? As 
>> something like that, this seems like a very small one. As for users knowing 
>> about it, I’m guessing it falls into one of those things that people just 
>> never explicitly notice but would likely have a huge impact on anyone with 
>> lots of mutable optionals. Developers from other languages may also assume 
>> this behavior, since it replicates the “nil by default” behavior seen in 
>> other languages. 
>>   Ultimately, while I won’t feel this deeply, since I tend to view mutable 
>> optionals as poor practice in Swift, it’s a nice little convenience that 
>> will likely impact everyone using mutable optionals. If you really want to 
>> find out, perhaps run it agains the compatibility suite?
>> 
>> 
>> Jon
>> 
>>> On Nov 6, 2017, at 5:33 PM, Slava Pestov via swift-evolution 
>>>  wrote:
>>> 
>>> Hi all,
>>> 
>>> Right now, the following two declarations are equivalent:
>>> 
>>> struct S {
>>> var x: Int?
>>> }
>>> 
>>> struct S {
>>> var x: Int? = nil
>>> }
>>> 
>>> That is, mutable bindings of sugared optional type (but not Optional!) 
>>> always have a default value of ‘nil’. This feature increases the surface 
>>> area of the language for no good reason, and I would like to deprecate it 
>>> in -swift-version 5 with a short proposal. Does anyone feel strongly about 
>>> giving it up? I suspect most Swift users don’t even know it exists.
>>> 
>>> Slava
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Pitch: Remove default initialization of optional bindings

2017-11-06 Thread Slava Pestov via swift-evolution


> On Nov 6, 2017, at 4:29 PM, Kelvin Ma  wrote:
> 
> hot take: i use the second one a lot but only because i always forget the 
> first one exists. So I type the = nil just to “be sure”.

Yeah, that’s one of my arguments against having the feature, along with the 
simple fact that if the language did not have it already, nobody would be 
requesting this to be added as a special case for optionals.

However, since I also want to avoid needless source compatibility churn, I’m 
fine with keeping the feature — it’s not a huge burden to maintain (unlike, 
say, AnyObject dispatch :) )

Slava

> 
> On Mon, Nov 6, 2017 at 4:33 PM, Slava Pestov via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Hi all,
> 
> Right now, the following two declarations are equivalent:
> 
> struct S {
>   var x: Int?
> }
> 
> struct S {
>   var x: Int? = nil
> }
> 
> That is, mutable bindings of sugared optional type (but not Optional!) 
> always have a default value of ‘nil’. This feature increases the surface area 
> of the language for no good reason, and I would like to deprecate it in 
> -swift-version 5 with a short proposal. Does anyone feel strongly about 
> giving it up? I suspect most Swift users don’t even know it exists.
> 
> Slava
> ___
> 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: Remove default initialization of optional bindings

2017-11-08 Thread Slava Pestov via swift-evolution


> On Nov 7, 2017, at 11:22 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Not a big deal either way, but I prefer the 2nd (nil) form and therefore 
> would like to see the 1st form go. It would make Swift more consistent, 
> consider:
> 
> let o: Int? // Looks like nil is assigned.
> if someTest {
> o = 1 // Why isn't this an error? (OK I know why - but it looks odd.)
> } else {
> o = nil
> }
> 
> 
> Whilst the above works it is weird because if you are aware that o: Int? 
> normally assigns nil then the above looks like o, which is a let, is assigned 
> to twice. If you do the equivalent of the above for a non-optional it is an 
> error.

The default initialization behavior is specifically not enabled for let 
bindings. Compare:

let x: Int?
print(x as Any) // error: constant 'x' used before being initialized

var y: Int?
print(y as Any)

So your example is perfectly consistent, because you’re only initializing ‘o’ 
once (along each control flow path).

Slava

> 
>   -- Howard.
> 
> On 8 November 2017 at 07:54, Adrian Zubarev via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Same here, but I wouldn’t care much if it were gone.
> 
> 
> Am 7. November 2017 um 21:40:56, David Hart via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> Yeah, I use the first form constantly.
>> 
>> > On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution 
>> > mailto:swift-evolution@swift.org>> wrote:
>> > 
>> > Hi all,
>> > 
>> > Right now, the following two declarations are equivalent:
>> > 
>> > struct S {
>> > var x: Int?
>> > }
>> > 
>> > struct S {
>> > var x: Int? = nil
>> > }
>> > 
>> > That is, mutable bindings of sugared optional type (but not Optional!) 
>> > always have a default value of ‘nil’. This feature increases the surface 
>> > area of the language for no good reason, and I would like to deprecate it 
>> > in -swift-version 5 with a short proposal. Does anyone feel strongly about 
>> > giving it up? I suspect most Swift users don’t even know it exists.
>> > 
>> > Slava
>> > ___
>> > 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

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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-10 Thread Slava Pestov via swift-evolution
Hi Chris,

> On Nov 10, 2017, at 9:37 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello all,
> 
> I have a couple of proposals cooking in a quest to make Swift interoperate 
> with dynamically typed languages like Python better.  Instead of baking in 
> hard coded support for one language or the other, I’m preferring to add a few 
> small but general purpose capabilities to Swift.  This is the first, which 
> allows a Swift type to become “callable”.

I’m generally in favor of adding new features if they simplify the language 
model or subsume existing special cases, either moving them into the standard 
library or simplifying their implementation. However this proposal looks like a 
strictly additive feature, which introduces yet another kind of callable thing. 
We already have:

- Statically dispatched functions
- VTable-dispatched class methods
- Witness table dispatched protocol methods
- ObjC methods
- Dynamic method dispatch on AnyObject
- Enum case constructors
- Curried functions and various thunks, etc

I don’t see the new dynamic callable you are proposing replacing or 
generalizing any of the above, it will simply be a whole new code path.

This all comes at a great cost. If you look at the implementation of calls in 
lib/SILGen/SILGenApply.cpp you will see there is a great deal of complexity 
there to deal with all the different special cases. The type checker also has a 
lot of complexity related to method calls and member accesses.

I would be against adding yet another new type of call to the language at this 
point. Even if the implementation is relatively small it is yet another special 
case we have to maintain forever.

> Swift is well known for being exceptional at interworking with existing C and 
> Objective-C APIs, but its support for calling APIs written in scripting 
> langauges like Python, Perl, and Ruby is quite lacking. These languages 
> provide an extremely dynamic programming model where almost everything is 
> discovered at runtime.

Most other statically compiled languages don’t attempt to solve this problem of 
interoperating with Python and Ruby either. I’m not sure this is a feature 
users expect or one that should be prioritized, given all the other work that 
remains in the implementation that will actually improve the day to day 
experience of developers.

> We propose introducing this protocol to the standard library:
> 
> protocol DynamicCallable {
>   associatedtype DynamicCallableArgument
>   associatedtype DynamicCallableResult
> 
>   func dynamicCall(arguments: [(String, DynamicCallableArgument)]) throws -> 
> DynamicCallableResult
> }
This is not really very general at all, because it assumes all arguments have 
the same type, along with all results. Why would arguments and results have 
different types if they’re type erased anyway? And why are string keyword names 
privileged in any way? What about varargs, inout parameters and other 
Swift-specific modifiers on calls?


> Before this proposal, the Swift language has two types that participate in 
> call syntax: functions and metatypes (for initialization). Neither of those 
> may conform to protocols at the moment, so this introduces no possible 
> ambiguity into the language.
> 
> 

However, it rules out a possible type checker optimization — currently we can 
assume that if a type variable is the subject of both a conformance constraint 
and an apply constraint, the constraint system is invalid. With your change we 
could not make this assumption anymore.

> It is worth noting that this does not introduce the ability to provide 
> dynamicly callable static/class members. We don't believe that this is 
> important given the goal of supporting dynamic languages like Python, but if 
> there is a usecase discovered in the future, it could be explored as future 
> work. Such future work should keep in mind that call syntax on metatypes is 
> already meaningful, and that ambiguity would have to be resolved somehow.
> 
> 

This is the problem with this proposal — it solves a very narrow use case, but 
it introduces a piece of ABI that we have to maintain forever. When future 
generalizations are discovered, we will have to add yet another mechanism, 
complicating the language model further.
>  
> Effect on ABI stability
> 
> This is a strictly additive proposal with no ABI breaking changes.
> 
> 

However, it adds *new* ABI which we will have to maintain forever.

A strong -1 from me here.

Slava

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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-10 Thread Slava Pestov via swift-evolution


> On Nov 10, 2017, at 6:01 PM, Chris Lattner  wrote:
> 
> It is.  It is strictly sugar, as mentioned in the proposal.

All new code has a cost.

> I do not expect any SIL or IRGen changes associated with this proposal, just 
> type checker changes.  The type checker changes should be straight-forward, 
> but you can evaluate that when there is a patch.

Like I said, the type checker’s code for solving member constraints and 
applying the solution is already a rats-nest of special cases to deal with the 
rich semantics of method calls in Swift. We’ve been trying to simplify it over 
time and fix bugs, and adding new special cases is a step in the wrong 
direction.

> Our goal is for Swift to be awesome, not comparable to “other statically 
> typed languages”.

Ok, but being awesome is not the same as adding every possible feature to the 
language.

> swift-evolution isn’t about priorities.  I’m not asking someone else to 
> implement this, and you don’t tell me how I spend my engineering time :-) :-)

Again, my point here is that implementing a new feature is just the first step. 
New code also has to be maintained going forward.

> I’m open to requiring these to be the same type if there is a benefit to 
> doing so. What benefit do you see?

Can you think of a case where they have to be different?

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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-10 Thread Slava Pestov via swift-evolution


> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> Setting this aside, I’m very curious to hear whether type providers influence 
> your thinking after you’ve had a chance to look into them.  I have always 
> thought they were very cool.

I’m in favor of solving this problem with something like type providers also. 
The required compiler changes would be significant but would also clean up the 
interface between the ClangImporter, Sema and Serialization. If done right it 
would be a net gain that would benefit all users, instead of just adding 
YetAnotherCornerCase™ that makes implementation maintainers curse and scream.

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


Re: [swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Slava Pestov via swift-evolution
Yeah, this is an unfortunate wart. Right now unqualified lookup starts at the 
innermost scope and stops when it finds a candidate which matches the name 
being looked up. Overload sets are only formed if there are multiple candidates 
inside the same scope, not in different scopes.

It would be nice to fix this but note that it might have a compile-time 
performance impact, because now we will be looking up names in more scopes. In 
particular, this means almost every name lookup will have to look at all 
imported modules.

If this can be implemented in a clever way without impacting compile time, I’ll 
be all for this change.

However, note that the most common way in which people hit this is with 
type(of:) vs a local name named type — I think this can be solved without 
fundamentally changing unqualified lookup, by having unqualified lookup look at 
the DeclName rather than an Identifier. So if you have

var type = …

type(of: foo)

We would not consider the ‘var type’ at all, since it doesn’t match the 
DeclName type(of:). This might also address min vs Collection.min if we 
consider the number of arguments when performing the lookup too.

Either way I think an evolution proposal is a good idea, this has source 
compatibility impact since it can introduce ambiguity at call sites that were 
formerly unambiguous. But we should be careful not to impact compile time.

Slava

> On Nov 12, 2017, at 5:12 PM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
> I brought this up on Swift Dev and was told to check on Swift Evolution to 
> see if a proposal is needed.
> 
> Currently, the following code produces a compiler error:
> 
> func foo(_ x: Int, _ y: Int) -> Int {
>   return x + y
> }
> 
> extension Int {
>   func foo() -> Int {
> return foo(self, self)// Error here
>   }
> }
> 
> Notice that the two functions named “foo” have entirely different signatures. 
> The global function takes 2 arguments, while the member function takes 0 (or 
> 1, if referenced as “Int.foo”).
> 
> There is exactly one function “foo” which takes 2 arguments, so a call to 
> “foo” with 2 arguments, like the one shown, should be unambiguous. However, 
> instead of calling the function with matching signature, there is instead a 
> compiler error.
> 
> This is already documented as SR–2450 
> , with an example from the standard 
> library (global 2-argument “min” vs. 0-argument “Collection.min”).
> 
> It appears that in any situation where a global function and a member 
> function share the same base name, but only the global function’s signature 
> matches the call site, the result is a compiler error.
> 
> I suggest that, when there is exactly one function available with the proper 
> name and signature, instead of a compiler error the matching function should 
> be called.
> 
> Do we need a Swift Evolution proposal for this change?
> 
> Nevin
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Slava Pestov via swift-evolution


> On Nov 12, 2017, at 7:14 PM, Nevin Brackett-Rozinsky 
>  wrote:
> 
> On Sun, Nov 12, 2017 at 8:44 PM, Slava Pestov  > wrote:
> Yeah, this is an unfortunate wart. Right now unqualified lookup starts at the 
> innermost scope and stops when it finds a candidate which matches the name 
> being looked up. Overload sets are only formed if there are multiple 
> candidates inside the same scope, not in different scopes.
> 
> It would be nice to fix this but note that it might have a compile-time 
> performance impact, because now we will be looking up names in more scopes. 
> In particular, this means almost every name lookup will have to look at all 
> imported modules.
> 
> Well, the fact that it currently gives a different error message if you 
> delete the global function, tells me that *something* in the compiler is 
> already looking at both the member function and the global function.

Yeah, if we fail to solve the constraint system with the innermost candidate as 
the choice of overload, the diagnostics pass performs an additional name lookup 
to try to figure out what the user meant. However this doesn’t mean we’re 
performing the global lookup in the normal path.

> Pardon my lack of imagination, but could you provide an example of a call 
> site that would become ambiguous?

protocol P {}
protocol Q {}
struct S : P, Q {}

struct Outer {
  static func foo(_: P) {}

  struct Inner {
static func foo(_: Q) {}

static func bar() {
   foo(S())
}
  }
}

Slava

> 
> The change I am proposing has the effect of taking something that is 
> currently a compiler error (calling a global function when a member function 
> has the same base name but a different signature) and making it not-an-error 
> (since the global function is the only one whose signature matches the call 
> site).
> 
> Nevin

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


Re: [swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Slava Pestov via swift-evolution


> On Nov 12, 2017, at 7:27 PM, Nevin Brackett-Rozinsky 
>  wrote:
> 
> On Sun, Nov 12, 2017 at 10:16 PM, Slava Pestov  > wrote:
>> Pardon my lack of imagination, but could you provide an example of a call 
>> site that would become ambiguous?
> 
> protocol P {}
> protocol Q {}
> struct S : P, Q {}
> 
> struct Outer {
>   static func foo(_: P) {}
> 
>   struct Inner {
> static func foo(_: Q) {}
> 
> static func bar() {
>foo(S())
> }
>   }
> }
> 
> Resolves to Inner.foo just like it does today.
> 
> We would still start from the innermost scope and work our way outward until 
> we find a match. The only difference is we no longer stop partway up the 
> chain *without* finding a match.

That’s not implementable as described. Right now we find all possible overloads 
for a call site up front, then evaluate every combination of overloads at all 
call sites in an expression. The valid solutions are then ranked and the “best” 
one chosen, or an ambiguity is diagnosed. This means you can’t “stop” 
evaluating overloads, you need some way to disambiguate them and you have to 
consider all of them.

Slava

> 
> If we do find a match then yes, of course we stop there and use it.
> 
> Nevin

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


Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-12 Thread Slava Pestov via swift-evolution


> On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution 
>>  wrote:
>> 
>> Hello evolution folks,
>> 
>> After the positive feedback on the idea of improving capturing semantics of 
>> local functions, Alex Lynch and I worked on a proposal. Please let us know 
>> if you have any feedback:
>> 
>> https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/-improve-capture-semantics-of-local-functions.md
> 
> So, quoting the proposal:
> 
>> First of all, this proposal suggests extending the requirement of the self. 
>> prefix to local functions, but only if the local function is used as or used 
>> inside an escaping closure.
> 
> I don't love that the use of a function many lines away can cause errors in 
> that closure. There's a "spooky action-at-a-distance" quality to this 
> behavior that I don't like.

Agreed.

> I think this is a good idea, but I don't like bringing the already weird use 
> of `in` to actual functions.
> 
> By analogy with the current closure syntax, the capture list ought to go 
> somewhere before the parameter list, in one of these slots:
> 
> 1.func fn[foo, bar](param: T) throws -> T where T: Equatable { … }
> 2.func fn[foo, bar](param: T) throws -> T where T: Equatable { … }
> 3.func [foo, bar] fn(param: T) throws -> T where T: Equatable { … }
> 4.[foo, bar] func fn(param: T) throws -> T where T: Equatable { … }
> 
> Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, 
> and 3 just seems weird. But it seems like the one that would be easiest to 
> misparse.

Another option that reads nicely IMHO is

func fn(param: T) throws -> T where T : Equatable [foo, bar] { … }

I think #4 is ambiguous with array literals unfortunately.

Perhaps this proposal should be split in two — the ‘self.’/escaping part is 
source breaking, and will likely require more discussion. Adding capture lists 
to local functions seems like a more straightforward change.

Slava

> 
> -- 
> 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] Introduce user-defined dynamically "callable" types

2017-11-13 Thread Slava Pestov via swift-evolution


> On Nov 13, 2017, at 10:27 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
> 
>> On Nov 13, 2017, at 1:45 AM, Adrian Zubarev > > wrote:
>> 
>> Hello Chris, I have some questions about this passage:
>> 
>> Before this proposal, the Swift language has two types that participate in 
>> call syntax: functions and metatypes (for initialization). Neither of those 
>> may conform to protocols at the moment, so this introduces no possible 
>> ambiguity into the language.
>> Can you shortly describe why it would be ambiguous if metatypes would 
>> conform to protocols?
>> 
> It would only be ambiguous if a metatype conformed to the DynamicCallable 
> protocol specifically.  This can’t happen today, and if it happened, we could 
> easily define disambiguation rules.

FWIW it looks like we don’t allow calling a value of metatype type as of Swift 
3 — you have to add ‘.init’:

t.swift:6:4: error: initializing from a metatype value must reference 'init' 
explicitly
  m()
   ^
   .init

Slava

> 
> -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] Improving capturing semantics of local functions

2017-11-14 Thread Slava Pestov via swift-evolution


> On Nov 14, 2017, at 7:31 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> You can add generic closures with some name mangling and simple 
> transformations, nothing very hard.
> 
> The compiler can emit the following for example:
> 
> // User writes
> let increment: (T) -> T = { $0 + 1 }
> increment(1) // 2
> increment(1.1) // 2.1
> 
> 
> // Compiler issues
> struct _Generic_Increment { // Mangle name
> let increment: (T) -> T = { $0 + 1 }
> }
> _Generic_Increment().increment(1) // 2
> _Generic_Increment().increment(1.1) // 2.1
> 
> It's plausible that the compiler can do better than the above, but the above 
> would be sufficient and is easy to do.

There are several problems here:

- You’re adding a new syntax for a typed pattern with a generic parameter list, 
‘let foo:  …’. Presumably the right hand side of the assignment has to be a 
closure literal. Also such a literal can only be assigned to a let binding and 
not passed around as a value, because then you need higher rank types.

- What happens if you use increment as a value without binding generic 
parameters? Would that be an error? Eg, ‘let increment2 = increment’.

- What about where clauses?

- Right now, nested types cannot capture values from outer scopes, so your 
proposed lowering would need more work in order to be implemented.

I’m not sure what this buys you over local functions. Local functions have the 
advantage that they use the same syntax as ordinary functions, whether they are 
generic or not. Upon first encountering a local function, someone who has never 
seen a local function before will immediately know what it does. You’re 
proposing adding some special cases to the grammar to make local functions look 
more like closures. This seems to be a step backwards.

Slava

> 
>   -- Howard.
> 
> On 15 November 2017 at 14:02, Matthew Johnson  > wrote:
> 
> 
> Sent from my iPhone
> 
> On Nov 14, 2017, at 6:56 PM, Howard Lovatt via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> Having read all the arguments for what to add to local functions it still 
>> strikes me as a poor use of engineering resources to fix them (though I do 
>> agree they have problems). A better use of resources would be:
>> 
>>   1. Deprecate local functions.
>>   2. Allow closures when assigned to a function type to be:
>>   2a. Recursive.
>>   2b. Annotatable with:
>> 2bi.  @inline
>> 2bii. @escaping
>>   2c. Generic.
>> 
>> That would be a similar engineering effort and give a better short term 
>> result of better closures which would be much more widely applicable as well 
>> as addressing the issues with local functions.
> 
> I believe generic closures would require adding higher rank types to Swift.  
> That would be pretty cool but I suspect the engineering effort is at least an 
> order of magnitude greater than the changes discussed in this thread.
> 
>> 
>> It also gives a better long term result of not having to maintain local 
>> functions.
>>   
>> 
>>   -- Howard.
>> 
>> On 15 November 2017 at 09:08, Alex Lynch via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> The inference algebra just suggested was enjoyable to read, but is still a 
>> new syntax. Which is interesting and deserving of its own proposal. The 
>> purpose of this proposal is simply to introduce the existing capture syntax 
>> to local functions. Thanks to everyone's feedback pointing out that the 
>> `self` reference analysis is a deeper question than initially realized. 
>> 
>> Alex
>> 
>> On Tue, Nov 14, 2017 at 4:36 PM, Mike Kluev via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> On 14 November 2017 at 21:02, David Hart > > wrote:
>> 
>> 
>> I’d be very hesitant to introduce this syntax:
>> 
>> it’s new syntax, so it comes with a complexity tax (it isn’t naturally 
>> obvious what it means for a func to be weak)
>> it’s only sugar for the capture of self
>> it might cover well over 90% of use cases (by my "pessimistic" estimate)... 
>> if someone has a quick way to scan and analyse, say, github swift sources we 
>> may even know that current percentage number of real life usage.
>> it doesn’t transpose well to local closures
>> 
>> the last one - maybe not. follow me:
>> 
>> let closure = { [weak self, bar] in ... }
>> 
>> which today can be written as: 
>> 
>> let closure = { [weak self, bar] () -> Int in ... } // full form
>> 
>> or as:
>> 
>> let closure: () -> Int = { [weak self, bar] in ... } // full form
>> 
>> which allows this change:
>> 
>> let closure:  [weak self, bar] () -> Int = { ... } // full alt form
>> 
>> or in alternative form:
>> 
>> let closure:  weak () -> Int = { [bar] in ... } // short hand form
>> 
>> same can be with functions:
>> 
>> func fn() -> Int { [weak self, bar] in ... } // full form
>> 
>> weak func fn() -> Int { [bar] in ... } // short hand form
>> 
>> the two capture attributes wil

Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-14 Thread Slava Pestov via swift-evolution


> On Nov 14, 2017, at 6:56 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
>   2. Allow closures when assigned to a function type to be:
>   2a. Recursive.

Local functions can also be mutually recursive:

func f() {
  func foo() { bar() }
  func bar() { foo() }
}

This would not work with let bindings, which are not visible before the 
location where they are defined.

>   2b. Annotatable with:
> 2bi.  @inline

Neither closures nor local functions benefit from being annotated with 
@_inlineable, because they can only be referenced from inside their defining 
function, and not across module boundaries. So the optimizer can already inline 
the function or closure if needed.

> 2bii. @escaping
>   2c. Generic.

See my other response to this thread.

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


Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-16 Thread Slava Pestov via swift-evolution


> On Nov 16, 2017, at 2:56 PM, Tino Heth via swift-evolution 
>  wrote:
> 
> 
>> the stat suggests that in 90%+ real-life cases [weak self] is used so the 
>> "weak func" syntax sugar is worth to consider as an addition to this 
>> proposal.
> Slightly OT:
> Just thought about making all captures weak by default… I know it’s probably 
> to late for such a change, but I wonder if this was considered when closures 
> were designed

Remember that only references can be captured weakly, not value types, even if 
those value types contain reference members… so this might end up being more 
confusing than necessary.

Slava

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

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


Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-16 Thread Slava Pestov via swift-evolution


> On Nov 16, 2017, at 3:07 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Where I am proposing a change is that if a closure with generic arguments is 
> encountered it is transformed into the equivalent struct and the struct is 
> typed as it currently is (or if there is a better implementation something 
> equivalent to this), therefore zero change to the type system.

Since we already have local functions that can capture values and be generic, 
there’s no need to implement a new mechanism for name mangling or handling of 
captures.

> 
> The changes proposed are a transformation into a struct and name mangling, 
> e.g.:
> 
> let increment: (T) throws -> T where T: Numeric = { $0 + 1 }
> let increment = { (n: T) throws -> T where T: Numeric in n + 1 }
> let increment: (T) throws -> T where T: Numeric = { (n: T) throws 
> -> T where T: Numeric in n + 1 }

It sounds like what you’re proposing is essentially a new surface syntax for 
local functions — since a generic closure would not be a first class value, it 
could not appear anywhere except for the right hand side of a let binding, 
right?

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


Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-16 Thread Slava Pestov via swift-evolution


> On Nov 16, 2017, at 4:38 PM, Howard Lovatt  wrote:
> 
> When the user writes:
> 
> let increment: (T) throws -> T where T: Numeric = { $0 + 1 }
> increment(1) // 2
> increment(1.1) // 2.1

This means that ‘increment’ is a *value* with a generic function type. 
Presumably you want to pass generic closures as function parameters and results 
too. This is called higher-rank polymorphism and it introduces considerable 
complexity in type checking and code generation.

> Compiler issues global struct as above. Then:
> 
> let _int_increment = _Function1__T1__T1__T1__E__Numeric({ $0 + 1 })
> try _int_increment.call(1) // 2
> let _double_increment = _Function1__T1__T1__T1__E__Numeric({ $0 + 
> 1 })
> try _double_increment.call(1.1) // 2.1

What if I do,

let array = [increment]

What is the type of ‘array’?

Slava

> 
> The more restrictive form that you suggest (I think this is what you mean 
> anyway) of only allowed locally, not globally, is easier to name mangle, you 
> just need a unique name, nothing about the name needs to be canonical. This 
> would be similar to local functions at present and would be useful (though I 
> am not sure how many local *generic* functions there are).
> 
> 
>   -- Howard.
> 
> On 17 November 2017 at 10:47, Slava Pestov  > wrote:
> 
> 
>> On Nov 16, 2017, at 3:07 PM, Howard Lovatt via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Where I am proposing a change is that if a closure with generic arguments is 
>> encountered it is transformed into the equivalent struct and the struct is 
>> typed as it currently is (or if there is a better implementation something 
>> equivalent to this), therefore zero change to the type system.
> 
> Since we already have local functions that can capture values and be generic, 
> there’s no need to implement a new mechanism for name mangling or handling of 
> captures.
> 
>> 
>> The changes proposed are a transformation into a struct and name mangling, 
>> e.g.:
>> 
>> let increment: (T) throws -> T where T: Numeric = { $0 + 1 }
>> let increment = { (n: T) throws -> T where T: Numeric in n + 1 }
>> let increment: (T) throws -> T where T: Numeric = { (n: T) throws 
>> -> T where T: Numeric in n + 1 }
> 
> It sounds like what you’re proposing is essentially a new surface syntax for 
> local functions — since a generic closure would not be a first class value, 
> it could not appear anywhere except for the right hand side of a let binding, 
> right?
> 
> Slava
> 

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0189: Restrict Cross-module Struct Initializers

2017-11-17 Thread Slava Pestov via swift-evolution


> On Nov 17, 2017, at 8:57 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Nov 17, 2017, at 15:20, Ben Langmuir > > wrote:
>> 
>> Hi Jordan,
>> 
>> First off, this is clearly the model we should have had all along ;-)  That 
>> said, I have a concern about source-compat and our ability to automatically 
>> migrate code impacted by this change.
>>> Source compatibility
>>> 
>>> This makes existing code invalid in Swift 5, which is a source 
>>> compatibility break.
>>> 
>> It's not just a source compatibility break, it's a break that cannot 
>> necessarily be fixed if you don't control the module that vended the struct. 
>>  If a library doesn't expose an appropriate initializer, there is no way for 
>> the client to invent one.  Similarly, this isn't going to be very amenable 
>> to automatic migration, since
>> a) there may not be a memberwise initializer to use
>> b) even if there is, it may change the semantics to use it
>> 
>> There are two classes that we could theoretically migrate automatically:
>> 1) C structs, since we know the initializer and its semantics
>> 2) when we are migrating the code that defines the struct at the same time
>> 
>> The latter case might be tricky though, since it requires more global 
>> knowledge than we have in today's migrator.
>> 
>> Any thoughts?  Do we have an idea how common this is or what kinds of places 
>> it comes up in most often (in a single codebase with multiple modules vs 
>> external dependencies vs C structs vs )?
> 
> This is good to bring up, but I think "this can't be migrated" is the correct 
> answer for Swift structs. It's equivalent in my mind to when someone was 
> passing 'nil' to something that wasn't annotated for nullability and now is 
> marked '_Nonnull': it's source-breaking, and what you had before might even 
> have worked, but there's no guarantee that it would keep working in the 
> future. That's harder to sell for multi-module projects or even test targets, 
> though. I don't have a great answer there, but I don't think it's worth 
> bending over backwards to handle the "I migrate everything at once" case.
> 
> The C case is a bit harder to sell, which is why I made sure there were 
> fix-its to suggest inserting `self.init()` (the zeroing initializer) in most 
> cases (both in Swift 4 mode and Swift 5 mode). Not all C structs have that 
> initializer (specifically, if they have a member marked _Nonnull), but nearly 
> all do, and that's something the migrator could insert fairly easily, as you 
> note.
> 
> The mitigating factor I'm hoping for is that these become warnings in Swift 
> 4.1, which is planned to ship in a mid-year Xcode (can I admit that publicly, 
> swift-evolution?), and that therefore many people will have cleaned up their 
> code well before they even think of switching to Swift 5. But yes, this is a 
> breaking, non-migratable language change that's only strictly necessary for 
> libraries with binary compatibility, which most libraries today are not, and 
> that has to be acknowledged.

The migrator could also detect special cases, for example:

- there is a public member wise initializer — instead of initializing the 
fields directly, it could suggest adding a call to that instead
- there is a public no-argument initializer — here it might be sufficient to 
insert a call to self.init() prior to initializing fields

Slava

> 
> Jordan___
> 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] Python Interop with Swift 4+

2017-11-20 Thread Slava Pestov via swift-evolution


> On Nov 20, 2017, at 1:39 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> It is straight-forward (and fits very very naturally into the Swift call 
> model) to support the second one as an atomic thing, which is I think what 
> you’re getting at. 

What if you write ‘let fn = obj.method’?

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0189: Restrict Cross-module Struct Initializers

2017-11-20 Thread Slava Pestov via swift-evolution


> On Nov 20, 2017, at 1:58 PM, Drew Crawford via swift-evolution 
>  wrote:
> 
> I'm "weak oppose" on this proposal.
> 
> The core premise here is to increase the encapsulation of a struct around its 
> member variables.  But I think the purview of encapsulation is more classes 
> than structs.


How so? It seems that encapsulation is orthogonal to reference/value semantics.

>  e.g. a struct leaks information about the mutation of its member variables, 
> even if those variables are private.

Can you explain what you mean by this?

>  Structs are the obvious implementation for a named tuple (CGPoint 
> CGAffineTransform UIColor etc.) where there is inherently a fixed set of 
> members that are more conveniently accessed directly.  Structs and classes 
> have different purposes and so the argument for consistency with classes is 
> weak.
> 
> With regard to the BalancedPair problem, I would prefer to see a "final 
> struct" or "required init”.

The real reason we want to introduce this language change is to solve some 
problems related to resilience. We want to be able to add new stored properties 
to structs, or change existing stored properties to computed properties (and 
vice versa) without breaking binary or source compatibility. Since 
non-delegating initializers expose the exact set of stored properties to the 
client module, they break the encapsulation that we need to allow this.

Slava
> On November 14, 2017 at 1:31:25 PM, Ted Kremenek (kreme...@apple.com 
> ) wrote:
> 
>> The review of "SE-0189: Restrict Cross-module Struct Initializers" begins 
>> now and runs through November 21, 2017.
>> 
>> The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0189-restrict-cross-module-struct-initializers.md
>>  
>> 
>> Reviews are an important part of the Swift evolution process. All review 
>> feedback should be sent to the swift-evolution mailing list at:
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager. 
>> 
>> When replying, please try to keep the proposal link at the top of the 
>> message:
>> 
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0189-restrict-cross-module-struct-initializers.md
>>  
>> 
>> ...
>> Reply text
>> ...
>> Other replies
>> What goes into a review of a proposal?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and, eventually, determine the direction of 
>> Swift. 
>> 
>> When reviewing a proposal, here are some questions to consider:
>> 
>> What is your evaluation of the proposal?
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> Thanks,
>> Ted Kremenek
>> Review Manager
>> ___
>> swift-evolution-announce mailing list
>> swift-evolution-annou...@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Synthesizing Equatable, Hashable, and Comparable for tuple types

2017-11-20 Thread Slava Pestov via swift-evolution
Ignoring synthesized conformances for a second, think about how you would 
manually implement a conformance of a tuple type to a protocol. You would need 
some way to statically “iterate” over all the component types of the tuple — in 
fact this is the same as having variadic generics.

If we had variadic generics, we could implement tuples conforming to protocols, 
either by refactoring the compiler to allow conforming types to be non-nominal, 
or by reworking things so that a tuple is a nominal type with a single variadic 
generic parameter.

Slava

> On Nov 20, 2017, at 9:06 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> This is something I've wanted to look at for a while. A few weeks ago I 
> pushed out https://github.com/apple/swift/pull/12598 
>  to extend the existing synthesis 
> to handle structs/enums when a field/payload has a tuple of things that are 
> Equatable/Hashable, and in that PR it was (rightly) observed, as Chris just 
> did, that making tuples conform to protocols would be a more general solution 
> that solves the same problem you want to solve here.
> 
> I'd love to dig into this more, but last time I experimented with it I got 
> stuck on places where the protocol conformance machinery expects 
> NominalTypeDecls, and I wasn't sure where the right place to hoist that logic 
> up to was (since tuples don't have a corresponding Decl from what I can 
> tell). Any pointers?
> 
> On Mon, Nov 20, 2017 at 5:51 PM Chris Lattner via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> On Nov 20, 2017, at 5:48 PM, Kelvin Ma  > wrote:
>> the end goal here is to use tuples as a compatible currency type, to that 
>> end it makes sense for these three protocols to be handled as “compiler 
>> magic” and to disallow users from manually defining tuple conformances 
>> themselves. i’m not a fan of compiler magic, but Equatable, Hashable, and 
>> Comparable are special because they’re the basis for a lot of standard 
>> library functionality so i think the benefits of making this a special 
>> supported case outweigh the additional language opacity.
> 
> I understand your goal, but that compiler magic can’t exist until there is 
> something to hook it into.  Tuples can’t conform to protocols right now, so 
> there is nothing that can be synthesized.
> 
> -Chris
> 
> 
>> 
>> On Mon, Nov 20, 2017 at 8:42 PM, Chris Lattner > > wrote:
>> 
>>> On Nov 20, 2017, at 5:39 PM, Kelvin Ma via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> when SE-185 
>>> 
>>>  went through swift evolution, it was agreed that the next logical step 
>>>  is 
>>> synthesizing these conformances for tuple types, though it was left out of 
>>> the original proposal to avoid mission creep. I think now is the time to 
>>> start thinking about this. i’m also tacking on Comparable to the other two 
>>> protocols because there is precedent in the language from SE-15 
>>> 
>>>  that tuple comparison is something that makes sense to write.
>>> 
>>> EHC conformance is even more important for tuples than it is for structs 
>>> because tuples effectively have no workaround whereas in structs, you could 
>>> just manually implement the conformance. 
>> 
>> In my opinion, you’re approaching this from the wrong direction.  The 
>> fundamental problem here is that tuples can’t conform to a protocol.  If 
>> they could, synthesizing these conformances would be straight-forward.
>> 
>> If you’re interested in pushing this forward, the discussion is “how do 
>> non-nominal types like tuples and functions conform to protocols”?
>> 
>> -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] [swift-evolution-announce] [Review] SE-0189: Restrict Cross-module Struct Initializers

2017-11-20 Thread Slava Pestov via swift-evolution


> On Nov 20, 2017, at 11:14 PM, Drew Crawford  wrote:
> 
> It would improve the important clients without harming other clients to use 
> the following implementation for our type: if the sorted accessor is used 
> before the unsorted one, sort the underlying storage, and then serve that 
> until the type is subsequently mutated (which important clients do not do).  
> This amortizes the cost of the sort across many calls to the accessor.

Sure, but it’s hard to completely encapsulate this kind of caching behavior 
inside the type. For example, thread safety. But yes, there are different 
tradeoffs with reference and value types, and it’s hard to argue that one is 
better for encapsulation than the other.

> > We want to be able to add new stored properties to structs, or change 
> > existing stored properties to computed properties (and vice versa) without 
> > breaking binary or source compatibility.
> 
> If CGAffineTransform, CGPoint, in_addr_t etc. are changing their members we 
> have a problem.  There are probably structs where this makes more sense, but 
> I can't immediately think of an example.

in_addr_t is actually mostly opaque so it’s actually not a good example.I agree 
that CGAffineTransform and such are trivial. But it’s easy to think of cases 
where you want to change the internal representation of a data type without 
changing it’s API, and sometimes this means stored properties become computed 
properties. The only place in the language where the difference between stored 
and computed properties can be observed is inside a non-delegating initializer 
of a struct, so it makes sense to prohibit them from being defined outside of 
the original module.

Slava

> 
> 
> On November 20, 2017 at 6:16:55 PM, Slava Pestov (spes...@apple.com 
> ) wrote:
> 
>> 
>> 
>>> On Nov 20, 2017, at 1:58 PM, Drew Crawford via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I'm "weak oppose" on this proposal.
>>> 
>>> The core premise here is to increase the encapsulation of a struct around 
>>> its member variables.  But I think the purview of encapsulation is more 
>>> classes than structs.
>> 
>> 
>> How so? It seems that encapsulation is orthogonal to reference/value 
>> semantics.
>> 
>>>  e.g. a struct leaks information about the mutation of its member 
>>> variables, even if those variables are private.
>> 
>> Can you explain what you mean by this?
>> 
>>>  Structs are the obvious implementation for a named tuple (CGPoint 
>>> CGAffineTransform UIColor etc.) where there is inherently a fixed set of 
>>> members that are more conveniently accessed directly.  Structs and classes 
>>> have different purposes and so the argument for consistency with classes is 
>>> weak.
>>> 
>>> With regard to the BalancedPair problem, I would prefer to see a "final 
>>> struct" or "required init”.
>> 
>> The real reason we want to introduce this language change is to solve some 
>> problems related to resilience. We want to be able to add new stored 
>> properties to structs, or change existing stored properties to computed 
>> properties (and vice versa) without breaking binary or source compatibility. 
>> Since non-delegating initializers expose the exact set of stored properties 
>> to the client module, they break the encapsulation that we need to allow 
>> this.
>> 
>> Slava
>>> On November 14, 2017 at 1:31:25 PM, Ted Kremenek (kreme...@apple.com 
>>> ) wrote:
>>> 
 The review of "SE-0189: Restrict Cross-module Struct Initializers" begins 
 now and runs through November 21, 2017.
 
 The proposal is available here:
 
 https://github.com/apple/swift-evolution/blob/master/proposals/0189-restrict-cross-module-struct-initializers.md
  
 
 Reviews are an important part of the Swift evolution process. All review 
 feedback should be sent to the swift-evolution mailing list at:
 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
 or, if you would like to keep your feedback private, directly to the 
 review manager. 
 
 When replying, please try to keep the proposal link at the top of the 
 message:
 
 Proposal link: 
 https://github.com/apple/swift-evolution/blob/master/proposals/0189-restrict-cross-module-struct-initializers.md
  
 
 ...
 Reply text
 ...
 Other replies
 What goes into a review of a proposal?
 
 The goal of the review process is to improve the proposal under review 
 through constructive criticism and, eventually, determine the direction of 
 Swift. 
 
 When reviewing a proposal, here are some questions to

Re: [swift-evolution] Synthesizing Equatable, Hashable, and Comparable for tuple types

2017-11-21 Thread Slava Pestov via swift-evolution


> On Nov 21, 2017, at 6:02 PM, David Hart  wrote:
> 
> Can somebody explain to me what are 
>  nominal and structural types and why Optional should really be a structural 
> type?

Nominal types are structs, enums, protocols and classes. They have declarations 
in source and are uniquely identified by their name. Structural types are 
functions, meta types, protocol compositions, and tuples.

The distinction is not as clear as you might think because as Chris said, you 
can imagine tuple being implemented as ‘struct Tuple’, similarly functions 
and meta types could also be written as such. It is mostly a syntactic 
distinction in the language, but it has far-reaching consequences in internal 
representations, which is why for now it would be tricky to have structural 
types conform to protocols.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0189: Restrict Cross-module Struct Initializers

2017-11-27 Thread Slava Pestov via swift-evolution


> On Nov 27, 2017, at 11:04 AM, Ben Langmuir  wrote:
> 
> 
> 
>> On Nov 17, 2017, at 5:59 PM, Slava Pestov > > wrote:
>> 
>> 
>> 
>>> On Nov 17, 2017, at 8:57 PM, Jordan Rose via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> 
 On Nov 17, 2017, at 15:20, Ben Langmuir >>> > wrote:
 
 Hi Jordan,
 
 First off, this is clearly the model we should have had all along ;-)  
 That said, I have a concern about source-compat and our ability to 
 automatically migrate code impacted by this change.
> Source compatibility
> 
> This makes existing code invalid in Swift 5, which is a source 
> compatibility break.
> 
 It's not just a source compatibility break, it's a break that cannot 
 necessarily be fixed if you don't control the module that vended the 
 struct.  If a library doesn't expose an appropriate initializer, there is 
 no way for the client to invent one.  Similarly, this isn't going to be 
 very amenable to automatic migration, since
 a) there may not be a memberwise initializer to use
 b) even if there is, it may change the semantics to use it
 
 There are two classes that we could theoretically migrate automatically:
 1) C structs, since we know the initializer and its semantics
 2) when we are migrating the code that defines the struct at the same time
 
 The latter case might be tricky though, since it requires more global 
 knowledge than we have in today's migrator.
 
 Any thoughts?  Do we have an idea how common this is or what kinds of 
 places it comes up in most often (in a single codebase with multiple 
 modules vs external dependencies vs C structs vs )?
>>> 
>>> This is good to bring up, but I think "this can't be migrated" is the 
>>> correct answer for Swift structs. It's equivalent in my mind to when 
>>> someone was passing 'nil' to something that wasn't annotated for 
>>> nullability and now is marked '_Nonnull': it's source-breaking, and what 
>>> you had before might even have worked, but there's no guarantee that it 
>>> would keep working in the future. That's harder to sell for multi-module 
>>> projects or even test targets, though. I don't have a great answer there, 
>>> but I don't think it's worth bending over backwards to handle the "I 
>>> migrate everything at once" case.
>>> 
>>> The C case is a bit harder to sell, which is why I made sure there were 
>>> fix-its to suggest inserting `self.init()` (the zeroing initializer) in 
>>> most cases (both in Swift 4 mode and Swift 5 mode). Not all C structs have 
>>> that initializer (specifically, if they have a member marked _Nonnull), but 
>>> nearly all do, and that's something the migrator could insert fairly 
>>> easily, as you note.
>>> 
>>> The mitigating factor I'm hoping for is that these become warnings in Swift 
>>> 4.1, which is planned to ship in a mid-year Xcode (can I admit that 
>>> publicly, swift-evolution?), and that therefore many people will have 
>>> cleaned up their code well before they even think of switching to Swift 5. 
>>> But yes, this is a breaking, non-migratable language change that's only 
>>> strictly necessary for libraries with binary compatibility, which most 
>>> libraries today are not, and that has to be acknowledged.
>> 
>> The migrator could also detect special cases, for example:
>> 
>> - there is a public member wise initializer — instead of initializing the 
>> fields directly, it could suggest adding a call to that instead
> 
> Are you suggesting we do this even when we don't know the semantics of the 
> init we would be calling (e.g. it might introduce new side effects)?  I was 
> thinking this would be unsafe to transform automatically, or at least we'd 
> want to draw the developer's attention to it to verify it didn't change the 
> behaviour.
> 
>> - there is a public no-argument initializer — here it might be sufficient to 
>> insert a call to self.init() prior to initializing fields
> 
> Good point about being able to use the no-arg init, although with the same 
> caveat as the previous case I think.

Yeah in general the amount of existing code that would be affected by this is 
an open question. This is why we wanted to stage the warning into 4.1 and see 
if people complain first.

Slava

> 
> Ben
> 
>> 
>> Slava
>> 
>>> 
>>> Jordan___
>>> 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] [Pre-pitch] Conditional default arguments

2017-11-27 Thread Slava Pestov via swift-evolution
Hi Tony,

So if my understanding is correct, the basic proposal is the following:

func id(t: T ?= T.defaultValue) { return t }

extension Int { static var defaultValue = 0 }

extension String { static var defaultValue = “” }

id() as Int // returns 0
id() as String // returns “”
id() as SomeRandomType // fails to type check — no default argument

I don’t understand what would happen if the caller is itself generic though, 
for example:

callsID(_ t: T) {
  _ = id() as T
}

It appears that body of callsID() itself cannot type check without knowledge of 
the concrete T that will be used with this function.

Slava

> On Nov 27, 2017, at 4:10 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> I totally agree that that's a good rule in general—I'm not 100% comfortable 
> making an exception to it for this, but I wanted to start a discussion about 
> a different approach than had been considered so far.
> 
> The idea of forcing the user to acknowledge the explicitness of SFINAE with a 
> strawman syntax `=?` instead of `=` was a thought experiment to bridge the 
> wild-west-C++ world of templates and Swift's stricter generics, but I can 
> definitely understand if even that kind of approach is something that the 
> core team (who are far more familiar with the C++ side of that coin than I 
> am) doesn't wish to support. As was pointed out, it's not something Swift 
> supports anywhere else today.
> 
> If we look at it from that point of view, where such a semantic treatment of 
> generics would not be supported, I think it becomes a lot harder to 
> rationalize treating this as "default arguments". What you really do have 
> (and what writing it as constrained extensions makes clear) is additional 
> overloads, because they only apply to certain subsets of types. If that's the 
> case, maybe it's the wrong approach to try to turn overloads into "partial 
> default values".

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


Re: [swift-evolution] [Pre-pitch] Conditional default arguments

2017-11-27 Thread Slava Pestov via swift-evolution


> On Nov 27, 2017, at 3:38 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> You are effectively proposing that in this very narrow case we perform 
> overload resolution on a symbol in a generic type context *after* the generic 
> type has been replaced with a concrete type. 

Keep in mind that in general, this would require runtime support — we don’t 
always know the concrete substitution for a generic parameter at compile time, 
especially in the presence of separate compilation (but even without, for 
instance when optimizations are not enabled or unable to recover concrete type 
information).

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


Re: [swift-evolution] [Pre-pitch] Conditional default arguments

2017-11-28 Thread Slava Pestov via swift-evolution


> On Nov 28, 2017, at 8:44 AM, Matthew Johnson  wrote:
> 
> func makeResource(
> with configuration: Configuration = () where Configuration == Void, 
> actionHandler: @escaping (Action) -> Void = { _ in } where Action == Never
> )

Similar question to the one I posed earlier — what happens if I’m using 
makeResource() from a generic context? Is the conditional default argument 
simply not available?

In this case, how is it different from defining some static overloads of 
makeResource(), some of which have default arguments and some of which are 
generic?

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


Re: [swift-evolution] [Pre-pitch] Conditional default arguments

2017-11-28 Thread Slava Pestov via swift-evolution


> On Nov 28, 2017, at 1:25 PM, Matthew Johnson  wrote:
> 
> 
>> On Nov 28, 2017, at 3:18 PM, Slava Pestov > > wrote:
>> 
>> 
>> 
>>> On Nov 28, 2017, at 8:44 AM, Matthew Johnson >> > wrote:
>>> 
>>> func makeResource(
>>> with configuration: Configuration = () where Configuration == Void, 
>>> actionHandler: @escaping (Action) -> Void = { _ in } where Action == 
>>> Never
>>> )
>> 
>> Similar question to the one I posed earlier — what happens if I’m using 
>> makeResource() from a generic context? Is the conditional default argument 
>> simply not available?
> 
> Right.  If the constraints are not met at the call site the default is not 
> available.  I think you understood, but looking at the example above I 
> omitted the resource type parameter.  It should read:
> 
> func makeResource(
> with configuration: R.Configuration = () where R.Configuration == Void, 
> actionHandler: @escaping (R.Action) -> Void = { _ in } where R.Action == 
> Never
> )
> 
>> 
>> In this case, how is it different from defining some static overloads of 
>> makeResource(), some of which have default arguments and some of which are 
>> generic?
> 
> From the point of view of the call site it is not different.  The differences 
> are that:
> 
> * the user is presented with a single API rather than several overloads

Is this less confusing than encountering a new ‘where’ clause on default 
arguments, which is probably rare enough that many users will spend 
months/years using Swift without seeing it?

> * the compiler doesn’t have to reason about an overload set which might 
> improve build times, etc

They’re effectively equivalent, because we still have to decide which subset of 
the default arguments apply at a given call site by checking all combinations 
of constraints.

Slava

> 
>> 
>> Slava
> 

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


Re: [swift-evolution] [Pre-pitch] Conditional default arguments

2017-11-28 Thread Slava Pestov via swift-evolution


> On Nov 28, 2017, at 1:35 PM, Matthew Johnson  wrote:
> 
>>> * the compiler doesn’t have to reason about an overload set which might 
>>> improve build times, etc
>> 
>> They’re effectively equivalent, because we still have to decide which subset 
>> of the default arguments apply at a given call site by checking all 
>> combinations of constraints.
> 
> Interesting.  Are there no advantages to the compiler that would be possible 
> if an overload set was replaced with constrained default arguments?
> 

Probably not. In general I’m wary of designing language features specifically 
to speed up the type checker, since they make not have the intended effect or 
even the opposite effect. We know the type checker implementation is not the 
best possible implementation of a type checker — there is a lot we can improve 
without changing the language.

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


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-11-28 Thread Slava Pestov via swift-evolution
Hi Chris,

> On Nov 28, 2017, at 8:54 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> “post.author" always invokes the DynamicMemberLookupProtocol proposal.
> “post.author()” would invoke the “DynamicCallableWithKeywordsToo” hook in the 
> dynamic callable proposal:
> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d 
> 
Elsewhere in Swift, it is generally the case that

foo.bar()

is equivalent to

let fn = foo.bar
fn()

Would this equivalence still hold with your proposal(s)?

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


Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-11-30 Thread Slava Pestov via swift-evolution


> On Nov 30, 2017, at 10:23 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> The difference between it and AnyObject lookup is that AnyObject lookup is:
> 
> b) type unsafe

Can you explain in what sense AnyObject lookup is type unsafe where your 
proposal is type safe? Both seem type safe in the sense that your program will 
not hit undefined behavior at runtime and instead trap if you access a 
non-existent member; both are type unsafe in the sense that you cannot reason 
statically about whether any specific member lookup will succeed. What is the 
distinguishing characteristic between the two that makes one safe and the other 
not?

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


Re: [swift-evolution] Optional Argument Chaining

2017-12-11 Thread Slava Pestov via swift-evolution


> On Dec 11, 2017, at 2:41 PM, Jared Khan via swift-evolution 
>  wrote:
> 
> I missed the previous threads! I’ve found one of the relevant threads here:
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160711/024201.html
>  
> 
> 
> Thanks for this important point.
> 
> If you were to write this logic out by hand then you would short-circuit it 
> and this is analogous to current chaining behaviour so to me evaluating left 
> to right (as Swift usually does) and stopping at the first failed unwrap 
> would make sense. I wouldn’t necessarily say it’s intuitive but I don’t think 
> it’s really less intuitive than the current chaining behaviour. 

I think it gets confusing when you have multiple levels of nested expressions, 
eg

foo(bar(x?)) + y?

Slava

> 
> Jared
> 
>> On 11 Dec 2017, at 19:28, Xiaodi Wu via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> This topic has been discussed at least two and maybe more times in the 
>> past.. It’s hard for me to post links at the moment, but it should be 
>> possible to find on Google.
>> 
>> One major challenge to this idea, for which no satisfactory answer has been 
>> achieved after all these years, is the following issue:
>> 
>> f(g()?, h()?, i(), j()?)?
>> 
>> If g() evaluates to nil, is h() called or not? How about i(), which is not 
>> failable? Since any function or property access can have side effects, in 
>> what order are the arguments evaluated, and how does one reason about this 
>> code flow?
>> 
>> To my mind, in the absence of an intuitive answer to the above—which does 
>> not appear to be possible—this idea is not feasible.
>> On Mon, Dec 11, 2017 at 12:34 Magnus Ahltorp via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> > 12 Dec. 2017 02:58 Jared Khan mailto:jaredk...@me.com>> 
>> > wrote:
>> >
>> > 2. It felt natural to me. It’s analogous to the existing optional chaining 
>> > scenarios and composes nicely. I think it’s about as understandable as 
>> > existing chaining, a newbie would have to look it up to discover its 
>> > meaning. What are your thoughts on this particular syntax (ignoring 3. 
>> > momentarily)? Hopefully others in this thread can share their views too.
>> 
>> Chaining methods is linear, while nesting fills a similar purpose when we 
>> use function calls. This of course affects the way existing Swift code is 
>> written, but that is something we have to live with if we want to use 
>> familiar syntax patterns. However, I think we have to consider this 
>> difference in this case, since the syntax becomes more convoluted. Your 
>> suggestion is definitely not as easy to read as the optional chaining 
>> syntax, and maybe it can't be.
>> 
>> > As for how common I’d expect it to be, it’s something I’ve run into myself 
>> > a few times. Again, I hope members of this list can give their view on if 
>> > this would be useful to them.
>> 
>> I don't have any real examples, but I certainly think that I have run into 
>> it, so I'm quite open to solving the problem. For me, it is probably only a 
>> matter of finding a syntax that is acceptable.
>> 
>> > 3. I’m not entirely sure what the grammar situation is yet but afaik ‘?’ 
>> > has never been available as a postfix operator. Perhaps I’m missing your 
>> > point, could you demonstrate where it is allowed?
>> 
>> I did not expect that you would be able to answer that, it was more a 
>> question directed to people who are more connected to the inner workings of 
>> the parsing of Swift than I am. It is not allowed, but the error message is 
>> not the one I expect, something that gives me a hint that it does have some 
>> meaning early in the parsing.
>> 
>> /Magnus
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> 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 0192 - Non-Exhaustive Enums

2017-12-19 Thread Slava Pestov via swift-evolution


> On Dec 19, 2017, at 3:31 PM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> So I guess I’m saying, I want more thought put on the topic of whether enums 
> defined in Swift should actually default to non-exhaustive, and I’m now 
> leaning towards the idea that they should remain exhaustive (but Obj-C enums 
> will still default to non-exhaustive).

This would introduce an inconsistency between enums and structs. Structs will 
not be fixed-contents by default (there’s a proposal coming for that), which 
means you will be able to add stored properties after the fact. For this reason 
it makes more sense to me to also make enums non-exhaustive by default so that 
new cases can be added.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-19 Thread Slava Pestov via swift-evolution
They would not be boxed, but there would be additional indirection required at 
runtime, using the same mechanism currently used for unspecialized generics.

Slava

> On Dec 19, 2017, at 6:42 PM, Kevin Ballard  wrote:
> 
> Isn’t this going to turn both structs and non-C-like enums into types that 
> need to be auto-boxed (as the client won’t be able to rely on knowing the 
> fixed size anymore)? This seems like a performance hazard.
> 
> -Kevin Ballard
> 
> On Dec 19, 2017, at 5:35 PM, Slava Pestov  > wrote:
> 
>> 
>> 
>>> On Dec 19, 2017, at 3:31 PM, Kevin Ballard via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> So I guess I’m saying, I want more thought put on the topic of whether 
>>> enums defined in Swift should actually default to non-exhaustive, and I’m 
>>> now leaning towards the idea that they should remain exhaustive (but Obj-C 
>>> enums will still default to non-exhaustive).
>> 
>> This would introduce an inconsistency between enums and structs. Structs 
>> will not be fixed-contents by default (there’s a proposal coming for that), 
>> which means you will be able to add stored properties after the fact. For 
>> this reason it makes more sense to me to also make enums non-exhaustive by 
>> default so that new cases can be added.
>> 
>> Slava

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


Re: [swift-evolution] [Pitch] @static imports

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Karl,

This is an interesting idea and part of something we would like to explore in 
the future, which is resilience domains that span more than one module.

However keep in mind that in the current design, resilience is something you 
opt into when building a library, with a compiler flag. If you don’t pass the 
flag, there’s no additional indirection, and the flag is off by default.

Note that this does not apply to exhaustive enums — we would like those to 
always be non-exhaustive by default because we don’t want a compiler flag 
changing language semantics. However, they will be compiled as if they are 
exhaustive, meaning the compiler can assume the enum has a fixed layout from 
the client binary.

Slava

> On Dec 20, 2017, at 6:56 AM, Karl Wagner via swift-evolution 
>  wrote:
> 
> There’s a lot of talk in the non-exhaustive enum discussion about the source 
> transition. So let me suggest a possible solution: @static imports.
> 
> Basically, it seems to me like resilience is going to introduce a lot of 
> indirection, both in generated instructions and in the language. I think that 
> making resilience opt-in on a declaration-by-declaration basis would make it 
> difficult for average programmers to get right, so I support the idea of 
> making Swift libraries resilient-by-default with opt-out abilities when it is 
> obvious from the perspective of the library author that it should be so.
> 
> However, Apps are not libraries. Whereas libraries are a kind of theoretical 
> block of code, and you naturally want them to be adaptable to different 
> circumstances, Apps are the concrete things which actually use them. They 
> might have a different perspective on what can be allowed to be 
> non-resilient. Just like an App may be built to be compatible with a 
> particular version of a library, I think it’s reasonable for it to be built 
> expecting other “flavours” of the library, too - including a non-resilient 
> flavour. We already kind of have something like this: executables can import 
> modules as @testable, and those modules are required to be built with the 
> “-enable-testing” flag.
> 
> My suggestion is that we create a new kind of import mode, "@static import" 
> and some corresponding compiler flag. When you import a module using @static, 
> you tell the compiler that your App requires exactly the module which it is 
> being compiled alongside. When compiling your regular, resilient-by-default 
> Swift libraries with the special flag, they will be transformed to fix them 
> at their current version and provide later stages of the compiler as much 
> information as if it was within the same module (i.e. applying final, 
> @exhaustive, providing complete SIL, etc). App code will not be able to 
> access “internal” members of the @static library (even though the compiler 
> can see them). We might allow the same attribute to be applied to static 
> libraries from C, which can be similarly freed of resilience concerns.
> 
> That would help ease code migration - for this and future resilience-related 
> changes - because you’ll basically get the Swift 4 behaviour back for 
> libraries which you control.
> 
> // Regular imports. We don’t control these libraries.
> import Foundation
> import UIKit
> // Static imports. We control these; they will be embedded in the final 
> product in some way. Everything is @exhaustive!
> @static import MyDataModel
> @static import SharedUIElements
> 
> - Karl
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Xiaodi,

Thanks for taking the time to look over the proposal.

> On Dec 20, 2017, at 7:01 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Does this proposal fit well with the feel and direction of Swift?
> 
> Yes, with a caveat. It seems a little unfortunate that @inline(never) is 
> spelled so differently from @inlinable. Probably too late to rename the 
> former @noninlinable though. It'd be lovely though.

So @inline(never) is not the opposite of @inlinable, it is something completely 
different:

- @inline(never) impacts the optimizer’s behavior inside the module, where as 
@inlinable has no effect on callees inside a module.
- You can in fact define a function that is @inline(never) and @inlinable. This 
would allow the function to be specialized or otherwise emitted inside a client 
module, but neither the specialization nor the original function would ever be 
inlined.

I’d like the swift-evolution community to discuss @inline(never) and 
@inline(__always) at some point, but I think they’re sufficiently unrelated to 
this proposal that we should probably not try to fit them in.

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Nevin,

Thanks for taking the time to review the proposal!

> On Dec 20, 2017, at 7:08 PM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
> Alternatively, since the “@abiPublic” attribute allows objects to be used by 
> inlined code, why not spell it “@inlinable”?
> 

Because both @abiPublic and @inlinable can be applied to functions, and we 
really do need to distinguish the two cases — they’re definitely not the same:

private func pf() {}

@abiPublic func af() {
  pf() // OK — we can reference a private function here
  // framework author can change the body of af() and clients see the new body
}

@inlinable public func if() {
  pf() // error!

  af() // OK

  // changes made here don’t necessarily get picked up by clients until 
recompiled
}

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Tony,

Thanks for the review!

> On Dec 20, 2017, at 8:09 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> A related question (with some background): My assumption is that conditional 
> compilation directives (e.g., #if DEBUG) are resolved *before* an @inlinable 
> function is serialized to the module. Is that correct?

That is correct. Conditional compilation directives are always resolved in the 
context of the defining module.

Slava

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Thanks for the review, Kelvin.

> On Dec 20, 2017, at 8:52 PM, Kelvin Ma via swift-evolution 
>  wrote:
> 
> it makes sense to have @abiPublic on private and fileprivate declarations too 
> and i hope this gets added, because private and fileprivate are tools for 
> code organization and maintenance,, the compiler with wmo doesn’t care about 
> private vs internal. but @abiPublic private is bound to cause confusion and 
> it just reads funny. 

>From an implementation standpoint, it would be a simple change to allow 
>@abiPublic on private and fileprivate declarations. However, I think that 
>introduce some confusion. Recall that the mangling of private symbols includes 
>the source file name. This would now be part of your framework’s ABI. If you 
>moved the @abiPublic function to another source file, or rename the source 
>file, you will break ABI.

Another approach would be to change the mangling so that @abiPublic private 
symbols are mangled like internal symbols, with a module name and no source 
file name. This makes for a simpler ABI. However this also has a downside, 
because now if you define two @abiPublic private functions in different files 
that have the same mangling, you will get a linker error and not a nice 
compiler diagnostic.

Note that nothing in this proposal precludes @abiPublic from being applied to 
private and fileprivate symbols though. If we figure out a nice solution to the 
above problems, we could generalize @abiPublic without any issues.

Slava

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Paul,

Thanks for reviewing the proposal!

> On Dec 20, 2017, at 9:21 PM, Paul Cantrell  wrote:
> 
> A concern: how would a library author reason about, and check for bugs in, 
> the combinatorial explosion of old and new implementations that could exist 
> simultaneously with this feature in use?

I don’t have a simple answer to this unfortunately, other than the author being 
really careful, perhaps keeping around build artifacts that were compiled 
against older versions of the library and testing those.

> That last paragraph gives a relatively trivial example, but the implications 
> are daunting! If I understand correctly, anything in a library that uses any 
> @inlinable or @abiPublic code must be prepared to deal with every possible 
> combination of every past published implementation of that code. And that 
> “every possible combination” is not per function, but per…call site?
> 
> Suppose we have this:
> 
> // Module A
> 
> @inlineable func bar() { ... }
> 
> // Module B
> 
> @inlineable func foo() {
> if whatever {
> bar(0)  // compiler decides to inline this...
> } else {
> bar(1)  // ...but not this, for whatever reason
> }
> }
> 
> // Module C
> 
> func baz() {
> foo()
> }
> 
> …and suppose B was compiled against A v1.0 but C was compiled against A v2.0. 
> Then, if I’m following, it’s possible for bar(0) to use the 1.0 
> implementation but bar(1) to use the 2.0 impl. Do I have that right? It seems 
> to be what the hash value example is getting at.

That is correct. Another example is if module A publishes an inlinable 
function, and module B and C depend on A, but B and C were compiled with 
different versions of A. Then a fourth module D that depends on B and C might 
see two different published versions of this function.

> Or is this not as dangerous as I’m imagining it to be?

It *is* pretty dangerous, which is why I hope this feature is used judiciously 
by third-party binary frameworks. With source frameworks that are built 
together with an app and always recompiled, this is less of a concern.

Also we are using this feature extensively in the standard library, so as the 
standard library evolves we will learn and develop best practices, hopefully 
without too many hiccups :)

Slava

> 
> Cheers, P
> 
> 
>> On Dec 20, 2017, at 6:19 PM, Ted Kremenek via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> The review of "SE-0193 - Cross-module inlining and specialization" begins 
>> now and runs through January 5, 2018.
>> 
>> The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> Reviews are an important part of the Swift evolution process. All review 
>> feedback should be sent to the swift-evolution mailing list at:
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager. 
>> 
>> When replying, please try to keep the proposal link at the top of the 
>> message:
>> 
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> ...
>> Reply text
>> ...
>> Other replies
>> What goes into a review of a proposal?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and, eventually, determine the direction of 
>> Swift. 
>> 
>> When reviewing a proposal, here are some questions to consider:
>> 
>> What is your evaluation of the proposal?
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> Thanks,
>> Ted Kremenek
>> Review Manager
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution
Hi Brent,

> On Dec 20, 2017, at 9:35 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> I concur. If we don't care about its ungainly size, the blindingly obvious 
> solution would be `@inlineCallable`. Another solution might be to declare the 
> symbol with a combination like `@hidden public`, which I assume is a closer 
> representation of how this feature is actually implemented.

@hidden public seems more confusing to me, because the symbol is not public to 
name lookup. @abiPublic has no effect on source compatibility, only binary 
compatibility.

> 
> (Incidentally, the proposal doesn't mention `open`; I suspect that it 
> probably should.)

I can revise the proposal to add a brief mention of ‘open’ if you’d like. As 
you may have guessed already there is no distinction between ‘open’ and 
‘public’ here.

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution


> On Dec 20, 2017, at 10:17 PM, Adam Kemp via swift-evolution 
>  wrote:
> 
> Should there be some kind of diagnostic if you have an @abiPublic definition 
> that is never referenced by any @inlinable function? I can imagine that there 
> might be tools to check that a new build of a module doesn’t break binary 
> compatibility by verifying that you didn’t remove any @abiPublic symbols, but 
> what if you never meant to and never needed to export that symbol in the 
> first place? How do we prevent that from happening?

>From a technical standpoint it would be possible to implement such a 
>diagnostic, with the caveat that it would probably only work in whole module 
>optimization mode. However, you’re right that there’s a complication here:

> Perhaps a diagnostic like this would cause problems if you started with an 
> @inlinable function that called an @abiPublic function and then in a 
> subsequent version of your module you modified the @inlinable function such 
> that it no longer calls the @abiPublic function. You would still need to keep 
> that @abiPublic function to support clients that had inlined the old version, 
> right?

This is correct; you may well end up with newer versions of a library that 
carry @abiPublic symbols only for compatibility reasons.

> Maybe this could be built into the hypothetical binary compatibility checker. 
> If there is no previous version or if the previous version didn’t have the 
> symbol and it’s never referenced then it’s an error. Would that work? Am I 
> overthinking this?

Yes, that would certainly be possible. We’ve discussed having an “ABI differ” 
tool as something we would really like to have, but so far no concrete design 
has been proposed. I expect this discussion will take on a greater urgency once 
we get close to shipping the second version of an “ABI stable” standard 
library. It’s obviously not needed the first time around.

Slava

> 
> On Dec 20, 2017, at 4:19 PM, Ted Kremenek via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> The review of "SE-0193 - Cross-module inlining and specialization" begins 
>> now and runs through January 5, 2018.
>> 
>> The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> Reviews are an important part of the Swift evolution process. All review 
>> feedback should be sent to the swift-evolution mailing list at:
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager. 
>> 
>> When replying, please try to keep the proposal link at the top of the 
>> message:
>> 
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> ...
>> Reply text
>> ...
>> Other replies
>> What goes into a review of a proposal?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and, eventually, determine the direction of 
>> Swift. 
>> 
>> When reviewing a proposal, here are some questions to consider:
>> 
>> What is your evaluation of the proposal?
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> Thanks,
>> Ted Kremenek
>> Review Manager
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Slava Pestov via swift-evolution


> On Dec 20, 2017, at 10:34 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
>> Perhaps a diagnostic like this would cause problems if you started with an 
>> @inlinable function that called an @abiPublic function and then in a 
>> subsequent version of your module you modified the @inlinable function such 
>> that it no longer calls the @abiPublic function. You would still need to 
>> keep that @abiPublic function to support clients that had inlined the old 
>> version, right?
> 
> This is correct; you may well end up with newer versions of a library that 
> carry @abiPublic symbols only for compatibility reasons.

Perhaps an “unused symbol checker” could skip @abiPublic declarations that have 
been marked as deprecated or unavailable.

Slava

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


Re: [swift-evolution] Preserving non-mutability of methods of an existential or generic object

2017-12-21 Thread Slava Pestov via swift-evolution
Hi Hooman,

Since the protocol P is not class-bounded, the requirement can be witnessed by 
a protocol extension method which re-assigns ‘self’:

protocol Initable {
  init()
}

extension P where Self : Initable {
  mutating func f(_ x: Int) -> Int {
self = Self()
return x
  }
}

class C : P, Initable {
  required init() {}
}

Now imagine you could do this,

let x: P & AnyObject

x.f(12)

This would be invalid because ‘x’ is a let binding but the requirement ‘f’ is 
witnessed by the protocol extension method, which performs a mutating access of 
‘self’.

Slava

> On Dec 21, 2017, at 6:01 PM, Hooman Mehr via swift-evolution 
>  wrote:
> 
> The title is confusing, let me clarify by example:
> 
> We have this protocol with a mutating method:
> 
> protocol P { mutating func f(_ x: Int) -> Int }
> 
> And a conforming class (which has to conform with a non-mutating method):
> 
> class C: P { func f(_ x: Int) -> Int { return x } }
> 
> An instance of this class can be used with a let constant:
> 
> let c = C()
> c.f(1) // OK
>  
> If we make it an existential object conforming to P, the immutability of the 
> method will be erased:
> 
> let c: AnyObject & P = C()
> c.f(1) // Cannot use mutating member on immutable value: 'c' is a 'let' 
> constant
> 
> A generic context has the same issue:
> 
> func f(_ arg: T)-> Int { return arg.f(1) } // Cannot use 
> mutating member on immutable value: ‘arg' is a 'let' constant
> 
> My question: 
> 
> Is it too much work to preserve method non-mutability in in these cases?
> 
> The workaround I am using is this:
> 
> protocol Q: class, P { func f(_ x: Int) -> Int } // 'Refine' it to be 
> non-mutating.
> extension C: Q {}
> 
> // Now these work:
> let c: Q = C()
> c.f(1) // OK
> func f(_ arg: T)-> Int { return arg.f(1) } // OK
> 
> This workaround creates a lot of duplication and is hard to maintain. It is 
> not something that I do often, but when I do, it is pretty annoying. 
> 
> Supplemental questions:
> 
> Have you guys ever ran into this?
> Is there already a bug tracking this? 
> 
> 
> ___
> 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-0193 - Cross-module inlining and specialization

2017-12-21 Thread Slava Pestov via swift-evolution
Hi Chris,

Thanks for reviewing the proposal!

> On Dec 20, 2017, at 11:14 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> On Dec 20, 2017, at 4:19 PM, Ted Kremenek > > wrote:
>> 
>> The review of "SE-0193 - Cross-module inlining and specialization" begins 
>> now and runs through January 5, 2018.
>> 
>> The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> When reviewing a proposal, here are some questions to consider:
>> 
>> What is your evaluation of the proposal?
>> 
> I am hugely supportive of the features that these attributes enable, but I 
> think that the spelling of this is absolutely wrong, and I’m disappointed 
> that the extensive discussion we’ve had for months about this didn’t make it 
> into (at least) the alternatives considered section.  Here are my concerns:

I’m totally aware of your earlier e-mail thread about tying this in with 
availability and I briefly mentioned it in the ‘future directions’ section. I 
don’t have any objections to your approach and I’d be open to changing the 
proposal if there’s some consensus that this is the right way to go.

Do you think exhaustive enums should be spelled as @available(exhaustive) (or 
@available(exhaustive: …)), also?

> Furthermore, these two attributes are the tip of the iceberg, and the core 
> team has spent a lot of time recently discussing the fact there are 
> potentially going to be about a dozen attributes similar to these 
> (fixed_contents,  global_var_is_directly_addressible, …)  that will only be 
> required for binary frameworks.

Hopefully not a dozen! But yes, there will probably be more than just the three 
currently under discussion.

> A minor point, but the specific name “abiPublic” is not great in my opinion, 
> because “ABI” is a term of art for compiler hackers.  Most users have no idea 
> what ABI means, and those who think they do often don’t.  Very few people 
> really understand what “stable ABI” means for example.
> 
> It would be better to go with something like “apiPublic” or “symbolPublic” or 
> “linkableButNotAccessible” or something else long.  This will not be commonly 
> used in user code, so being long and descriptive is a good thing.

Several other people in the thread also objected to the name abiPublic. I’m not 
attached to it and I would be open to changing it to something better. We just 
don’t have a clear winner yet...

> which generalizes properly when we add version ranges:
> 
>   @available(iOS 14, *)   // this was introduced in iOS 14
>   @available(linkerSymbol: iOS 15, *)  // this decl’s symbol became 
> “abiPublic" in iOS 15
>   @available(inlinable: iOS 16, *)  // this decl became inlinable in iOS 
> 16
>   public func foo() {… }

Minor nitpick: public implies ABI-public, so you probably meant the other way 
around, where a symbol became ABI public in iOS 14, then public in iOS 15. This 
is certainly something we need to support and my understanding is the 
equivalent already happens all the time in Objective-C land, where SPI becomes 
API.

> In short, respectfully request that you at least add this approach to the 
> "alternatives considered” section.

So, does anyone have any strong objections to Chris’s proposal?

>From an implementation standpoint, reworking the parser to parse 
>@available(inlinable) and @available(fixedContents) or whatever would be 
>straightforward. I would still like to punt the version range part of this to 
>a future proposal, though.

Slava

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-21 Thread Slava Pestov via swift-evolution
Hi Johannes,

Thanks for reviewing this proposal!

> On Dec 21, 2017, at 8:06 AM, Johannes Weiß via swift-evolution 
>  wrote:

> The library I'm working on will presumably never have stable ABI as you'd 
> naturally build it with your application. However we also don't want to miss 
> on the cross-module optimisation & specialisation and I suspect there are 
> quite a few (mostly open-source) libraries in the same space. I'm pretty sure 
> everybody would just end up littering their code with @abiPublic/@inlinable 
> (or the @available(...) syntax Chris Lattner proposed) without actually 
> meaning that.
> 
> Summing up: I think this feature is crucial but shouldn't come without a 
> compiler "where all declarations become implicitly @inlinable, and all 
> private and internal declarations become @abiPublic". I really don't want to 
> litter the code with attributes that aren't what I mean. (basically `swift 
> build --global-resilience-domain`) Having this compiler mode also makes these 
> attributes IMHO really niche and therefore I can only sympathise with's 
> Chris' sentiment to not litter the global attribute namespace.

I agree that a ‘completely non-resilient’ compiler mode would be great when 
building libraries that are always shipped together, and I hope Swift gains 
such a feature one day, possibly built on top of the very infrastructure used 
to implement this proposal!

However, the goal of this proposal is to formalize some language features that 
already exist and are used by the standard library. Clearly making everything 
fragile is a non-starter for the standard library in an ABI-stable world.

I do hope that this attribute is not abused in the manner in which you 
describe, but I’m not sure the potential for abuse is reason enough to not run 
the proposal — people are already using the underscored attribute today, 
risking source breakage and bugs due to insufficient test coverage in the 
future.

> C(++) as described in the proposal and Haskell 
> (https://wiki.haskell.org/Inlining_and_Specialisation 
> ), where {-# INLINABLE 
> myFunction #-} (quoting the docs) causes exactly two things to happens.
> 
>   • The function's (exact) definition is included in the interface file 
> for the module.
>   • The function will be specialised at use sites -- even across modules.
> Note that [the Haskell compiler] GHC is no more keen to inline an INLINABLE 
> function than any other.

Note that Swift’s compiler is the same — @inlinable does not influence 
optimizer decisions to inline or not.

Also currently the proposal is implemented by binary serialization of the SIL 
IR, but nothing in it precludes serializing inlinable function bodies as source 
code in the future — in fact we are likely to go in that direction if we 
implement the proposed textual ‘stable’ module format.

Slava

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


Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-21 Thread Slava Pestov via swift-evolution


> On Dec 21, 2017, at 9:33 AM, Tony Parker via swift-evolution 
>  wrote:
> 
> public
> public(inlinable)
> public(external) // *where we define external to be what abiPublic is now — 
> more bike shedding welcome

I think the downside is that public(external) or whatever @abiPublic becomes 
actually behaves like ‘internal’ as far as name lookup is concerned — a user 
might be confused if they see a public(external) declaration in a source file 
that they cannot actually call.

Also, @inlinable @abiPublic is a totally legit combination; here is an example:

@inlinable @abiPublic func foo() -> Int {
  return 42
}

@inlinable public func bar() -> Int {
  return foo()
}

A client module can call bar() (and inline and specialize it, which in turn 
might inline or specialize foo()). However, it cannot directly call foo(), 
since foo() is not visible in the source language.

To reiterate I’m totally open to alternate spellings for both attributes — I’m 
just not entirely sold on tying it in with the ‘public’ keyword.

Also tying this in with access control still has the problem Chris pointed out, 
where once version ranges are introduced, we have several completely different 
syntaxes and keywords that all take version ranges.

A final data point is that we already have a precedent for <>(<>) — the private(set) and internal(set) syntax for 
properties and subscripts. But here the syntax is used to denote something 
completely different, and it might be confusing to overload it further.

Slava

> 
> - Tony
> 
>> On Dec 20, 2017, at 11:14 PM, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Dec 20, 2017, at 4:19 PM, Ted Kremenek >> > wrote:
>>> 
>>> The review of "SE-0193 - Cross-module inlining and specialization" begins 
>>> now and runs through January 5, 2018.
>>> 
>>> The proposal is available here:
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>>  
>>> 
>>> When reviewing a proposal, here are some questions to consider:
>>> 
>>> What is your evaluation of the proposal?
>>> 
>> I am hugely supportive of the features that these attributes enable, but I 
>> think that the spelling of this is absolutely wrong, and I’m disappointed 
>> that the extensive discussion we’ve had for months about this didn’t make it 
>> into (at least) the alternatives considered section.  Here are my concerns:
>> 
>> Availability Ranges
>> 
>> Both of these attributes will (perhaps not for Swift 5 given the fact that 
>> these will be new then, but certainly in 5.1 or 6) need to be qualified by 
>> deployment modifiers.  We’ll need the ability to specify not just that a 
>> declaration is inlinable or abipublic, but in *which versions* of the binary 
>> package (that they are defined in) have this property.  
>> 
>> For example, while perhaps it will be common for a decl to be “born 
>> inlinable” and just need the form of attribute as specified here, it is just 
>> as clear that this is not the *only* model we need.  It is entirely 
>> reasonable (and will be important in the future) to say that something 
>> “became ABI public in iOS14, became abiPublic in iOS 15, and became 
>> inlinable in iOS16”.  The use of this will be relatively rare, but it is 
>> important for the model to support this in time.
>> 
>> Because of this, if we accept the spelling as proposed in this proposal, 
>> these attributes will need to be generalized to have an availability range, 
>> e.g.:
>> 
>>  @abipublic(iOS 15, *)
>> 
>> The concern is that this proposal opens the door to have a family of 
>> attributes each of which have availability information on them, and this 
>> “family” of attributes will have nothing tying them together into a unified 
>> framework.
>> 
>> 
>> Pollution of the Attribute Namespace
>> 
>> Furthermore, these two attributes are the tip of the iceberg, and the core 
>> team has spent a lot of time recently discussing the fact there are 
>> potentially going to be about a dozen attributes similar to these 
>> (fixed_contents,  global_var_is_directly_addressible, …)  that will only be 
>> required for binary frameworks.  It is possible that @inlinable will be 
>> prominent enough to be a global attribute (I personally am not sure if it 
>> will be commonly used or not, it depends a lot on how widely used binary 
>> frameworks are).  That said, it is clear @abiPublic will not be commonly 
>> used, and many attributes that follow these will be even more obscure.
>> 
>> This is bad for three reasons: 
>> 
>> 1) we’re polluting the general attribute namespace with obscure things.  
>> Pollution of the attribute namespace may have a marginal impact today, but 
>> will start to matter if/when we ever get user defined attributes.  
>> 
>> 2) The other reason is that this provid

Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-21 Thread Slava Pestov via swift-evolution


> On Dec 21, 2017, at 11:05 AM, Greg Titus via swift-evolution 
>  wrote:
> 
> I come from a perspective similar to Johannes, in that: for my work we are 
> interested in the performance improvements of cross-module optimization and 
> specialization but we regularly rebuild frameworks along with apps and 
> explicitly don’t need ABI versioning. Unlike him, I’m not that concerned with 
> littering attributes for inlinability around, but for our purposes the 
> original proposed spelling of @inlinable/@abiPublic or even better, Tony’s 
> proposed public(inlinable) makes for easier understanding when reading the 
> code than Chris’s proposed @available() extensions, which semantically leans 
> much more heavily on the ABI versioning concept that we won’t otherwise need.

Yeah, the main downside I can think of with Chris’s approach is that for 
developers publishing source-only packages, version number ranges are probably 
overkill. I believe Jordan had a similar objection at some point in our 
internal discussions. However, treating @inlinable as shorthand for 
@available(inlinable) might be sufficient.


> 
> And the Tony-style spelling of @abiPublic should _clearly_ be 
> “internal(external)” for its amazingly oxymoronic yet accurate spelling.

If oxymoronic spelling discourages abuse of these features, I’m all for it ;-)

Slava

> 
>   — Greg
> 
>> On Dec 21, 2017, at 8:06 AM, Johannes Weiß via swift-evolution 
>>  wrote:
>> 
>> 
>>> On 21 Dec 2017, at 12:19 am, Ted Kremenek via swift-evolution 
>>>  wrote:
>>> 
>>> The review of "SE-0193 - Cross-module inlining and specialization" begins 
>>> now and runs through January 5, 2018.
>>> 
>>> The proposal is available here:
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>> Reviews are an important part of the Swift evolution process. All review 
>>> feedback should be sent to the swift-evolution mailing list at:
>>> 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> or, if you would like to keep your feedback private, directly to the review 
>>> manager. 
>>> 
>>> When replying, please try to keep the proposal link at the top of the 
>>> message:
>>> 
>>> Proposal link: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>> ...
>>> Reply text
>>> ...
>>> Other replies
>>> What goes into a review of a proposal?
>>> 
>>> The goal of the review process is to improve the proposal under review 
>>> through constructive criticism and, eventually, determine the direction of 
>>> Swift. 
>>> 
>>> When reviewing a proposal, here are some questions to consider:
>>> 
>>> • What is your evaluation of the proposal?
>> 
>> I'm working on a performance sensitive library and we're sometimes bitten 
>> quite hard by not being able to cross-module inline & specialise. Therefore, 
>> it's thrilling to see that you're working in this area.
>> 
>> However, I have to admit that I believe this language feature will most 
>> likely be grossly abused. The library I'm working on will presumably never 
>> have stable ABI as you'd naturally build it with your application. However 
>> we also don't want to miss on the cross-module optimisation & specialisation 
>> and I suspect there are quite a few (mostly open-source) libraries in the 
>> same space. I'm pretty sure everybody would just end up littering their code 
>> with @abiPublic/@inlinable (or the @available(...) syntax Chris Lattner 
>> proposed) without actually meaning that.
>> 
>> Summing up: I think this feature is crucial but shouldn't come without a 
>> compiler "where all declarations become implicitly @inlinable, and all 
>> private and internal declarations become @abiPublic". I really don't want to 
>> litter the code with attributes that aren't what I mean. (basically `swift 
>> build --global-resilience-domain`) Having this compiler mode also makes 
>> these attributes IMHO really niche and therefore I can only sympathise 
>> with's Chris' sentiment to not litter the global attribute namespace.
>> 
>> 
>>> • Is the problem being addressed significant enough to warrant a change 
>>> to Swift?
>> 
>> see above.
>> 
>> 
>>> • Does this proposal fit well with the feel and direction of Swift?
>> 
>> to back up the 'swift' claim, cross-module inlining & specialisation is 
>> absolutely necessary. However this should also be achievable with a 'I don't 
>> need a stable ABI for this product' mode in the compiler :).
>> 
>> 
>>> • If you have used other languages or libraries with a similar feature, 
>>> how do you feel that this proposal compares to those?
>> 
>> C(++) as described in the proposal and Haskell 
>> (https://wiki.haskell.org/Inlining_and_Specialisation), where {-# INLINABLE 
>> myFunction #-} (quoting the docs) causes exactly two things to happens.
>> 
>>  • The function's (exact) definition is included in the interface file 
>> for

Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-21 Thread Slava Pestov via swift-evolution


> On Dec 21, 2017, at 12:42 PM, Paul Cantrell  wrote:
> 
> 1. Presumably the portions of A inlined into B and C remain sensitive to the 
> version-specific memory layout of A? Or will ABI stability mean that the 
> compiler can magically rearrange memory offsets in already-compiled code when 
> the layout changes? (Apologies if this is a too-obvious question; this part 
> of Swift is all a mystery to me.)

There is not really a notion of memory layout at the level of an entire module. 
For structs, classes and enums, you pretty much have the same concerns with 
both inlinable and non-inlinable functions — if the framework author can change 
the stored property layout of a struct or class (or adds a case to an enum), 
code that manipulates these data types must not make any compile-time 
assumptions that might be invalidated at runtime with a newer version of the 
framework.

This is basically what the upcoming @fixedContents proposal for structs is 
about — giving framework authors a way to trade future flexibility for 
performance by allowing the compiler to make assumptions about the layout of a 
struct as it is written at compile-time. The @exhaustive proposal for enums has 
a similar implementation angle, but is of course more interesting because it 
affects the source language as well, with switch statements.

We don’t plan on any kind of resilience opt-out for classes — already in 
shipping Swift compilers, accesses to stored properties of classes use accessor 
methods and not direct access across module boundaries.

> 2. Is there some class of statically identifiable breaking changes that the 
> compiler does (or should) detect to flag incompatible inlined code? e.g. some 
> version of A inlined into B references A.foo, then A.foo is deleted in a 
> later version of A, so mixing older B with newer A in a project gives a 
> compile- or link-time error?

This is what an “ABI differ” tool would achieve, but like I said it has not yet 
been designed.

> 3. Does this need some sort of poison pill feature for other sorts of 
> breaking changes that are not statically detectable? e.g. invariants of a 
> data structure in A change in release 2.0, so the author of A says “it is an 
> error to include A ≥2.0 in any project that inlined any of my code from a 
> version <2.0.” Is this what you were getting at with the mention of 
> @inlinable(2.0) in the proposal? Sounded like that part was about something 
> else, but I didn’t really grasp it tbh.

This is an interesting point and I think it is outside of the scope of these 
proposals. If the ABI of a library changes in an incompatible manner and 
previous binaries are no longer compatible with it, you should think of it as 
shipping a *new* library, either by changing it’s name or bumping the major 
version number, so that the dynamic linker prevents the client binary from 
being run in the first place.

> Yes, frameworks+app built simultaneously are clearly the more common case. 
> Though Carthage seems to be champing at the bit to create this problem, since 
> it added a feature to download prebuilt binaries long before ABI stability! I 
> can easily imagining this feature spreading via word of mouth as a “secret go 
> faster switch,” and causing no end of problems in the wild.

Perhaps, but I still think it is strictly better to formalize the feature 
through a proposal and document the pitfalls carefully — the underscored 
attribute is already spreading through word of mouth and in the absence of 
official documentation the potential for abuse is greater.

> It might be safer — and better match the understanding of the typical user — 
> to have @inlinable assume by default that an inlined version of any given 
> method is only valid only for the specific version of the module it was 
> inlined from. The compiler would by default flag any version mixing as an 
> error, and require an explicit statement of compatibility intent for each 
> piece of inlinable code to opt in to the danger zone of mixed versions.

How would this be implemented?

Slava

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-22 Thread Slava Pestov via swift-evolution


> On Dec 22, 2017, at 1:50 AM, Johannes Weiß  wrote:
> 
> totally agree that these attributes are necessary, they should be in Swift as 
> soon as we bike shedded the right name. But to prevent them from being placed 
> everywhere without thinking I propose to introduce a compiler mode at the 
> same time.
> Performance testing is hard and takes time. So I'm pretty sure that as soon 
> as one @abiPublic/@inlinable has proven to improve performance, library 
> authors will just start putting them anywhere as there's no downside besides 
> making the code harder to read.
> 
> What is the downside of bringing the attributes and the compiler mode at the 
> same time. Am I massively underestimating the amount of work required for 
> such mode?

ABI stability for the standard library is our top priority for Swift 5. While 
adding a ‘completely fragile’ compiler mode should be straightforward in 
theory, the devil is in the details, and I don’t think we can commit to 
delivering this feature any time soon.

> Cool. Just to be sure I understand you correctly: Assuming your proposal gets 
> implemented as proposed, a function that does _not_ have the @inlinable 
> attribute it won't be specialised across modules, ever. Correct?

That is correct. This is already the behavior today, so there’s no change here.

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


Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-22 Thread Slava Pestov via swift-evolution


> On Dec 22, 2017, at 9:55 AM, Chris Lattner  wrote:

> When and if we add private cases to enums, we’ll need to be able to associate 
> an availability range with an “exhaustive” marker.  When/if that happens, 
> then yes, we should do so through @available(exhaustive: iOS41, *).The 
> @exhaustive attribute will become sugar for “born exhaustive”, because in the 
> absence of private cases the availability range doesn’t matter (AFAIK).

It still matters if the enum was not “born exhaustive”. Recall that 
non-exhaustive enums and non-fixed contents structs are address-only types, 
because we don’t know their size at compile time and so they must be passed 
indirectly. So if your framework defines a non-exhaustive enum and a function 
taking or returning this enum, the calling convention will change if the enum 
becomes exhaustive (unless one of its cases is address-only for some other 
reason). So we will need to use availability ranges to declare that an enum 
became exhaustive after the fact. Such an enum will still be treated as 
non-exhaustive in the calling convention, but can otherwise be manipulated 
directly (as long as your deployment target is more recent than when it became 
exhaustive).

Slava

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


Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-22 Thread Slava Pestov via swift-evolution


> On Dec 22, 2017, at 7:09 PM, Xiaodi Wu  wrote:
> 
> On Fri, Dec 22, 2017 at 6:12 PM, Chris Lattner  > wrote:
> 
>> On Dec 22, 2017, at 1:03 PM, Xiaodi Wu > > wrote:
>> 
>>> In short, respectfully request that you at least add this approach to the 
>>> "alternatives considered” section.
>> 
>> So, does anyone have any strong objections to Chris’s proposal?
>> 
>> From an implementation standpoint, reworking the parser to parse 
>> @available(inlinable) and @available(fixedContents) or whatever would be 
>> straightforward. I would still like to punt the version range part of this 
>> to a future proposal, though.
>> 
>> 
>> I wish I had more time to compose a fully thought-out reply, but that's not 
>> going to happen in a little while because of outside constraints, so I'll 
>> spill a few thoughts here:
> 
> No rush, no worries, enjoy the holiday!
> 
>> I'm not a great fan of the @available(inlinable) notation.
>> 
>> For one, I have a hard time reasoning how Swift would behave when 
>> inlinability is tied to OS version. In this example, if the *app* (as 
>> opposed to the library) is compiled (as opposed to run) on iOS 16+, then the 
>> *library method* would potentially be emitted into the app, but if compiled 
>> on iOS 15 it wouldn't? Huh?
> 
> No: availability information kicks in based on what you are *deploying* to, 
> not what you’re compiling on.
> 
> I expect that this stuff will be extremely rarely used in practice, but 
> here’s an example:
> 
> iOS15 declares this public:
> 
> public void foo() {
>bar()
> }
> 
> iOS16 wants to promote foo to inlinable, but knows that the inlined body 
> doesn’t work with iOS15, because iOS15 needs the call to bar to happen (for 
> whatever reason)
> 
> @available(inlinable: iOS16)
> public void foo() {
> // nothing needed on iOS16 or later.
> }
> 
> Deployment platform makes more sense, but I still can't envision a real use 
> case. What sorts of `bar()` would hypothetically be necessary for iOS 15 but 
> not 16? Why would a third-party library need to increase its inlining 
> availability for an app based on deployment platform?

A better example would be if bar() was itself only available in iOS 16:

@available(iOS 15)
@available(inlinable: iOS 16)
public func foo() {
  bar()
}

@available(iOS 16)
public func bar() { … }

Suppose your app calls foo() and deploys to iOS 15. Then you cannot inline 
foo(), because bar() does not exist on iOS 15. (Presumably, foo() had a 
different implementation on iOS 15). But if you’re deploying to iOS 16, all is 
well, and you can inline foo(), which results in your app directly calling 
bar().

> I'm quite sure that the reason you inverted your "abiPublic" example is 
> because of the same issue. Intuitively, you would want to mark something as 
> "available" in version N and then maybe some special kind of "available" in 
> version N+1 (which @available(inlinable) would be). But 
> @available(linkerSymbol), as you spell it, suffers from a similar problem to 
> that of @available(unavailable): it's _not_ a special kind of API 
> availability, but rather indicates that something is less-than-available. 
> That is, you would use it to indicate that something is available as ABI but 
> not as API. In that sense, it extends the "mess" we have with 
> @available(unavailable).

I don’t think it’s quite the same thing as @available(unavailable). An 
@available(abiPublic) symbol would still be declared to have internal 
visibility, so in this case the @available attribute makes it strictly more 
visible than it would be without. We’re not going to spell it as 
‘@available(abiPublic) public’, which indeed would be confusing because the 
symbol is not actually public at the source level.

Slava

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


Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Slava Pestov via swift-evolution


> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>  wrote:
> 
> 
> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> 
>> What are your thoughts on `final switch` as a way to treat any enum as 
>> exhaustible?
>> https://dlang.org/spec/statement.html#FinalSwitchStatement 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> 
> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
> 
> Looking back at the proposal, I noticed that something similar was mentioned 
> that I earlier missed. In the proposal, it says:
> 
>> However, this results in some of your code being impossible to test, since 
>> you can't write a test that passes an unknown value to this switch.
> 
> Is that strictly true? Would it be theoretically possible for the compiler to 
> emit or make accessible a special ‘test’ case for non-exhaustive enums that 
> can only be used in test modules or e.g. by a ‘EnumName(testCaseNamed:)’, 
> constructor? There is  potential for abuse there but it would address that 
> particular issue. 
> 
> Regardless, I still feel something like a ‘final switch’ is necessary if this 
> proposal is introduced, and that it fits with the ‘progressive disclosure’ 
> notion; once you learn this keyword you have a means to check for 
> completeness, but people unaware of it could just use a ‘default’ case as per 
> usual and not be concerned with exhaustiveness checking. 

My general philosophy with syntax sugar is that it should do more than just 
remove a constant number of tokens. Basically you’re saying that

final switch x {}

just expands to

swift x {
default: fatalError()
}

I don’t think a language construct like this carries its weight.

For example, generics have a multiplicative effect on code size — they prevent 
you from having to write an arbitrary number of versions of the same algorithm 
for different concrete types.

Another example is optionals — while optionals don’t necessarily make code 
shorter, they make it more understandable, and having optionals in the language 
rules out entire classes of errors at compile time.

On the other hand, a language feature that just reduces the number of tokens 
without any second-order effects makes code harder to read, the language harder 
to learn, and the compiler buggier and harder to maintain without much benefit. 
So I think for the long term health of the language we should avoid ‘shortcuts’ 
like this.

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-23 Thread Slava Pestov via swift-evolution
Hi Dave,

The broader problem is being considered holistically, and we’re designing and 
implementing various pieces of the solution as part of the ABI stability effort 
for Swift 5. Some of these pieces impact the language, hence you’ll be seeing 
some evolution proposals. Non-exhaustive enums is one part, the inlinable 
proposal out for review right now is another part. There are a few more related 
proposals in the pipeline also.

Perhaps we need to do a better job of explaining how these things all tie 
together. In the mean time you can read about the overall design here: 
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst 


Slava

> On Dec 23, 2017, at 11:17 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> Continuing on this vein, there is another huge reason this proposal is 
> incomplete and won’t solve the problem.
> 
> This proposal, as I outlined previously, is all about binary compatibility 
> and functional resilience in the face of changing libraries. However, it 
> falls woefully short by only considering the binary implications of changing 
> enums.
> 
> The problem of binary compatibility extends *far* beyond the mutation of 
> enums between library versions. By only considering the “enum problem”, we 
> are ignoring a much larger and worse problem that will be even easier for 
> libraries to succumb to. It’s easy as a library author to inadvertently 
> rename a method or change the type of a parameter, or add a parameter, or 
> change the return type, or change the implementation semantics, or remove a 
> type, or remove a function, in such a way that a linking app cannot handle. 
> This is why the burden of binary compatibility rightfully rests on library 
> authors, and not app authors. 
> 
> The thing that changes has the responsibility to maintain compatibility for 
> the thing that hasn’t changed.
> 
> We should absolutely not implement this proposal; it only addresses a single 
> portion of a very large problem. Instead, we should figure out what the 
> broader binary compatibility story is. If we can answer *that* and provide 
> the necessary features to address it, then enum resilience will naturally 
> fall out of it. Focusing on the enum problem is focusing on the wrong problem.
> 
> Dave
> 
>> On Dec 21, 2017, at 11:02 AM, Dave DeLong > > wrote:
>> 
>> I realized further why we should not implement this proposal: It forces the 
>> problem of binary compatibility on the app developer, when experience has 
>> shown us that problem is better handled by the libraries.
>> 
>> Binary Compatibility
>> 
>> “Binary compatibility” is the notion that, even if the libraries you link 
>> against change, your app will still behave as it did when it was first 
>> compiled. For Swift apps these days, we don’t really have this problem, 
>> *yet*. We do have the problem of “binary compatibility” with Apple-provided 
>> frameworks, but those are all written in Objective-C, and so the question of 
>> “Swift” binary compatibility is still up-in-the-air.
>> 
>> Post-ABI stability, we still won’t have much issue with swift binary 
>> compatibility on Apple platforms, because there isn’t a mechanism to ship a 
>> framework to your users independently of an app update. So from the app POV, 
>> none of this will be a problem for Apple platform developers.
>> 
>> It will be a problem for non-Apple platform developers. As a simple example, 
>> let’s say I write a web app in Swift, and deploy it to a server that has 
>> some built-in Swift-on-the-server libraries. Here, my Swift app is decoupled 
>> from the libraries, and either one can update independently of each other. 
>> If the server owner decides to update from Swift 6 to Swift 6.1, that’s 
>> cool. But my web app should continue to run and behave *as if* the server 
>> were still running Swift 6, because it has not been re-compiled to use Swift 
>> 6.1 features.
>> 
>> This is the situation today on Apple platforms. Every app deployed to an 
>> Apple device includes a little piece of information in the executable file 
>> indicating which SDK was used to compile the app. At runtime, the system 
>> frameworks read this value and then alter their behavior accordingly. This 
>> is why apps written against the iOS 9 SDK continue to work on iOS 11 
>> devices; UIKit and friends are altering their behavior to provide iOS 9 
>> semantics. 
>> 
>> This is “binary compatibility”: the binary (your app) continues to be 
>> compatible with the dynamically linked frameworks present on the system, 
>> even though those frameworks may change.
>> 
>> When you have a setup where the frameworks do NOT provide binary 
>> compatibility, you end up in DLL Hell [1]. This is the same frustrating 
>> scenario when you’re in when you’re doing stuff with homebrew and find that 
>> this package you want has multiple dependencies, but these dependencies wa

Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Slava Pestov via swift-evolution
Hi Thomas,

I see what you mean now. I think in this case I would prefer to just spell this 
as ‘switch x { … unknown: … }’ vs ‘switch x { … default: … }’. But yes, a few 
people have signaled support for such a feature and I think it’s worth 
discussing.

Slava

> On Dec 23, 2017, at 4:27 PM, Thomas Roughton  wrote:
> 
> Hi Slava,
> 
> I think we may be referring to different things. For whatever it’s worth, I 
> agree with your reasoning on all the points you brought up. I also don’t 
> think having a 'default: fatalError()’ case is a good idea because then a 
> library change can cause crashes in a running version of an application.
> 
> What I mean by some sort of ‘complete switch’ statement is that it would be 
> compiled as per a normal ‘switch’ but error at compile time if it’s not 
> complete against the known set of cases as compile time. Assuming an enum 
> with known cases [a, b] at compile time,
> 
> switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   case b:
>   print(“b”)
>   default:
>   break
> }
> 
> would be exactly equivalent to:
> 
> complete switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   case b:
>   print(“b”)
>   unknown:  // the ‘unknown’ case would only be required for 
> non-exhaustive enums
>   break
> }
> 
> where the keywords ‘complete’ and ‘unknown’ are up for debate. If, however, 
> the programmer wrote:
> 
> complete switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   unknown:
>   break
> }
> 
> the compiler would give an error that there are unhandled cases in the switch 
> statement, whereas
> 
> switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   default:
>   break
> }
> 
> would compile without issue. If a user didn’t know about the existence of the 
> ‘complete switch’ construct, they could just use normal ‘switch’ statements 
> and miss out on the completeness checking.
> 
> Thomas
> 
>> On 24/12/2017, at 1:15 PM, Slava Pestov > > wrote:
>> 
>> 
>> 
>>> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
 
 What are your thoughts on `final switch` as a way to treat any enum as 
 exhaustible?
 https://dlang.org/spec/statement.html#FinalSwitchStatement 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> 
>>> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
>>> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
>>> 
>>> Looking back at the proposal, I noticed that something similar was 
>>> mentioned that I earlier missed. In the proposal, it says:
>>> 
 However, this results in some of your code being impossible to test, since 
 you can't write a test that passes an unknown value to this switch.
>>> 
>>> Is that strictly true? Would it be theoretically possible for the compiler 
>>> to emit or make accessible a special ‘test’ case for non-exhaustive enums 
>>> that can only be used in test modules or e.g. by a 
>>> ‘EnumName(testCaseNamed:)’, constructor? There is  potential for abuse 
>>> there but it would address that particular issue. 
>>> 
>>> Regardless, I still feel something like a ‘final switch’ is necessary if 
>>> this proposal is introduced, and that it fits with the ‘progressive 
>>> disclosure’ notion; once you learn this keyword you have a means to check 
>>> for completeness, but people unaware of it could just use a ‘default’ case 
>>> as per usual and not be concerned with exhaustiveness checking. 
>> 
>> My general philosophy with syntax sugar is that it should do more than just 
>> remove a constant number of tokens. Basically you’re saying that
>> 
>> final switch x {}
>> 
>> just expands to
>> 
>> swift x {
>> default: fatalError()
>> }
>> 
>> I don’t think a language construct like this carries its weight.
>> 
>> For example, generics have a multiplicative effect on code size — they 
>> prevent you from having to write an arbitrary number of versions of the same 
>> algorithm for different concrete types.
>> 
>> Another example is optionals — while optionals don’t necessarily make code 
>> shorter, they make it more understandable, and having optionals in the 
>> language rules out entire classes of errors at compile time.
>> 
>> On the other hand, a language feature that just reduces the number of tokens 
>> without any second-order effects makes code harder to read, the language 
>> harder to learn, and the

Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-24 Thread Slava Pestov via swift-evolution


> On Dec 24, 2017, at 3:04 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Proposal link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>  
> 
> What is your evaluation of the proposal ?
> 
> -1
> 
> The proposal puts all the emphasis on the programmer. It is better for the 
> compiler to decide if something is to be inclined both across modules and 
> within modules. 
> 
> If something is made public then it should be fixed for a given major version 
> number. No need for extra annotation. 
> 
> A module system that allows versioning is a better solution. 
> 
> 
Can you explain your proposed solution in more detail?

> No, cluttering up declarations is completely against the clarity of Swift. 
> For example who other than people on this group will understand 
> @inline(never) @inlinable. 
> 
> 
We don’t expect this attribute to be used frequently in third-party frameworks. 
@inline(never) @inlinable is a weird combination, but I hope that 
@inline(never) is used even less frequently. In fact other than debugging it 
probably doesn’t have much purpose at all, and it would be nice to deprecate it 
some day.
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> 
> Yes C and C++ and found the equivalent of these annotations problematic. In 
> Java they eliminated all this and let the compiler do the work. In practice 
> this works much better. 
> 
> 
The Java approach works because there’s no separate compilation — having a JIT 
means the optimizer is free to inline across module boundaries without any 
resilience considerations. This doesn’t fit with Swift’s compilation model 
though.

Slava

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


Re: [swift-evolution] namespacing protocols to other types

2017-12-24 Thread Slava Pestov via swift-evolution
There was a proposal to allow protocols to be nested inside types at one point 
but it didn’t move forward.

Basically, if the outer type is a non-generic class, struct or enum, there’s no 
conceptual difficulty at all.

If the outer type is a generic type or another protocol, you have a problem 
where the inner protocol can reference generic parameters or associated types 
of the outer type. This would either have to be banned, or we would need to 
come up with coherent semantics for it:

struct Generic {
  protocol P {
func f() -> T
  }
}

struct Conforms : Generic.P {
  func f() -> Int { … } // Like this?
}

let c = Conforms()
c is Generic.P // is this false? Ie, are Generic.P and 
Generic.P different protocols?

Slava

> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
>  wrote:
> 
> is there a reason why it’s not allowed to nest a protocol declaration inside 
> another type?
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-24 Thread Slava Pestov via swift-evolution


> On Dec 24, 2017, at 4:00 PM, Kelvin Ma via swift-evolution 
>  wrote:
> 
> why can’t we just remove inlineable functions from ABI altogether? if the 
> argument is that app code won’t be able to take advantage of improved 
> implementations in future library versions i don’t think that makes sense at 
> all i would assume client code gets recompiled much more often than library 
> code and their updates are much more likely to be downloaded by users than 
> library updates. 

This is not necessarily true. If Swift were to ship with the OS, updating the 
OS might install a new Swift standard library without updating all of your apps.

Slava

> 
> On Sun, Dec 24, 2017 at 6:04 PM, Howard Lovatt via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Proposal link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>  
> 
> What is your evaluation of the proposal <>?
> 
> -1
> 
> The proposal puts all the emphasis on the programmer. It is better for the 
> compiler to decide if something is to be inclined both across modules and 
> within modules. 
> 
> If something is made public then it should be fixed for a given major version 
> number. No need for extra annotation. 
> 
> A module system that allows versioning is a better solution. 
> 
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
> Yes significant but wrong solution 
> 
> Does this proposal fit well with the feel and direction of Swift?
> 
> No, cluttering up declarations is completely against the clarity of Swift. 
> For example who other than people on this group will understand 
> @inline(never) @inlinable. 
> 
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> 
> Yes C and C++ and found the equivalent of these annotations problematic. In 
> Java they eliminated all this and let the compiler do the work. In practice 
> this works much better. 
> 
> Perhaps the compiler should publish the SIL or LLVM for all public functions. 
> Analogous to Java’s class files. This sort of system works really will, much 
> better than C and C++. 
> 
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> 
> Followed the discussions and read the proposal. The proposal doesn’t seem to 
> encompass all the discussions. It would be nice if the proposal had a much 
> more extensive summary of alternatives suggested. 
> -- Howard. 
> 
> On 20 Dec 2017, at 7:19 pm, Ted Kremenek via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> The proposal is available here:
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> Reviews are an important part of the Swift evolution process. All review 
>> feedback should be sent to the swift-evolution mailing list at:
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager. 
>> 
>> When replying, please try to keep the proposal link at the top of the 
>> message:
>> 
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> ...
>> Reply text
>> ...
>> Other replies
>> What goes into a review of a proposal?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and, eventually, determine the direction of 
>> Swift. 
>> 
>> When reviewing a proposal, here are some questions to consider:
>> 
>> What is your evaluation of the proposal?
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-24 Thread Slava Pestov via swift-evolution


> On Dec 24, 2017, at 8:33 PM, Howard Lovatt  wrote:
> 
> I was making two seperate points: 1. Annotating which parts of a public APIs 
> are stable should not be necessary and 2. Inlining should be left to the 
> compiler. 
> 
> Point 1: If you had a module system that was versioned then a public 
> declaration should be taken as stable across all minor releases. IE You can 
> only add public declarations, not remove or change, for versions 1.x.x 
> compared to 1.0.0. 
> 
> That way you don’t need to separately annotate which bits of the API are 
> stable. All the public API is stable. 

The @abiPublic attribute as described in the proposal is only meant to be used 
for *internal* declarations which can be referenced from inlinable functions. 
Public functions are not annotated, and indeed as you describe, you cannot 
remove any public declaration if you’re publishing a source-stable or 
binary-stable library.

> Point 2: Functions that the compiler of a module decrees are potentially 
> inlinable should be published using SIL or LLVM so that they can be inlined 
> when the module is used either at compile time or runtime.

The reason the compiler cannot make the decision about what to inline across 
module boundaries is that this can end up exposing implementation details of 
the module. If everything can be inlined, you’re effectively doing static 
linking, which eliminates the ability to ship updated versions of a binary 
framework.

> It is important that it is something simple like SIL or LLVM to make inlining 
> light weight. That way the module compiler can be quite speculative about 
> inlining and make many functions available for inlining. In contrast the 
> compiler consuming the library can be conservative with a runtime back up if 
> in doubt. IE if the function is marginal then don’t inline until runtime has 
> proven that inlining is worth while. 

This is already how the optimizer works today. @inlinable annotations are not 
necessary to inline within a module, where the compiler makes all the decisions 
based on cost heuristics. Across modules @inlinable does not force any inlining 
either, it just makes the body available for the optimizer, if it decides to 
make use of it.

Slava

> 
> -- Howard. 
> 
> On 24 Dec 2017, at 9:53 pm, Slava Pestov  > wrote:
> 
>> 
>> 
>>> On Dec 24, 2017, at 3:04 PM, Howard Lovatt via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Proposal link: https://github.com/apple/swift-evolution/blob/ 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>>  
>>> master/proposals/0193-cross-module-inlining-and-specialization.md
>>>  
>>> What
>>>  is your evaluation of the proposal ?
>>> 
>>> -1
>>> 
>>> The proposal puts all the emphasis on the programmer. It is better for the 
>>> compiler to decide if something is to be inclined both across modules and 
>>> within modules. 
>>> 
>>> If something is made public then it should be fixed for a given major 
>>> version number. No need for extra annotation. 
>>> 
>>> A module system that allows versioning is a better solution. 
>>> 
>>> 
>> Can you explain your proposed solution in more detail?
>> 
>>> No, cluttering up declarations is completely against the clarity of Swift. 
>>> For example who other than people on this group will understand 
>>> @inline(never) @inlinable. 
>>> 
>>> 
>> We don’t expect this attribute to be used frequently in third-party 
>> frameworks. @inline(never) @inlinable is a weird combination, but I hope 
>> that @inline(never) is used even less frequently. In fact other than 
>> debugging it probably doesn’t have much purpose at all, and it would be nice 
>> to deprecate it some day.
>>> If you have used other languages or libraries with a similar feature, how 
>>> do you feel that this proposal compares to those?
>>> 
>>> Yes C and C++ and found the equivalent of these annotations problematic. In 
>>> Java they eliminated all this and let the compiler do the work. In practice 
>>> this works much better. 
>>> 
>>> 
>> The Java approach works because there’s no separate compilation — having a 
>> JIT means the optimizer is free to inline across module boundaries without 
>> any resilience considerations. This doesn’t fit with Swift’s compilation 
>> model though.
>> 
>> Slava
>> 

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


Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-24 Thread Slava Pestov via swift-evolution
Sure, users download new apps more often than they download new OSes, but 
you’re basically arguing against dynamic linking at this point. If everything 
was statically linked, vendors would not be able to ship security updates, etc.

Slava

> On Dec 24, 2017, at 8:46 PM, Kelvin Ma  wrote:
> 
> in theory this could happen but if you ask me this is such an exceedingly 
> rare case that i don’t count much net benefit from it. most ithing users 
> (that i know) avoid ios updates like hell but have automatic app updates 
> turned on. so 99% of the time i would expect the app version to be more 
> recent than the library version.
> 
> On Sun, Dec 24, 2017 at 9:59 PM, Slava Pestov  > wrote:
> 
> 
>> On Dec 24, 2017, at 4:00 PM, Kelvin Ma via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> why can’t we just remove inlineable functions from ABI altogether? if the 
>> argument is that app code won’t be able to take advantage of improved 
>> implementations in future library versions i don’t think that makes sense at 
>> all i would assume client code gets recompiled much more often than library 
>> code and their updates are much more likely to be downloaded by users than 
>> library updates. 
> 
> This is not necessarily true. If Swift were to ship with the OS, updating the 
> OS might install a new Swift standard library without updating all of your 
> apps.
> 
> Slava
> 
>> 
>> On Sun, Dec 24, 2017 at 6:04 PM, Howard Lovatt via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>  
>> 
>> What is your evaluation of the proposal <>?
>> 
>> -1
>> 
>> The proposal puts all the emphasis on the programmer. It is better for the 
>> compiler to decide if something is to be inclined both across modules and 
>> within modules. 
>> 
>> If something is made public then it should be fixed for a given major 
>> version number. No need for extra annotation. 
>> 
>> A module system that allows versioning is a better solution. 
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Yes significant but wrong solution 
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> No, cluttering up declarations is completely against the clarity of Swift. 
>> For example who other than people on this group will understand 
>> @inline(never) @inlinable. 
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> Yes C and C++ and found the equivalent of these annotations problematic. In 
>> Java they eliminated all this and let the compiler do the work. In practice 
>> this works much better. 
>> 
>> Perhaps the compiler should publish the SIL or LLVM for all public 
>> functions. Analogous to Java’s class files. This sort of system works really 
>> will, much better than C and C++. 
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> Followed the discussions and read the proposal. The proposal doesn’t seem to 
>> encompass all the discussions. It would be nice if the proposal had a much 
>> more extensive summary of alternatives suggested. 
>> -- Howard. 
>> 
>> On 20 Dec 2017, at 7:19 pm, Ted Kremenek via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> The proposal is available here:
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>>  
>>> 
>>> Reviews are an important part of the Swift evolution process. All review 
>>> feedback should be sent to the swift-evolution mailing list at:
>>> 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>>> or, if you would like to keep your feedback private, directly to the review 
>>> manager. 
>>> 
>>> When replying, please try to keep the proposal link at the top of the 
>>> message:
>>> 
>>> Proposal link: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
>>>  
>>> 
>>> ...
>>> Reply text
>>> ...
>>> Other replies
>>> What goes into a review of a proposal?
>>> 
>>> The goal of the review process is to improve the proposal under review 
>>> through constructive criticism and, eventually, determine the direction of 
>>> Swift. 
>>> 
>>> When reviewing a proposal, here are some questions to consider:
>>> 
>>> What is your evaluation of th

Re: [swift-evolution] Preserving non-mutability of methods of an existential or generic object

2018-01-03 Thread Slava Pestov via swift-evolution


> On Jan 3, 2018, at 5:33 PM, Hooman Mehr  wrote:
> 
> Thank you Slava, it is a very insightful answer. 
> 
> It also reveals a potential source for hard to track bugs. To make it easier 
> to see, lets add state to class C:
> 
> class D: C { var state = 0 }
> 
> var d = D() // Bad but common habit of declaring objects as var
> for i in 1...5 { d.f(i); d.state += 1 }
> print(d.state) // Prints 1
> 
> The result is surprising because a typical programmer does not expect an 
> object to have mutating methods (that replace the object itself with a 
> different one).
> 
> I think this is a bug in Swift compiler. It should not let a class “inherit” 
> a mutating method in this manner. Compiler should require a non-mutating 
> declaration of `f()` to satisfy `P` conformance for a class type.

Perhaps, but it’s also possible to define a mutating method g() in a protocol 
extension of P, where g() is not a protocol requirement. Calling g() on a class 
instance can “replace” self in this manner also.

> If we fix the above, it should be possible to do what I asked in my post: 
> When compiler knows an existential is an object, it should know all methods 
> are non-mutating and accept `let` declaration despite calls to nominally 
> mutating methods. Also, if a protocol refines another protocol to be 
> class-bound, compiler should automatically refine all of its inherited 
> mutating methods to be non-mutating and allow `let` declaration of an 
> existential of that protocol even if there are calls to those originally 
> mutating methods. 

This will prevent you from defining default implementations of protocol 
requirements in protocol extensions, which would be a source-breaking change at 
this point. I don’t think we can make such a change now.

Slava

> 
> Hooman
> 
>> On Dec 21, 2017, at 10:59 PM, Slava Pestov > > wrote:
>> 
>> Hi Hooman,
>> 
>> Since the protocol P is not class-bounded, the requirement can be witnessed 
>> by a protocol extension method which re-assigns ‘self’:
>> 
>> protocol Initable {
>>   init()
>> }
>> 
>> extension P where Self : Initable {
>>   mutating func f(_ x: Int) -> Int {
>> self = Self()
>> return x
>>   }
>> }
>> 
>> class C : P, Initable {
>>   required init() {}
>> }
>> 
>> Now imagine you could do this,
>> 
>> let x: P & AnyObject
>> 
>> x.f(12)
>> 
>> This would be invalid because ‘x’ is a let binding but the requirement ‘f’ 
>> is witnessed by the protocol extension method, which performs a mutating 
>> access of ‘self’.
>> 
>> Slava
>> 
>>> On Dec 21, 2017, at 6:01 PM, Hooman Mehr via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> The title is confusing, let me clarify by example:
>>> 
>>> We have this protocol with a mutating method:
>>> 
>>> protocol P { mutating func f(_ x: Int) -> Int }
>>> 
>>> And a conforming class (which has to conform with a non-mutating method):
>>> 
>>> class C: P { func f(_ x: Int) -> Int { return x } }
>>> 
>>> An instance of this class can be used with a let constant:
>>> 
>>> let c = C()
>>> c.f(1) // OK
>>>  
>>> If we make it an existential object conforming to P, the immutability of 
>>> the method will be erased:
>>> 
>>> let c: AnyObject & P = C()
>>> c.f(1) // Cannot use mutating member on immutable value: 'c' is a 'let' 
>>> constant
>>> 
>>> A generic context has the same issue:
>>> 
>>> func f(_ arg: T)-> Int { return arg.f(1) } // Cannot use 
>>> mutating member on immutable value: ‘arg' is a 'let' constant
>>> 
>>> My question: 
>>> 
>>> Is it too much work to preserve method non-mutability in in these cases?
>>> 
>>> The workaround I am using is this:
>>> 
>>> protocol Q: class, P { func f(_ x: Int) -> Int } // 'Refine' it to be 
>>> non-mutating.
>>> extension C: Q {}
>>> 
>>> // Now these work:
>>> let c: Q = C()
>>> c.f(1) // OK
>>> func f(_ arg: T)-> Int { return arg.f(1) } // OK
>>> 
>>> This workaround creates a lot of duplication and is hard to maintain. It is 
>>> not something that I do often, but when I do, it is pretty annoying. 
>>> 
>>> Supplemental questions:
>>> 
>>> Have you guys ever ran into this?
>>> Is there already a bug tracking this? 
>>> 
>>> 
>>> ___
>>> 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] Checking in; more thoughts on arrays and variadic generics

2017-01-27 Thread Slava Pestov via swift-evolution

> On Jan 27, 2017, at 11:44 AM, Karl Wagner via swift-evolution 
>  wrote:
> 
> So, 2 quick points:
> 
> 1) I have often wanted a shorthand for expressing long tuples; I definitely 
> think that’s something worth bike-shedding, e.g. - (String * 4, Int32 * 4) or 
> something

Why not define a struct, or a tuple consisting of two arrays?

> 2) Having a special non-growing array type which is called “array” and 
> separate from Array is not such a good idea IMO. I would rather allow 
> tuples to conform to protocols (see: 
> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>  
> ).
> 
> If tuples could conform to protocols, we could say “any tuple of homogenous 
> elements is a Collection”. There would be benefits for the standard library, 
> too - EmptyCollection would disappear, replaced with the empty tuple (),

This sounds too clever.

> as would CollectionOfOne, to be replaced by a single-element tuple (T).

For what it’s worth, Swift doesn’t have single-element tuples. (T) is just 
sugar for the type T itself.

> We would also be able to remove our limited-arity == overloads in favour of 
> actual, honest-to-goodness Equatable conformance.

I like this idea though.

> 
> - Karl
>  
> ___
> 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] Checking in; more thoughts on arrays and variadic generics

2017-01-28 Thread Slava Pestov via swift-evolution

> On Jan 27, 2017, at 4:55 PM, Karl Wagner  wrote:
> 
> 
>> On 27 Jan 2017, at 22:25, Slava Pestov > > wrote:
>> 
>> 
>>> On Jan 27, 2017, at 11:44 AM, Karl Wagner via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> So, 2 quick points:
>>> 
>>> 1) I have often wanted a shorthand for expressing long tuples; I definitely 
>>> think that’s something worth bike-shedding, e.g. - (String * 4, Int32 * 4) 
>>> or something
>> 
>> Why not define a struct, or a tuple consisting of two arrays?
> 
> Because I want a fixed-length guarantee; ([String], [Int]) could have any 
> number of Strings or Ints.

Ok, maybe a struct would named fields would be better though.

> It’s just a shorthand for defining long or complex tuples; we currently 
> import C arrays as massive tuples which can be basically impossible to read.

I agree that this is a problem — fixed length arrays should be imported better, 
once we have the right language features.

> 
>> 
>>> 2) Having a special non-growing array type which is called “array” and 
>>> separate from Array is not such a good idea IMO. I would rather allow 
>>> tuples to conform to protocols (see: 
>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>>>  
>>> ).
>>> 
>>> If tuples could conform to protocols, we could say “any tuple of homogenous 
>>> elements is a Collection”. There would be benefits for the standard 
>>> library, too - EmptyCollection would disappear, replaced with the empty 
>>> tuple (),
>> 
>> This sounds too clever.
> 
> Yeah… the cleverness is one of things I like about it. We get to remove these 
> canned conformances and reduce the stdlib surface area while gaining an 
> efficient way to express a fixed-size Collection. It would come with all 
> kinds of supplementary benefits, such as iterating and mapping the elements 
> of a tuple.
> 
>> 
>>> as would CollectionOfOne, to be replaced by a single-element tuple (T).
>> 
>> For what it’s worth, Swift doesn’t have single-element tuples. (T) is just 
>> sugar for the type T itself.
> 
> Would it be unreasonable to separate those, so that (T) is separate from T 
> instead of being a synonym for it? There is some awkwardness with tuples due 
> to legacy designs. Perhaps this would help clean it up a little (or perhaps 
> make it worse, who knows?)
> 
> For source compatibility, we could allow an implicit conversion; in the same 
> way that a T can be implicitly “promoted" to an Optional, it could be 
> implicitly “promoted” to a single-element tuple of T (and vice-versa).

Sure, we *could* re-design tuple types in a way where single element tuples 
make sense. Then we’d have to come up with a source compatibility story for 
Swift 3 vs Swift 4, fix any fallout (compiler crashes) from this change, 
implement migrator support when the stdlib is changed to use the new features, 
etc. But think of it this way — every such “unnecessary” change (and I realize 
this is subjective!) is taking away cycles the team could use to fix crashes, 
improve compiler speed, and improve diagnostics. Not to mention implementing 
the other evolution proposals which arguably increase expressive power in 
important ways we feel we need for ABI stability, such as generic subscripts.

> 
>> 
>>> We would also be able to remove our limited-arity == overloads in favour of 
>>> actual, honest-to-goodness Equatable conformance.
>> 
>> I like this idea though.
>> 
>>> 
>>> - Karl
>>>  
>>> ___
>>> 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] extending typealiases

2017-01-29 Thread Slava Pestov via swift-evolution

> On Jan 29, 2017, at 1:03 PM, Matt Whiteside via swift-evolution 
>  wrote:
> 
> In Swift 3.1, I was happy to see that we can now extend types with concrete 
> constraints.  I think one other feature which fits nicely with this new 
> capability would be extending typealiases, like this:
> 
> typealias Vector = Array
> 
> extension Vector { 
>...
> }
> 
> Which currently doesn't compile due to:  "Constrained extension must be 
> declared on the unspecialized generic type 'Array' with constraints specified 
> by a 'where’ clause”
> 
> What is other people’s interest level?  How possible would it be to add this?

I think this particular case would be pretty easy to add, but there is a more 
general case with generic typealiases that requires some thought:

typealias OptionalArray = Optional>

extension OptionalArray {
  …
}

Without generic typealiases, you might imagine this could be written as 
something like

extension  Optional> {
  …
}

I think this is called out in the generics manifesto as a potential future 
feature. I’m not sure how much work it would take to add it but I imagine it’s 
not entirely trivial.

Slava

> 
> -Matt
> 
> 
> 
> ___
> 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] Subclass Existentials

2017-01-29 Thread Slava Pestov via swift-evolution
This is a nice generalization of the existing protocol composition syntax. 
Implementation might get a little tricky — this touches a lot of things, such 
as inheritance clauses, constraints in generic signatures, and casts. It would 
require thorough testing.

There are also a few odd corner cases to sort out:

typealias T = SomeClass & SomeProtocol

class C : T { // should we allow this? probably yes
}

protocol P : T { // should we allow this? probably no
}

Slava

> On Jan 29, 2017, at 8:39 AM, David Hart via swift-evolution 
>  wrote:
> 
> Hello,
> 
> As promised, I wrote the first draft of a proposal to add class requirements 
> to the existential syntax. Please let me know what you think.
> 
> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md
>  
> 
> 
> Regards,
> David.
> 
> Existentials for classes conforming to protocols
> 
> Proposal: SE- 
> 
> Authors: David Hart , Austin Zheng 
> 
> Review Manager: TBD
> Status: TBD
>  
> Introduction
> 
> This proposal brings more expressive power to the type system by allowing 
> Swift to represent existentials of classes and subclasses which conform to 
> protocols.
> 
>  
> Motivation
> 
> Currently, the only existentials which can be represented in Swift are 
> conformances to a set of protocols, using the &syntax:
> 
> let existential: Hashable & CustomStringConvertible
> On the other hand, Objective-C is capable of expressing existentials of 
> subclasses conforming to protocols with the following syntax:
> 
> UIViewController* existential;
> We propose to provide similar expressive power to Swift, which will also 
> improve the bridging of those types from Objective-C.
> 
>  
> Proposed
>  solution
> 
> The proposal keeps the existing & syntax but allows the first element, and 
> only the first, to be of class type. The equivalent declaration to the above 
> Objective-C declaration would look like this:
> 
> let existential: UIViewController & UITableViewDataSource & 
> UITableViewDelegate
> As in Objective-C, this existential represents classes which have 
> UIViewController in their parent inheritance hierarchy and which also conform 
> to the UITableViewDataSource and UITableViewDelegate protocols.
> 
> As only the first element in the existential composition syntax can be a 
> class type, and by extending this rule to typealias expansions, we can make 
> sure that we only need to read the first element to know if it contains a 
> class requirement. As a consequence, here is a list of valid and invalid code 
> and the reasons for them:
> 
> let a: Hashable & CustomStringConvertible
> // VALID: This is still valid, as before
> 
> let b: MyObject & Hashable
> // VALID: This is the new rule which allows an object type in first position
> 
> let c: CustomStringConvertible & MyObject
> // INVALID: MyObject is not allowed in second position. A fix-it should help 
> transform it to:
> // let c: MyObject & CustomStringConvertible
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let d: Hashable & MyObjectStringConvertible
> // INVALID: The typealias expansion means that the type of d expands to 
> Hashable & MyObject & CustomStringConvertible, which has the class in the 
> wrong position. A fix-it should help transform it to:
> // let d: MyObjectStringConvertible & Hashable
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let e: MyOtherObject & MyObjectStringConvertible
> // INVALID: The typealias expansion would allow an existential with two class 
> requirements, which is invalid
> The following examples could technically be legal, but we believe we should 
> keep them invalid to keep the rules simple:
> 
> let a: MyObject & MyObject & CustomStringConvertible
> // This is equivalent to MyObject & CustomStringConvertible
> 
> let b: MyObjectSubclass & MyObject & Hashable
> // This is equivalent to MyObjectSubclass & Hashable
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let d: MyObject & MyObjectStringConvertible
> // This is equivalent to MyObject & CustomStringConvertible
>  
> Source
>  compatibility
> 
> This is a source breaking change. All types bridged from Objective-C which 
> use the equivalent Objective-C feature import without the pr

Re: [swift-evolution] Subclass Existentials

2017-01-29 Thread Slava Pestov via swift-evolution

> On Jan 29, 2017, at 2:05 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On Jan 29, 2017, at 3:52 PM, Xiaodi Wu > > wrote:
>> 
>> On Sun, Jan 29, 2017 at 3:35 PM, Matthew Johnson > > wrote:
>> 
>>> On Jan 29, 2017, at 3:24 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Sun, Jan 29, 2017 at 3:11 PM, Matthew Johnson >> > wrote:
>>> 
 On Jan 29, 2017, at 3:05 PM, Xiaodi Wu >>> > wrote:
 
 On Sun, Jan 29, 2017 at 2:40 PM, Matthew Johnson >>> > wrote:
 
> On Jan 29, 2017, at 2:25 PM, Xiaodi Wu  > wrote:
> 
> On Sun, Jan 29, 2017 at 2:16 PM, Matthew Johnson  > wrote:
> 
>> On Jan 29, 2017, at 2:01 PM, Xiaodi Wu > > wrote:
>> 
>> On Sun, Jan 29, 2017 at 1:37 PM, Matthew Johnson > > wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Jan 29, 2017, at 12:58 PM, Xiaodi Wu via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> Cool. Another avenue of improvement here is relaxing the single-class 
>>> spelling rule for the sake of composing typealiases.
>>> 
>>> As Matthew mentioned, if I have class Base and typealiases Foo = Base & 
>>> Protocol1 and Bar = Base & Protocol2, it'd be nice to allow Foo & Bar.
>>> 
>>> It'd be nice to go one step further: given class Derived : Base, if I 
>>> have typealiases Foo2 = Base & Protocol1 and Bar2 = Derived & 
>>> Protocol2, then it could be permitted to write Foo2 & Bar2, since there 
>>> is effectively only one subclass requirement (Derived).
>>> 
>>> As I understand it, the rationale for allowing only one subclass 
>>> requirement is that Swift supports only single inheritance. Thus, two 
>>> disparate subclass requirements Base1 & Base2 would make your 
>>> existential type essentially equivalent to Never. But Base1 & Base1 & 
>>> Base1 is fine for the type system, the implementation burden (though 
>>> greater) shouldn't be too awful, and you would measurably improve 
>>> composition of typealiases.
>> 
>> Yes, this is what I was indicating in my post as well.
>> 
>> Are you suggesting that Base1 & Base2 compose to a type that is treated 
>> identically to Never do you think it should be an immediate compiler 
>> error?  I remember having some discussion about this last year and think 
>> somebody came up with a very interesting example of where the former 
>> might be useful.
>> 
>> Last year's discussion totally eludes me for some reason. But sure, if 
>> deferring the error until runtime is actually useful then why not? In 
>> the absence of an interesting use case, though, I think it'd be nice for 
>> the compiler to warn you that Base1 & Base2 is not going to be what you 
>> want.
> 
> Deferring to runtime isn’t what I mean.  If you try to actually *do* 
> anything that requires an instance of `Base1 & Based` (which you almost 
> always would) you would still get a compile time error.
> 
> I managed to dig up the example from last year’s thread and it is 
> definitely a good one:
> 
> func intersection(ts; Set, us: Set) -> Set
> 
> The desire is that we are always able to produce a result set.  When T & 
> U is uninhabitable it will simply be an empty set just like Set 
> has a single value which is the empty set.
> 
> Currently, Set is impossible because Never is not Hashable :)
 
 Ahh, good point.  I hadn’t tried it.  It can easily be made Hashable with 
 a simple extension though - this code compiles today:
 
 extension Never: Hashable {
 public var hashValue: Int { return 0 }
 }
 public func ==(lhs: Never, rhs: Never) -> Bool { return false }
 let s = Set()
 
> Since concrete types *can't* be used, this example seems like it'd be of 
> little use currently. How widely useful would it be to have an 
> intersection facility such as this when T != U even if that restriction 
> were lifted, though? Seems like the only real useful thing you can do 
> with generic Set is based on the fact that it'd be Set. 
> Other than those immediate thoughts, I'll have to think harder on this.
 
 Sure, it’s possible that this is the only interesting example and may not 
 have enough value to be worthwhile.  But I found it interesting enough 
 that it stuck around in the back of my mind for 8 months! :) 
  
 Hmm, it had not occurred to me: instantiating a Set is not 
 supported (and you can substitute for Hashable any protocol you want). 
 Thus, for any Set and Set that you can actually instantiate, unless

<    1   2   3   >