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

2017-11-25 Thread Mike Kluev via swift-evolution
On 25 November 2017 at 23:39, Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 5:21 PM, Mike Kluev  wrote:
>
>> On 25 November 2017 at 23:07, Xiaodi Wu  wrote:
>>
>>> Not sure what you’re asking. Equatable is a protocol.
>>>
>>
>> that's the point. i mean, if user writes this:
>>
>> extension (Equatable, Equatable) : Equatable
>>
>> what *else* could he mean other than this:
>>
>> extension  (T, R) : Equatable
>>
>
> No, it would mean extending the concrete type `(Equatable, Equatable)`
> (which has other roadblocks to becoming possible because Equatable has Self
> requirements).
>

>
>> and if it is indeed the only reasonable meaning we can think of - i'd say
>> the first notation is nicer.
>>
>>
>>> For a protocol P, (P, P) is a concrete type with two elements each of
>>> existential type P.
>>>
>>
>> this part i do not understand. protocol is not an existential type. or is
>> it?
>>
>
> Ah. You seem to be unfamiliar with protocol existentials. Protocols
> (currently, only those without Self or associated type requirements, for
> various implementation reasons) are themselves types. For example, you can
> write:
>
> ```
> protocol P { }
> extension Int : P { }
> let x: P = 42
> ```
>

thanks, indeed i was totally unaware of this. can't even find it in the
language reference.

if i decipher this correctly, the above example with Equatable is probably
"fine" (because Equatable has self requirement) but in other cases it won't
be fine.


> In this example, x is of type `P`, not of type `Int`. Let's clarify the
> difference:
>
> ```
> extension Array where Element == P {
>   func hi() {
> print("Hello")
>   }
> }
>
> extension Array where Element : P {
>   func hi() {
> print("World!")
>   }
> }
>
> let y: [P] = [x]
> let z: [Int] = [x as Int]
>
> y.hi() // Prints "Hello"
> z.hi() // Prints "World!"
> ```
>
> Moreover, if we do not write the first `extension Array`, then `y.hi()`
> doesn't compile. This helps to illustrate that P does not conform to itself.
>


thanks for example. too subtle feature imho. i never thought protocol could
be a type on it's own, makes the whole story more complex.

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


Re: [swift-evolution] Revisiting SE-0132 Rationalizing Sequence end-operation names

2017-11-25 Thread Step Christopher via swift-evolution
I second Xiaodi. The new names are much improved. Land them in 4.1 or as soon 
as possible. Depreciations in 5 and removal in 6, though stability may not 
allow removal. 

> On Nov 2, 2017, at 9:58 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Thu, Nov 2, 2017 at 7:26 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> During the Swift 3 cycle, I proposed SE-0132, "Rationalizing Sequence 
>> end-operation names". It was rejected because it needed revision and there 
>> was no time to do so. Since then, part of the proposal—partial ranges and 
>> the `RangeExpression` slicing protocol—has been adopted in SE-0172, 
>> "One-sided Ranges". I''d like to reopen discussion of the rest of the 
>> proposal.
>> 
>> To refresh your memory, SE-0132 proposed systematically renaming a number of 
>> `Sequence` and `Collection` methods which operate on the beginning and end 
>> of a sequence. Many of these methods have names borrowed directly from 
>> functional programming; they use terminology in conflicting ways and don't 
>> follow our conventions for non-mutating method names. For example, consider 
>> the inconsistent and API Guideline-violating names of a few members which 
>> operate on the beginning of a sequence or collection:
>> 
>> first   dropFirst() removeFirst()
>> prefix(_:)  dropFirst(_:)   
>> removeFirst(_:)
>> prefix(while:)  drop(while:)—
>> 
>> These members could be renamed to form consistent "families" where a given 
>> term always meant the same thing:
>> 
>> first   removingFirst() removeFirst()
>> prefix(_:)  removingPrefix(_:)  
>> removePrefix(_:)
>> prefix(while:)  removingPrefix(while:)  —
>> 
>> The main question in my mind about this plan is source stability. Back 
>> during Swift 3, we broke compatibility willy-nilly, but today we're being a 
>> little more circumspect. I believe these names meet the criteria of being 
>> actively harmful—they are difficult to discover, so developers don't use 
>> these members even when they should, and many of them sound like mutating 
>> methods or are unclear about their purpose—but that still doesn't tell us 
>> how we should treat the old names.
>> 
>> Basically, when should we introduce the new names?
>> 
>> 1. Swift 4.1 (or whatever pre-Swift 5 version the proposal ends up 
>> landing in)
>> 2. Swift 4.n (the version of Swift 5's compatibility mode for Swift 
>> 4)
>> 3. Swift 5
> 
> (All of the following IMHO:)
> 
> Swift 4.1 or whatever is closest. The new names are very clear, and their 
> introduction doesn't impair backwards compatibility.
>  
>> And when should we deprecate the old ones?
>> 
>> 1. Swift 4.1
>> 2. Swift 4.n
>> 3. Swift 5
>> 4. Swift 6
>> 5. Never
> 
> Deprecation warnings: Swift 5. Code continues to compile, and fix-its and a 
> migrator can get rid of the warning.
> Removal of deprecated API: Swift 6; ABI stability may require these symbols 
> to continue to exist though.
> 
>> I'm also open to discussion about whether this should be done at all, 
>> whether any additional methods should be included (or included methods 
>> should be left alone), whether the now-obsolete `prefix(from:)` 
>> `prefix(upTo:)`, and `prefix(through:)` methods should be left alone, 
>> deprecated, or removed, and whether this should be done in this proposal or 
>> a different one.
> 
> Could deprecate in Swift 5--don't feel strongly about this one. Definitely a 
> separate proposal.
>  
>> The original proposal, which lists all affected methods and explains the 
>> logic behind them, is available at 
>> .
>>  Keep in mind that the parts about ranges have already been incorporated 
>> into Swift in a revised form, so you can ignore them.
>> 
>> I'll get cracking on an implementation once we figure out what I should 
>> implement.
>> 
>> Thanks!
>  
> ___
> 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-25 Thread Tony Allevato via swift-evolution
Yeah, I realized that wasn’t true after sending it—it could come from an
imported module, as long as it’s visible. Still, I imagine that retroactive
conformance wouldn’t be an issue because when the compiler type checks the
default at the declaration site, it would only see declarations that it
already knows about.

As for locality, yes, that’s a drawback of my approach, but I still would
prefer it to an odd-looking annotation based approach that introduced a
whole new and different syntax for certain kinds of default arguments.

On Sat, Nov 25, 2017 at 3:18 PM Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 4:44 PM, Tony Allevato 
> wrote:
>
>> On Sat, Nov 25, 2017 at 2:35 PM Xiaodi Wu  wrote:
>>
>>> On Sat, Nov 25, 2017 at 4:25 PM, Tony Allevato 
>>> wrote:
>>>
 On Sat, Nov 25, 2017 at 1:16 PM Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
> wrote:
>
>> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>> It's kludgy, but we could have something like:
>>>
>>> ```
>>> @defaultArgument(configuration = (), where R.Configuration == Void)
>>> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
>>> func makeResource(with configuration: R.Configuration,
>>> actionHandler: @escaping (R.Action) -> Void) -> R { ... }
>>> ```
>>>
>>> I don't like that we'd be setting a default argument on something
>>> lexically before even encountering it in the declaration, but it's
>>> serviceable.
>>>
>>
>>
>> What if we could take advantage of the fact that you can have
>> non-constant expressions in default arguments? Overload resolution could
>> already do most of the job—what we need on top of that is a way for the
>> author to say that “if no overload matches, then it’s not an error—just
>> don’t have a default argument in that case”. Something like SFINAE in 
>> C++,
>> but more explicit.
>>
>> I’m imagining something like this:
>>
>> func defaultConfiguration() -> Void {
>>   return ()
>> }
>> func defaultActionHandler() -> (Never) -> Void {
>>   return { _ in }
>> }
>> struct ResourceDescription {
>>   func makeResource(
>> with configuration: R.Configuration *=?* defaultConfiguration(),
>> actionHandler: @escaping (R.Action) -> Void *=?* 
>> defaultActionHandler()
>>   ) -> R {
>> // create a resource using the provided configuration
>> // connect the action handler
>> // return the resource
>>   }
>> }
>>
>> The main difference here is the strawman =? syntax, which would
>> indicate that “the default argument exists if there is a way the RHS can 
>> be
>> satisfied for some instances of the generic arguments; otherwise, there 
>> is
>> no default”, instead of today’s behavior where it would be an error. 
>> There
>> could be multiple overloads of defaultConfiguration and
>> defaultActionHandler (even ones that are themselves generic) and it
>> would do the right thing when there are matches and when there aren’t.
>>
>> I like this approach because it mostly takes advantage of existing
>> language features and is fairly lightweight in terms of how it’s 
>> expressed
>> in code compared to regular default arguments—we’d just need to design 
>> the
>> new operator and type-checker logic around it.
>>
>> This is an interesting approach.  One advantage to something in this
>> direction is that it could support defining different defaults for the 
>> same
>> argument under different constraints by overloading the default argument
>> factories on their return type.
>>
>> One concern I have is that it doesn’t allows us to clearly define
>> under which constraints a default argument is available.  I suspect this
>> might be problematic especially for public interfaces where source
>> compatibility is a concern.
>>
>
> It's certainly an interesting idea but it would suggest that the
> constraints under which a default argument is available can change at
> runtime. I'm concerned, like you, that this is difficult to reason about.
> It is still unclear to me how widespread the underlying issue is that
> requires conditional default arguments, but the conversation thus far has
> been about compile-time constraints and Tony's design seems to envision
> much more than that.
>

 This runtime/reasoning problem *already exists* today with default
 arguments, because you can write something like this:

 

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

2017-11-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 5:21 PM, Mike Kluev  wrote:

> On 25 November 2017 at 23:07, Xiaodi Wu  wrote:
>
>> Not sure what you’re asking. Equatable is a protocol.
>>
>
> that's the point. i mean, if user writes this:
>
> extension (Equatable, Equatable) : Equatable
>
> what *else* could he mean other than this:
>
> extension  (T, R) : Equatable
>

No, it would mean extending the concrete type `(Equatable, Equatable)`
(which has other roadblocks to becoming possible because Equatable has Self
requirements).


> and if it is indeed the only reasonable meaning we can think of - i'd say
> the first notation is nicer.
>
>
>> For a protocol P, (P, P) is a concrete type with two elements each of
>> existential type P.
>>
>
> this part i do not understand. protocol is not an existential type. or is
> it?
>

Ah. You seem to be unfamiliar with protocol existentials. Protocols
(currently, only those without Self or associated type requirements, for
various implementation reasons) are themselves types. For example, you can
write:

```
protocol P { }
extension Int : P { }
let x: P = 42
```

In this example, x is of type `P`, not of type `Int`. Let's clarify the
difference:

```
extension Array where Element == P {
  func hi() {
print("Hello")
  }
}

extension Array where Element : P {
  func hi() {
print("World!")
  }
}

let y: [P] = [x]
let z: [Int] = [x as Int]

y.hi() // Prints "Hello"
z.hi() // Prints "World!"
```

Moreover, if we do not write the first `extension Array`, then `y.hi()`
doesn't compile. This helps to illustrate that P does not conform to itself.


For a type T : P, a tuple of type (T, T) is not a tuple of type (P, P). If
>> we can extend tuples, you can write a generic algorithm that works with any
>> type (T, T) where T : P, and/or you can write an algorithm that works with
>> concrete type (P, P). Note that there is no overlap between these two
>> because existential type P does not conform to protocol P.
>>
>>
> Mike
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Generalized supertype constraints

2017-11-25 Thread Dennis Weissmann via swift-evolution
You’re right, I misunderstood that paragraph (maybe I read what I wanted to 
read :D). Thank you very much for the clarification and I’ll take a closer look 
at your proposal tomorrow!

- Dennis

Sent from my iPhone

> On 25. Nov 2017, at 10:37 PM, Adrian Zubarev 
>  wrote:
> 
> Well no, this proposal won’t allow your example. The problem in your example 
> actually has different roots - *Metatypes*. As by today, meta types are 
> somehow broken, especially in generic / associated type context. Furthermore 
> there is currently no way to express that you may want a subtype for an 
> existential metatype instead of the static metatype.
> 
> For more informations about meta types and who some of us would like them to 
> work, read our proposal here:
> https://github.com/DevAndArtist/swift-evolution/blob/refactor_existential_metatypes/proposals/0126-refactor-metatypes.md
> 
> Then your example could be expressed as:
> 
> ```
> func register(_ service: Service, ofType type: Type) where AnyType : 
> AnyType {}
> 
> // or if I’m not mistaken we can make use if implicit existential like this 
> then
> func register(_ service: Service, ofType type: Type) where S : Service 
> {}
> ```
> 
> I don't want to dive any deeper about the metatype pain points, because I 
> don’t want to prevent the success of the pitched idea with an off-topic.
> 
> 
> Am 25. November 2017 um 16:34:58, Dennis Weissmann 
> (den...@dennisweissmann.me) schrieb:
> 
>> I would also love to have generic associated types in the language, I have a 
>> lot of uses for them and, IIUC, supertype constraint would enable me to 
>> express the following:
>> 
>> protocol Service {}
>> 
>> protocol WikiService: Service {} // methods not shown for conciseness
>> class DefaultWikiService: WikiService {}
>> class DemoWikiService: WikiService {}
>> 
>> class DataServiceManager {
>> 
>> private var registry = [String: Service]()
>> 
>> func register(_ service: Service, ofType type: S.Type) where S: 
>> Service {
>> let key = "\(Swift.type(of: type))"
>> registry[key] = service
>> }
>> 
>> func service(ofType type: S.Type) -> S where S: Service {
>> let key = "\(Swift.type(of: type))"
>> 
>> // It is a programmer error to expect a value for a not yet 
>> registered type
>> guard let service = registry[key] as? S else {
>> fatalError("Service of type \(type) cannot be found. Please 
>> register a service for that type before accessing it.")
>> }
>> return service
>> }
>> 
>> }
>> 
>> let manager = DataServiceManager()
>> if isDemoMode {
>> manager.register(DemoWikiService(), ofType: WikiService.self) // 
>> Currently: error: in argument type 'WikiService.Protocol', 'WikiService' 
>> does not conform to expected type 'Service'
>> } else {
>> manager.register(DefaultWikiService(), ofType: WikiService.self) // 
>> Currently: error: in argument type 'WikiService.Protocol', 'WikiService' 
>> does not conform to expected type 'Service'
>> }
>> 
>> If that's right, I'm also +1 on this :)
>> 
>> - Dennis
>> 
>>> On Nov 25, 2017, at 12:13 AM, Adrian Zubarev via swift-evolution 
>>>  wrote:
>>> 
>>> In general this is more then welcome, so +1 for me.
>>> 
>>> However I have one question:
>>> 
>>> Could this allow support, or at least be a first step towards Swift 
>>> allowing the following behaviour?
>>> 
>>> ```
>>> extension MyProtocol where Self : SomeClass {
>>> static func getSubtypes(ofType _: T.Type = T.self) -> [T] where T : Self 
>>> { ... }
>>> }
>>> ```
>>> 
>>> I would like to be able to upgrade `Self` to a class constraint, which then 
>>> will allow me to only accept subtypes from T at compile time.
>>> 
>>> Am 25. November 2017 um 00:03:23, Matthew Johnson via swift-evolution 
>>> (swift-evolution@swift.org) schrieb:
>>> 
 One of the most frequent frustrations I encounter when writing generic 
 code in Swift is the requirement that supertype constraints be concrete.  
 When I mentioned this on Twitter 
 (https://twitter.com/anandabits/status/929958479598534656) Doug Gregor 
 mentioned that this feature is smaller and mostly straightforward to 
 design and implement 
 (https://twitter.com/dgregor79/status/929975472779288576). 
 
 I currently have a PR open to add the high-level description of this 
 feature found below to the generics manifesto 
 (https://github.com/apple/swift/pull/13012):
 
 Currently, supertype constraints may only be specified using a concrete 
 class or protocol type.  This prevents us from abstracting over the 
 supertype.
 
 ```swift
 protocol P {
   associatedtype Base
   associatedtype Derived: Base
 }
 ```
 
 In the above example `Base` may be any type.  `Derived` may be the same as 
 `Base` or may be _any_ subtype of `Base`.  All subtype relationships 
 supported by Swift 

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

2017-11-25 Thread Mike Kluev via swift-evolution
on Date: Wed, 22 Nov 2017 08:01:16 +0100 David Hart 
wrote:

>
> What confuses me is that I always thought that T? was sugar for
> Optional by design, and found that to be quite elegant.


ditto, i thought the same.


> But now you’re telling me that its just a hack to allow conformance on
> Optionals until it can be made structural. I would have thought that it
> would be cleaner to have specific concepts (optionals, tuples, etc…)
> represented in terms of more general concepts (enum, struct) so that the
> compiler had less to reason about. I’m just trying to understand :-)
>

Mike
___
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-25 Thread Mike Kluev via swift-evolution
On 25 November 2017 at 23:07, Xiaodi Wu  wrote:

> Not sure what you’re asking. Equatable is a protocol.
>

that's the point. i mean, if user writes this:

extension (Equatable, Equatable) : Equatable

what *else* could he mean other than this:

extension  (T, R) : Equatable

and if it is indeed the only reasonable meaning we can think of - i'd say
the first notation is nicer.


> For a protocol P, (P, P) is a concrete type with two elements each of
> existential type P.
>

this part i do not understand. protocol is not an existential type. or is
it?


> For a type T : P, a tuple of type (T, T) is not a tuple of type (P, P). If
> we can extend tuples, you can write a generic algorithm that works with any
> type (T, T) where T : P, and/or you can write an algorithm that works with
> concrete type (P, P). Note that there is no overlap between these two
> because existential type P does not conform to protocol P.
>
>
Mike
___
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-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 4:44 PM, Tony Allevato 
wrote:

> On Sat, Nov 25, 2017 at 2:35 PM Xiaodi Wu  wrote:
>
>> On Sat, Nov 25, 2017 at 4:25 PM, Tony Allevato 
>> wrote:
>>
>>> On Sat, Nov 25, 2017 at 1:16 PM Xiaodi Wu  wrote:
>>>
 On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
 wrote:

> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> It's kludgy, but we could have something like:
>>
>> ```
>> @defaultArgument(configuration = (), where R.Configuration == Void)
>> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
>> func makeResource(with configuration: R.Configuration, actionHandler:
>> @escaping (R.Action) -> Void) -> R { ... }
>> ```
>>
>> I don't like that we'd be setting a default argument on something
>> lexically before even encountering it in the declaration, but it's
>> serviceable.
>>
>
>
> What if we could take advantage of the fact that you can have
> non-constant expressions in default arguments? Overload resolution could
> already do most of the job—what we need on top of that is a way for the
> author to say that “if no overload matches, then it’s not an error—just
> don’t have a default argument in that case”. Something like SFINAE in C++,
> but more explicit.
>
> I’m imagining something like this:
>
> func defaultConfiguration() -> Void {
>   return ()
> }
> func defaultActionHandler() -> (Never) -> Void {
>   return { _ in }
> }
> struct ResourceDescription {
>   func makeResource(
> with configuration: R.Configuration *=?* defaultConfiguration(),
> actionHandler: @escaping (R.Action) -> Void *=?* 
> defaultActionHandler()
>   ) -> R {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
>
> The main difference here is the strawman =? syntax, which would
> indicate that “the default argument exists if there is a way the RHS can 
> be
> satisfied for some instances of the generic arguments; otherwise, there is
> no default”, instead of today’s behavior where it would be an error. There
> could be multiple overloads of defaultConfiguration and
> defaultActionHandler (even ones that are themselves generic) and it
> would do the right thing when there are matches and when there aren’t.
>
> I like this approach because it mostly takes advantage of existing
> language features and is fairly lightweight in terms of how it’s expressed
> in code compared to regular default arguments—we’d just need to design the
> new operator and type-checker logic around it.
>
> This is an interesting approach.  One advantage to something in this
> direction is that it could support defining different defaults for the 
> same
> argument under different constraints by overloading the default argument
> factories on their return type.
>
> One concern I have is that it doesn’t allows us to clearly define
> under which constraints a default argument is available.  I suspect this
> might be problematic especially for public interfaces where source
> compatibility is a concern.
>

 It's certainly an interesting idea but it would suggest that the
 constraints under which a default argument is available can change at
 runtime. I'm concerned, like you, that this is difficult to reason about.
 It is still unclear to me how widespread the underlying issue is that
 requires conditional default arguments, but the conversation thus far has
 been about compile-time constraints and Tony's design seems to envision
 much more than that.

>>>
>>> This runtime/reasoning problem *already exists* today with default
>>> arguments, because you can write something like this:
>>>
>>> struct Foo {
>>>   static var defaultExponent = 2.0
>>>
>>>   func raise(_ x: Double, to exponent: Double = defaultExponent) {
>>> print(pow(x, exponent))
>>>   }
>>> }
>>> Foo().raise(4)  // "16.0"Foo.defaultExponent = 3.0Foo().raise(4)  // "64.0"
>>>
>>> Swift lets you write a default value expression that references static
>>> (but not instance) vars of the enclosing type, as well as anything else
>>> that’s visible from that expression’s scope. Should people do this?
>>> Probably not, for the reasons that you described.
>>>
>>> But the point is that my example is no more harmful or difficult to
>>> reason about than default arguments in the language today. My proposed
>>> solution *in no way* changes the runtime behavior of default 

Re: [swift-evolution] [Pitch #2] Introduce User-defined "Dynamic Member Lookup" Types

2017-11-25 Thread Chris Lattner via swift-evolution
On Nov 20, 2017, at 10:36 PM, Chris Lattner  wrote:
> Hi all,
> 
> I’ve significantly revised the ‘dynamic member lookup’ pitch, here’s the 
> second edition:
> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438
> 
> I’ve incorporated some minor changes to it:
> - I’ve made it possible to provide read-only dynamic members.
> - I’ve added an example JSON use-case which uses read-only dynamic members.
> - Minor wording changes.

Just to talk to myself a bit here, but I’ve come to realize that the right 
design really is to have a simple empty marker protocol like this:

/// Types type conform to this protocol have the behavior that member lookup -
/// accessing `someval.member` will always succeed.  Failures to find normally
/// declared members of `member` will be turned into subscript references using
/// the `someval[dynamicMember: member]` member.
///
public protocol DynamicMemberLookupProtocol {
  // Implementations of this protocol must have a subscript(dynamicMember:)
  // implementation where the keyword type is some type that is
  // ExpressibleByStringLiteral.  It can be get-only or get/set which defines
  // the mutability of the resultant dynamic properties.
  
  // subscript
  //  (dynamicMember name: KeywordType) -> LookupValue { get }
}


A design like this can almost work:

public protocol DynamicMemberLookupProtocol {
  associatedtype DynamicMemberLookupKeyword : ExpressibleByStringLiteral
  associatedtype DynamicMemberLookupValue
  
  subscript(dynamicMember name: DynamicMemberLookupKeyword)
-> DynamicMemberLookupValue { get }
}

The problem is that now everything that conforms to DynamicMemberLookupProtocol 
is a PAT, so it doesn’t work with existentials.  We could almost make due with 
a generic subscript:

public protocol DynamicMemberLookupProtocol {
  subscript
(dynamicMember name: KeywordType) -> LookupValue { get }
}

but it turns out that while you can declare that, nothing can actually conform 
to it with concrete types (I filed SR-6473, but it isn’t clear that it ever can 
work given how our generics system works).

Defining this as an empty marker protocol has several advantages:
 - Only one protocol is required
 - Suddenly you can define mutating getters and nonmutating setters
 - Existentials work as well as concrete types.

-Chris

___
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-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 16:44 Mike Kluev  wrote:

> On 25 November 2017 at 22:38, Xiaodi Wu  wrote:
>
>> On Sat, Nov 25, 2017 at 4:30 PM, Mike Kluev  wrote:
>>
>>>
 i haven't encounter this notation before so it looks strange and
>>> requires some effort to decipher. if it was e.g. in this form:
>>>
>>> extension (Equatable...) : Equatable
>>>
>>> then it would be immediately obvious what it means, IMHO
>>>
>>
>> That reads to me like you are extending a tuple of type `(Equatable...)`.
>> This is not the same as extending a tuple of type `(E...) where ...E :
>> Equatable`.
>>
>
> and if Equatable is not a type but a protocol then the practical
> difference is what ?
>

Not sure what you’re asking. Equatable is a protocol.

For a protocol P, (P, P) is a concrete type with two elements each of
existential type P. For a type T : P, a tuple of type (T, T) is not a tuple
of type (P, P). If we can extend tuples, you can write a generic algorithm
that works with any type (T, T) where T : P, and/or you can write an
algorithm that works with concrete type (P, P). Note that there is no
overlap between these two because existential type P does not conform to
protocol P.
___
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-25 Thread Dave Abrahams via swift-evolution
This sort of “it compiles if it’s syntactically valid, regardless of declared 
constraints” thing is deliberately avoided in Swift’s generics design with good 
reason; it’s possible that in this instance there are no problems, but I’m 
skeptical. 

Sent from my iPhone

> On Nov 25, 2017, at 1:16 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Sat, Nov 25, 2017 at 15:06 Matthew Johnson  wrote:
>>> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution 
>>>  wrote:
>>> 
>>> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
 It's kludgy, but we could have something like:
 
 ```
 @defaultArgument(configuration = (), where R.Configuration == Void)
 @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
 func makeResource(with configuration: R.Configuration, actionHandler: 
 @escaping (R.Action) -> Void) -> R { ... }
 ```
 
 I don't like that we'd be setting a default argument on something 
 lexically before even encountering it in the declaration, but it's 
 serviceable.
>>> 
>>> 
>>> What if we could take advantage of the fact that you can have non-constant 
>>> expressions in default arguments? Overload resolution could already do most 
>>> of the job—what we need on top of that is a way for the author to say that 
>>> “if no overload matches, then it’s not an error—just don’t have a default 
>>> argument in that case”. Something like SFINAE in C++, but more explicit.
>>> 
>>> I’m imagining something like this:
>>> 
>>> func defaultConfiguration() -> Void {
>>>   return ()
>>> }
>>> 
>>> func defaultActionHandler() -> (Never) -> Void {
>>>   return { _ in }
>>> }
>>> 
>>> struct ResourceDescription {
>>>   func makeResource(
>>> with configuration: R.Configuration =? defaultConfiguration(),
>>> actionHandler: @escaping (R.Action) -> Void =? defaultActionHandler()
>>>   ) -> R {
>>> // create a resource using the provided configuration
>>> // connect the action handler
>>> // return the resource
>>>   }
>>> }
>>> The main difference here is the strawman =? syntax, which would indicate 
>>> that “the default argument exists if there is a way the RHS can be 
>>> satisfied for some instances of the generic arguments; otherwise, there is 
>>> no default”, instead of today’s behavior where it would be an error. There 
>>> could be multiple overloads of defaultConfiguration and 
>>> defaultActionHandler (even ones that are themselves generic) and it would 
>>> do the right thing when there are matches and when there aren’t.
>>> 
>>> I like this approach because it mostly takes advantage of existing language 
>>> features and is fairly lightweight in terms of how it’s expressed in code 
>>> compared to regular default arguments—we’d just need to design the new 
>>> operator and type-checker logic around it.
>>> 
>> 
>> This is an interesting approach.  One advantage to something in this 
>> direction is that it could support defining different defaults for the same 
>> argument under different constraints by overloading the default argument 
>> factories on their return type.
>> 
>> One concern I have is that it doesn’t allows us to clearly define under 
>> which constraints a default argument is available.  I suspect this might be 
>> problematic especially for public interfaces where source compatibility is a 
>> concern.  
> 
> It's certainly an interesting idea but it would suggest that the constraints 
> under which a default argument is available can change at runtime. I'm 
> concerned, like you, that this is difficult to reason about. It is still 
> unclear to me how widespread the underlying issue is that requires 
> conditional default arguments, but the conversation thus far has been about 
> compile-time constraints and Tony's design seems to envision much more than 
> that.
> 
>> I think I prefer Xiaodi’s suggestion for that reason.  His approach could 
>> also support multiple defaults for the same parameter as long as the 
>> constraints are not allowed to overlap (overlapping constraints would result 
>> in ambiguity similar to ambiguous overload resolution) or an explicit 
>> argument is required if they do.
>> 
>>> 
>>> 
>>> 
 
 
> On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution 
>  wrote:
> I am all for this. are many types where there is an obvious 'zero' or 
> 'default' value and the ability to express "use that when possible" 
> without an overload is welcome.
> 
> 
> The best thing that I can think of right now, in terms of syntax, is 
> actually using @overload
> 
> ```
> struct ResourceDescription {
> 
>   func makeResource(with configuration: R.Configuration, actionHandler: 
> @escaping (R.Action) -> Void) -> R 
>  @overload(R.Configuration == 

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

2017-11-25 Thread Mike Kluev via swift-evolution
on Date: Thu, 23 Nov 2017 09:56:35 +1100 Howard Lovatt <
howard.lov...@gmail.com> wrote:

>
> I would defend turning tuples into structs (change from structural type to
> nominal type). This is a much better story for programmers, compare the two
> stories:
>
>1. Tuples are just syntax sugar for simple structs.
>2. Tuples are sort of like structs but there is a list of things tuples
>can do that structs can't and a list of things structs can do and tuples
>can't.
>
> I think unification can be achieved with some name mangling (Chris Lattner
> noted this previously - I am just spelling out one scheme), e.g.:
>
> // var a = (zero: 0, one: 1)
> public struct Tuple_zero_Int_one_Int { // Mangle name.
> public var zero: Int
> public var one: Int
> }
> var a = Tuple_zero_Int_one_Int(zero: 0, one: 1)
> // a.0 = -1
> a.zero = -1
>
> // var b = (0, 1)
> public struct Tuple_0_Int_1_Int { // Mangle name.
> public var _0_: Int // Unique name.
> public var _1_: Int // Unique name.
> }
> var b = Tuple_0_Int_1_Int(_0_: 0, _1_: 1)
> // a = b
> a = Tuple_zero_Int_one_Int(zero: b._0_, one: b._1_)
>
>
> Implicit in the above transformation is:
>
>1. struct and tuple have the same memory layout.
>2. `.0` access the 1st stored property of a struct, `.1` the 2nd, etc.
>

not sure about the name mangling per se, but the very idea of treating
tuples as structs is awesome and worth exploring.

Mike
___
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-25 Thread Mike Kluev via swift-evolution
On 25 November 2017 at 22:38, Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 4:30 PM, Mike Kluev  wrote:
>
>>
>>> i haven't encounter this notation before so it looks strange and
>> requires some effort to decipher. if it was e.g. in this form:
>>
>> extension (Equatable...) : Equatable
>>
>> then it would be immediately obvious what it means, IMHO
>>
>
> That reads to me like you are extending a tuple of type `(Equatable...)`.
> This is not the same as extending a tuple of type `(E...) where ...E :
> Equatable`.
>

and if Equatable is not a type but a protocol then the practical difference
is what ?

Mike
___
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-25 Thread Tony Allevato via swift-evolution
On Sat, Nov 25, 2017 at 2:35 PM Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 4:25 PM, Tony Allevato 
> wrote:
>
>> On Sat, Nov 25, 2017 at 1:16 PM Xiaodi Wu  wrote:
>>
>>> On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
>>> wrote:
>>>
 On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
 swift-evolution@swift.org> wrote:

 On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
 swift-evolution@swift.org> wrote:


 It's kludgy, but we could have something like:
>
> ```
> @defaultArgument(configuration = (), where R.Configuration == Void)
> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
> func makeResource(with configuration: R.Configuration, actionHandler:
> @escaping (R.Action) -> Void) -> R { ... }
> ```
>
> I don't like that we'd be setting a default argument on something
> lexically before even encountering it in the declaration, but it's
> serviceable.
>


 What if we could take advantage of the fact that you can have
 non-constant expressions in default arguments? Overload resolution could
 already do most of the job—what we need on top of that is a way for the
 author to say that “if no overload matches, then it’s not an error—just
 don’t have a default argument in that case”. Something like SFINAE in C++,
 but more explicit.

 I’m imagining something like this:

 func defaultConfiguration() -> Void {
   return ()
 }
 func defaultActionHandler() -> (Never) -> Void {
   return { _ in }
 }
 struct ResourceDescription {
   func makeResource(
 with configuration: R.Configuration *=?* defaultConfiguration(),
 actionHandler: @escaping (R.Action) -> Void *=?* defaultActionHandler()
   ) -> R {
 // create a resource using the provided configuration
 // connect the action handler
 // return the resource
   }
 }

 The main difference here is the strawman =? syntax, which would
 indicate that “the default argument exists if there is a way the RHS can be
 satisfied for some instances of the generic arguments; otherwise, there is
 no default”, instead of today’s behavior where it would be an error. There
 could be multiple overloads of defaultConfiguration and
 defaultActionHandler (even ones that are themselves generic) and it
 would do the right thing when there are matches and when there aren’t.

 I like this approach because it mostly takes advantage of existing
 language features and is fairly lightweight in terms of how it’s expressed
 in code compared to regular default arguments—we’d just need to design the
 new operator and type-checker logic around it.

 This is an interesting approach.  One advantage to something in this
 direction is that it could support defining different defaults for the same
 argument under different constraints by overloading the default argument
 factories on their return type.

 One concern I have is that it doesn’t allows us to clearly define under
 which constraints a default argument is available.  I suspect this might be
 problematic especially for public interfaces where source compatibility is
 a concern.

>>>
>>> It's certainly an interesting idea but it would suggest that the
>>> constraints under which a default argument is available can change at
>>> runtime. I'm concerned, like you, that this is difficult to reason about.
>>> It is still unclear to me how widespread the underlying issue is that
>>> requires conditional default arguments, but the conversation thus far has
>>> been about compile-time constraints and Tony's design seems to envision
>>> much more than that.
>>>
>>
>> This runtime/reasoning problem *already exists* today with default
>> arguments, because you can write something like this:
>>
>> struct Foo {
>>   static var defaultExponent = 2.0
>>
>>   func raise(_ x: Double, to exponent: Double = defaultExponent) {
>> print(pow(x, exponent))
>>   }
>> }
>> Foo().raise(4)  // "16.0"Foo.defaultExponent = 3.0Foo().raise(4)  // "64.0"
>>
>> Swift lets you write a default value expression that references static
>> (but not instance) vars of the enclosing type, as well as anything else
>> that’s visible from that expression’s scope. Should people do this?
>> Probably not, for the reasons that you described.
>>
>> But the point is that my example is no more harmful or difficult to
>> reason about than default arguments in the language today. My proposed
>> solution *in no way* changes the runtime behavior of default argument
>> expressions. I’m not envisioning anything more than what default arguments
>> can already do except for adding a way to choose different default
>> factories (or choose none without error) based on the 

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

2017-11-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 4:30 PM, Mike Kluev  wrote:

> On 25 November 2017 at 16:04, Xiaodi Wu  wrote:
>
>>
>> The workaround substantially bloats the standard library, and the result
>> is nothing close to the same because your type is still not Equatable. This
>> means that it cannot benefit from any generic algorithms. For example, an
>> array of such tuples cannot be Equatable in turn.
>>
>>>
>>
> i see. then the current workaround is not deep enough.
>
>
>> speaking of ugliness, the ellipsis on the left of names is quite ugly:
>>>
>>>  extension<...Elements : Equatable> (Elements...) : Equatable
>>>
>>
>> Seems perfectly fine to me.
>>
>
> i haven't encounter this notation before so it looks strange and requires
> some effort to decipher. if it was e.g. in this form:
>
> extension (Equatable...) : Equatable
>
> then it would be immediately obvious what it means, IMHO
>

That reads to me like you are extending a tuple of type `(Equatable...)`.
This is not the same as extending a tuple of type `(E...) where ...E :
Equatable`.
___
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-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 4:25 PM, Tony Allevato 
wrote:

> On Sat, Nov 25, 2017 at 1:16 PM Xiaodi Wu  wrote:
>
>> On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
>> wrote:
>>
>>> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>>
>>> It's kludgy, but we could have something like:

 ```
 @defaultArgument(configuration = (), where R.Configuration == Void)
 @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
 func makeResource(with configuration: R.Configuration, actionHandler:
 @escaping (R.Action) -> Void) -> R { ... }
 ```

 I don't like that we'd be setting a default argument on something
 lexically before even encountering it in the declaration, but it's
 serviceable.

>>>
>>>
>>> What if we could take advantage of the fact that you can have
>>> non-constant expressions in default arguments? Overload resolution could
>>> already do most of the job—what we need on top of that is a way for the
>>> author to say that “if no overload matches, then it’s not an error—just
>>> don’t have a default argument in that case”. Something like SFINAE in C++,
>>> but more explicit.
>>>
>>> I’m imagining something like this:
>>>
>>> func defaultConfiguration() -> Void {
>>>   return ()
>>> }
>>> func defaultActionHandler() -> (Never) -> Void {
>>>   return { _ in }
>>> }
>>> struct ResourceDescription {
>>>   func makeResource(
>>> with configuration: R.Configuration *=?* defaultConfiguration(),
>>> actionHandler: @escaping (R.Action) -> Void *=?* defaultActionHandler()
>>>   ) -> R {
>>> // create a resource using the provided configuration
>>> // connect the action handler
>>> // return the resource
>>>   }
>>> }
>>>
>>> The main difference here is the strawman =? syntax, which would
>>> indicate that “the default argument exists if there is a way the RHS can be
>>> satisfied for some instances of the generic arguments; otherwise, there is
>>> no default”, instead of today’s behavior where it would be an error. There
>>> could be multiple overloads of defaultConfiguration and
>>> defaultActionHandler (even ones that are themselves generic) and it
>>> would do the right thing when there are matches and when there aren’t.
>>>
>>> I like this approach because it mostly takes advantage of existing
>>> language features and is fairly lightweight in terms of how it’s expressed
>>> in code compared to regular default arguments—we’d just need to design the
>>> new operator and type-checker logic around it.
>>>
>>> This is an interesting approach.  One advantage to something in this
>>> direction is that it could support defining different defaults for the same
>>> argument under different constraints by overloading the default argument
>>> factories on their return type.
>>>
>>> One concern I have is that it doesn’t allows us to clearly define under
>>> which constraints a default argument is available.  I suspect this might be
>>> problematic especially for public interfaces where source compatibility is
>>> a concern.
>>>
>>
>> It's certainly an interesting idea but it would suggest that the
>> constraints under which a default argument is available can change at
>> runtime. I'm concerned, like you, that this is difficult to reason about.
>> It is still unclear to me how widespread the underlying issue is that
>> requires conditional default arguments, but the conversation thus far has
>> been about compile-time constraints and Tony's design seems to envision
>> much more than that.
>>
>
> This runtime/reasoning problem *already exists* today with default
> arguments, because you can write something like this:
>
> struct Foo {
>   static var defaultExponent = 2.0
>
>   func raise(_ x: Double, to exponent: Double = defaultExponent) {
> print(pow(x, exponent))
>   }
> }
> Foo().raise(4)  // "16.0"Foo.defaultExponent = 3.0Foo().raise(4)  // "64.0"
>
> Swift lets you write a default value expression that references static
> (but not instance) vars of the enclosing type, as well as anything else
> that’s visible from that expression’s scope. Should people do this?
> Probably not, for the reasons that you described.
>
> But the point is that my example is no more harmful or difficult to reason
> about than default arguments in the language today. My proposed solution *in
> no way* changes the runtime behavior of default argument expressions. I’m
> not envisioning anything more than what default arguments can already do
> except for adding a way to choose different default factories (or choose
> none without error) based on the *static* types of the generic arguments
> that are bound at a particular call site.
>
Unless I misunderstand, with your example, a method would retroactively
gain a default argument if 

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

2017-11-25 Thread Mike Kluev via swift-evolution
On 25 November 2017 at 16:04, Xiaodi Wu  wrote:

>
> The workaround substantially bloats the standard library, and the result
> is nothing close to the same because your type is still not Equatable. This
> means that it cannot benefit from any generic algorithms. For example, an
> array of such tuples cannot be Equatable in turn.
>
>>
>
i see. then the current workaround is not deep enough.


> speaking of ugliness, the ellipsis on the left of names is quite ugly:
>>
>>  extension<...Elements : Equatable> (Elements...) : Equatable
>>
>
> Seems perfectly fine to me.
>

i haven't encounter this notation before so it looks strange and requires
some effort to decipher. if it was e.g. in this form:

extension (Equatable...) : Equatable

then it would be immediately obvious what it means, IMHO

Mike
___
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-25 Thread David Sweeris via swift-evolution

> On Nov 25, 2017, at 08:05, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> 
>> On Sat, Nov 25, 2017 at 06:35 Mike Kluev  wrote:
>>> On 25 November 2017 at 03:12, Xiaodi Wu  wrote:
>> 
 On Fri, Nov 24, 2017 at 9:08 PM, Mike Kluev via swift-evolution 
  wrote:
>>> 
> On 24 November 2017 at 23:47, Douglas Gregor  wrote:
 
> 
> e.g., making all tuples of Equatable elements Equatable 
 
 that's already the case.. (all tuples of equatable elements are 
 equatable). no?
>>> 
>>> No, tuples do not conform to any protocols. There are hardcoded 
>>> implementations of `==` up to some arity in the stdlib to partially 
>>> mitigate the lack of protocol conformance.
>> 
>> to me as a user the end result is the same...
>> probably we need a better convincing example of what users may want that 
>> doesn't have a workaround now.
> 
> The workaround substantially bloats the standard library, and the result is 
> nothing close to the same because your type is still not Equatable. This 
> means that it cannot benefit from any generic algorithms. For example, an 
> array of such tuples cannot be Equatable in turn.
> 
>> speaking of ugliness, the ellipsis on the left of names is quite ugly:
>> 
>>  extension<...Elements : Equatable> (Elements...) : Equatable
> 
> Seems perfectly fine to me.

Agreed.

Speaking of which, have we started designing the syntax & semantics of the 
variadic generics/tuples system yet? I’ve been away from my computer a lot 
lately, and I tend to miss threads when subject lines gets truncated to 
“[swift-evolution][pitch] Some subj” on my phone.

- Dave Sweeris___
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-25 Thread Tony Allevato via swift-evolution
On Sat, Nov 25, 2017 at 1:16 PM Xiaodi Wu  wrote:

> On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
> wrote:
>
>> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>> It's kludgy, but we could have something like:
>>>
>>> ```
>>> @defaultArgument(configuration = (), where R.Configuration == Void)
>>> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
>>> func makeResource(with configuration: R.Configuration, actionHandler:
>>> @escaping (R.Action) -> Void) -> R { ... }
>>> ```
>>>
>>> I don't like that we'd be setting a default argument on something
>>> lexically before even encountering it in the declaration, but it's
>>> serviceable.
>>>
>>
>>
>> What if we could take advantage of the fact that you can have
>> non-constant expressions in default arguments? Overload resolution could
>> already do most of the job—what we need on top of that is a way for the
>> author to say that “if no overload matches, then it’s not an error—just
>> don’t have a default argument in that case”. Something like SFINAE in C++,
>> but more explicit.
>>
>> I’m imagining something like this:
>>
>> func defaultConfiguration() -> Void {
>>   return ()
>> }
>> func defaultActionHandler() -> (Never) -> Void {
>>   return { _ in }
>> }
>> struct ResourceDescription {
>>   func makeResource(
>> with configuration: R.Configuration *=?* defaultConfiguration(),
>> actionHandler: @escaping (R.Action) -> Void *=?* defaultActionHandler()
>>   ) -> R {
>> // create a resource using the provided configuration
>> // connect the action handler
>> // return the resource
>>   }
>> }
>>
>> The main difference here is the strawman =? syntax, which would indicate
>> that “the default argument exists if there is a way the RHS can be
>> satisfied for some instances of the generic arguments; otherwise, there is
>> no default”, instead of today’s behavior where it would be an error. There
>> could be multiple overloads of defaultConfiguration and
>> defaultActionHandler (even ones that are themselves generic) and it
>> would do the right thing when there are matches and when there aren’t.
>>
>> I like this approach because it mostly takes advantage of existing
>> language features and is fairly lightweight in terms of how it’s expressed
>> in code compared to regular default arguments—we’d just need to design the
>> new operator and type-checker logic around it.
>>
>> This is an interesting approach.  One advantage to something in this
>> direction is that it could support defining different defaults for the same
>> argument under different constraints by overloading the default argument
>> factories on their return type.
>>
>> One concern I have is that it doesn’t allows us to clearly define under
>> which constraints a default argument is available.  I suspect this might be
>> problematic especially for public interfaces where source compatibility is
>> a concern.
>>
>
> It's certainly an interesting idea but it would suggest that the
> constraints under which a default argument is available can change at
> runtime. I'm concerned, like you, that this is difficult to reason about.
> It is still unclear to me how widespread the underlying issue is that
> requires conditional default arguments, but the conversation thus far has
> been about compile-time constraints and Tony's design seems to envision
> much more than that.
>

This runtime/reasoning problem *already exists* today with default
arguments, because you can write something like this:

struct Foo {
  static var defaultExponent = 2.0

  func raise(_ x: Double, to exponent: Double = defaultExponent) {
print(pow(x, exponent))
  }
}
Foo().raise(4)  // "16.0"Foo.defaultExponent = 3.0Foo().raise(4)  // "64.0"

Swift lets you write a default value expression that references static (but
not instance) vars of the enclosing type, as well as anything else that’s
visible from that expression’s scope. Should people do this? Probably not,
for the reasons that you described.

But the point is that my example is no more harmful or difficult to reason
about than default arguments in the language today. My proposed solution *in
no way* changes the runtime behavior of default argument expressions. I’m
not envisioning anything more than what default arguments can already do
except for adding a way to choose different default factories (or choose
none without error) based on the *static* types of the generic arguments
that are bound at a particular call site.
​


> I think I prefer Xiaodi’s suggestion for that reason.  His approach could
>> also support multiple defaults for the same parameter as long as the
>> constraints are not allowed to overlap (overlapping constraints would
>> result in ambiguity similar to ambiguous overload resolution) or an
>> explicit 

Re: [swift-evolution] [Pitch] Generalized supertype constraints

2017-11-25 Thread Adrian Zubarev via swift-evolution
Well no, this proposal won’t allow your example. The problem in your example 
actually has different roots - *Metatypes*. As by today, meta types are somehow 
broken, especially in generic / associated type context. Furthermore there is 
currently no way to express that you may want a subtype for an existential 
metatype instead of the static metatype.

For more informations about meta types and who some of us would like them to 
work, read our proposal here:
https://github.com/DevAndArtist/swift-evolution/blob/refactor_existential_metatypes/proposals/0126-refactor-metatypes.md

Then your example could be expressed as:

```
func register(_ service: Service, ofType type: Type) where AnyType : 
AnyType {}

// or if I’m not mistaken we can make use if implicit existential like this then
func register(_ service: Service, ofType type: Type) where S : Service {}
```

I don't want to dive any deeper about the metatype pain points, because I don’t 
want to prevent the success of the pitched idea with an off-topic.


Am 25. November 2017 um 16:34:58, Dennis Weissmann (den...@dennisweissmann.me) 
schrieb:

I would also love to have generic associated types in the language, I have a 
lot of uses for them and, IIUC, supertype constraint would enable me to express 
the following:

protocol Service {}

protocol WikiService: Service {} // methods not shown for conciseness
class DefaultWikiService: WikiService {}
class DemoWikiService: WikiService {}

class DataServiceManager {

    private var registry = [String: Service]()

    func register(_ service: Service, ofType type: S.Type) where S: Service {
        let key = "\(Swift.type(of: type))"
        registry[key] = service
    }

    func service(ofType type: S.Type) -> S where S: Service {
        let key = "\(Swift.type(of: type))"

        // It is a programmer error to expect a value for a not yet registered 
type
        guard let service = registry[key] as? S else {
            fatalError("Service of type \(type) cannot be found. Please 
register a service for that type before accessing it.")
        }
        return service
    }

}

let manager = DataServiceManager()
if isDemoMode {
    manager.register(DemoWikiService(), ofType: WikiService.self) // Currently: 
error: in argument type 'WikiService.Protocol', 'WikiService' does not conform 
to expected type 'Service'
} else {
    manager.register(DefaultWikiService(), ofType: WikiService.self) // 
Currently: error: in argument type 'WikiService.Protocol', 'WikiService' does 
not conform to expected type 'Service'
}

If that's right, I'm also +1 on this :)

- Dennis

On Nov 25, 2017, at 12:13 AM, Adrian Zubarev via swift-evolution 
 wrote:

In general this is more then welcome, so +1 for me.

However I have one question:

Could this allow support, or at least be a first step towards Swift allowing 
the following behaviour?

```
extension MyProtocol where Self : SomeClass {
static func getSubtypes(ofType _: T.Type = T.self) -> [T] where T : Self { 
... }
}
```

I would like to be able to upgrade `Self` to a class constraint, which then 
will allow me to only accept subtypes from T at compile time.

Am 25. November 2017 um 00:03:23, Matthew Johnson via swift-evolution 
(swift-evolution@swift.org) schrieb:

One of the most frequent frustrations I encounter when writing generic code in 
Swift is the requirement that supertype constraints be concrete.  When I 
mentioned this on Twitter 
(https://twitter.com/anandabits/status/929958479598534656) Doug Gregor 
mentioned that this feature is smaller and mostly straightforward to design and 
implement (https://twitter.com/dgregor79/status/929975472779288576).

I currently have a PR open to add the high-level description of this feature 
found below to the generics manifesto 
(https://github.com/apple/swift/pull/13012):

Currently, supertype constraints may only be specified using a concrete class 
or protocol type.  This prevents us from abstracting over the supertype.

```swift
protocol P {
  associatedtype Base
  associatedtype Derived: Base
}
```

In the above example `Base` may be any type.  `Derived` may be the same as 
`Base` or may be _any_ subtype of `Base`.  All subtype relationships supported 
by Swift should be supported in this context including, but not limited to, 
classes and subclasses, existentials and conforming concrete types or refining 
existentials, `T?` and  `T`, `((Base) -> Void)` and `((Derived) -> Void)`, etc.

Generalized supertype constraints would be accepted in all syntactic locations 
where generic constraints are accepted.

I would like to see generalized supertype constraints make it into Swift 5 if 
possible.  I am not an implementer so I will not be able to bring a proposal 
forward alone but am interested in collaborating with anyone interested in 
working on implementation.

I am also interested in hearing general feedback on this feature from the 
community at large.  Have you also found this limitation 

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

2017-11-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 15:06 Matthew Johnson 
wrote:

> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> It's kludgy, but we could have something like:
>>
>> ```
>> @defaultArgument(configuration = (), where R.Configuration == Void)
>> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
>> func makeResource(with configuration: R.Configuration, actionHandler:
>> @escaping (R.Action) -> Void) -> R { ... }
>> ```
>>
>> I don't like that we'd be setting a default argument on something
>> lexically before even encountering it in the declaration, but it's
>> serviceable.
>>
>
>
> What if we could take advantage of the fact that you can have non-constant
> expressions in default arguments? Overload resolution could already do most
> of the job—what we need on top of that is a way for the author to say that
> “if no overload matches, then it’s not an error—just don’t have a default
> argument in that case”. Something like SFINAE in C++, but more explicit.
>
> I’m imagining something like this:
>
> func defaultConfiguration() -> Void {
>   return ()
> }
> func defaultActionHandler() -> (Never) -> Void {
>   return { _ in }
> }
> struct ResourceDescription {
>   func makeResource(
> with configuration: R.Configuration *=?* defaultConfiguration(),
> actionHandler: @escaping (R.Action) -> Void *=?* defaultActionHandler()
>   ) -> R {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
>
> The main difference here is the strawman =? syntax, which would indicate
> that “the default argument exists if there is a way the RHS can be
> satisfied for some instances of the generic arguments; otherwise, there is
> no default”, instead of today’s behavior where it would be an error. There
> could be multiple overloads of defaultConfiguration and
> defaultActionHandler (even ones that are themselves generic) and it would
> do the right thing when there are matches and when there aren’t.
>
> I like this approach because it mostly takes advantage of existing
> language features and is fairly lightweight in terms of how it’s expressed
> in code compared to regular default arguments—we’d just need to design the
> new operator and type-checker logic around it.
>
> This is an interesting approach.  One advantage to something in this
> direction is that it could support defining different defaults for the same
> argument under different constraints by overloading the default argument
> factories on their return type.
>
> One concern I have is that it doesn’t allows us to clearly define under
> which constraints a default argument is available.  I suspect this might be
> problematic especially for public interfaces where source compatibility is
> a concern.
>

It's certainly an interesting idea but it would suggest that the
constraints under which a default argument is available can change at
runtime. I'm concerned, like you, that this is difficult to reason about.
It is still unclear to me how widespread the underlying issue is that
requires conditional default arguments, but the conversation thus far has
been about compile-time constraints and Tony's design seems to envision
much more than that.

I think I prefer Xiaodi’s suggestion for that reason.  His approach could
> also support multiple defaults for the same parameter as long as the
> constraints are not allowed to overlap (overlapping constraints would
> result in ambiguity similar to ambiguous overload resolution) or an
> explicit argument is required if they do.
>
>
>
>
>
>>
>> On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> I am all for this. are many types where there is an obvious 'zero' or
>>> 'default' value and the ability to express "use that when possible" without
>>> an overload is welcome.
>>>
>>>
>>> The best thing that I can think of right now, in terms of syntax, is
>>> actually using @overload
>>>
>>> ```
>>> struct ResourceDescription {
>>>
>>>   func makeResource(with configuration: R.Configuration, actionHandler:
>>> @escaping (R.Action) -> Void) -> R
>>>  @overload(R.Configuration == Void) func makeResource(actionHandler:
>>> @escaping (R.Action) -> Void) -> R
>>> @overload(R.Action == Never)  func makeResource(with configuration:
>>> R.Configuration) -> R
>>> {
>>> // create a resource using the provided configuration
>>> // connect the action handler
>>> // return the resource
>>>   }
>>> }
>>> ```
>>>
>>>
>>> This isn't great though…
>>>
>>> On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 As mentioned in my prior message, I currently have a PR open to update
 the generics manifesto 

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

2017-11-25 Thread Thorsten Seitz via swift-evolution
I like Tony's idea. Maybe the default argument functions could even take 
arguments 
with earlier parameters from the parameter list.

-Thorsten 


> Am 25.11.2017 um 20:28 schrieb Tony Allevato via swift-evolution 
> :
> 
>> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> It's kludgy, but we could have something like:
>> 
>> ```
>> @defaultArgument(configuration = (), where R.Configuration == Void)
>> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
>> func makeResource(with configuration: R.Configuration, actionHandler: 
>> @escaping (R.Action) -> Void) -> R { ... }
>> ```
>> 
>> I don't like that we'd be setting a default argument on something lexically 
>> before even encountering it in the declaration, but it's serviceable.
> 
> What if we could take advantage of the fact that you can have non-constant 
> expressions in default arguments? Overload resolution could already do most 
> of the job—what we need on top of that is a way for the author to say that 
> “if no overload matches, then it’s not an error—just don’t have a default 
> argument in that case”. Something like SFINAE in C++, but more explicit.
> 
> I’m imagining something like this:
> 
> func defaultConfiguration() -> Void {
>   return ()
> }
> 
> func defaultActionHandler() -> (Never) -> Void {
>   return { _ in }
> }
> 
> struct ResourceDescription {
>   func makeResource(
> with configuration: R.Configuration =? defaultConfiguration(),
> actionHandler: @escaping (R.Action) -> Void =? defaultActionHandler()
>   ) -> R {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
> The main difference here is the strawman =? syntax, which would indicate that 
> “the default argument exists if there is a way the RHS can be satisfied for 
> some instances of the generic arguments; otherwise, there is no default”, 
> instead of today’s behavior where it would be an error. There could be 
> multiple overloads of defaultConfiguration and defaultActionHandler (even 
> ones that are themselves generic) and it would do the right thing when there 
> are matches and when there aren’t.
> 
> I like this approach because it mostly takes advantage of existing language 
> features and is fairly lightweight in terms of how it’s expressed in code 
> compared to regular default arguments—we’d just need to design the new 
> operator and type-checker logic around it.
> 
> 
> 
>> 
>> 
>>> On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution 
>>>  wrote:
>>> I am all for this. are many types where there is an obvious 'zero' or 
>>> 'default' value and the ability to express "use that when possible" without 
>>> an overload is welcome.
>>> 
>>> 
>>> The best thing that I can think of right now, in terms of syntax, is 
>>> actually using @overload
>>> 
>>> ```
>>> struct ResourceDescription {
>>> 
>>>   func makeResource(with configuration: R.Configuration, actionHandler: 
>>> @escaping (R.Action) -> Void) -> R 
>>>  @overload(R.Configuration == Void) func makeResource(actionHandler: 
>>> @escaping (R.Action) -> Void) -> R
>>> @overload(R.Action == Never)  func makeResource(with configuration: 
>>> R.Configuration) -> R
>>> {
>>> // create a resource using the provided configuration
>>> // connect the action handler
>>> // return the resource
>>>   }
>>> }
>>> ```
>>> 
>>> 
>>> This isn't great though…
>>> 
 On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution 
  wrote:
 As mentioned in my prior message, I currently have a PR open to update the 
 generics manifesto (https://github.com/apple/swift/pull/13012).  I removed 
 one topic from that update at Doug Gregor’s request that it be discussed 
 on the list first.  
 
 The idea is to add the ability to make default arguments conditional (i.e. 
 depend on generic constraints).  It is currently possible to emulate 
 conditional default arguments using an overload set.  This is verbose, 
 especially when several arguments are involved.  Here is an example use 
 case using the overload method to emulate this feature:
 
 ```swift
 protocol Resource {
   associatedtype Configuration
   associatedtype Action
 }
 struct ResourceDescription {
   func makeResource(with configuration: R.Configuration, actionHandler: 
 @escaping (R.Action) -> Void) -> R {
 // create a resource using the provided configuration
 // connect the action handler
 // return the resource
   }
 }
 
 extension ResourceDescription where R.Configuration == Void {
   func makeResource(actionHandler: @escaping (R.Action) -> Void) -> R {
 return makeResource(with: (), actionHandler: actionHandler)
   }
 }
 
 extension 

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

2017-11-25 Thread Matthew Johnson via swift-evolution

> On Nov 25, 2017, at 1:28 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution 
> > wrote:
> 
> 
> 
> It's kludgy, but we could have something like:
> 
> ```
> @defaultArgument(configuration = (), where R.Configuration == Void)
> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
> func makeResource(with configuration: R.Configuration, actionHandler: 
> @escaping (R.Action) -> Void) -> R { ... }
> ```
> 
> I don't like that we'd be setting a default argument on something lexically 
> before even encountering it in the declaration, but it's serviceable.
> 
> 
> What if we could take advantage of the fact that you can have non-constant 
> expressions in default arguments? Overload resolution could already do most 
> of the job—what we need on top of that is a way for the author to say that 
> “if no overload matches, then it’s not an error—just don’t have a default 
> argument in that case”. Something like SFINAE in C++, but more explicit.
> 
> I’m imagining something like this:
> 
> func defaultConfiguration() -> Void {
>   return ()
> }
> 
> func defaultActionHandler() -> (Never) -> Void {
>   return { _ in }
> }
> 
> struct ResourceDescription {
>   func makeResource(
> with configuration: R.Configuration =? defaultConfiguration(),
> actionHandler: @escaping (R.Action) -> Void =? defaultActionHandler()
>   ) -> R {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
> The main difference here is the strawman =? syntax, which would indicate that 
> “the default argument exists if there is a way the RHS can be satisfied for 
> some instances of the generic arguments; otherwise, there is no default”, 
> instead of today’s behavior where it would be an error. There could be 
> multiple overloads of defaultConfiguration and defaultActionHandler (even 
> ones that are themselves generic) and it would do the right thing when there 
> are matches and when there aren’t.
> 
> I like this approach because it mostly takes advantage of existing language 
> features and is fairly lightweight in terms of how it’s expressed in code 
> compared to regular default arguments—we’d just need to design the new 
> operator and type-checker logic around it.
> 
This is an interesting approach.  One advantage to something in this direction 
is that it could support defining different defaults for the same argument 
under different constraints by overloading the default argument factories on 
their return type.

One concern I have is that it doesn’t allows us to clearly define under which 
constraints a default argument is available.  I suspect this might be 
problematic especially for public interfaces where source compatibility is a 
concern.  

I think I prefer Xiaodi’s suggestion for that reason.  His approach could also 
support multiple defaults for the same parameter as long as the constraints are 
not allowed to overlap (overlapping constraints would result in ambiguity 
similar to ambiguous overload resolution) or an explicit argument is required 
if they do.

> 
> 
> 
> 
> 
> On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution 
> > wrote:
> I am all for this. are many types where there is an obvious 'zero' or 
> 'default' value and the ability to express "use that when possible" without 
> an overload is welcome.
> 
> 
> The best thing that I can think of right now, in terms of syntax, is actually 
> using @overload
> 
> ```
> struct ResourceDescription {
> 
>   func makeResource(with configuration: R.Configuration, actionHandler: 
> @escaping (R.Action) -> Void) -> R 
>  @overload(R.Configuration == Void) func makeResource(actionHandler: 
> @escaping (R.Action) -> Void) -> R
> @overload(R.Action == Never)  func makeResource(with configuration: 
> R.Configuration) -> R
> {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
> ```
> 
> 
> This isn't great though…
> 
> On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution 
> > wrote:
> As mentioned in my prior message, I currently have a PR open to update the 
> generics manifesto (https://github.com/apple/swift/pull/13012 
> ).  I removed one topic from that 
> update at Doug Gregor’s request that it be discussed on the list first.  
> 
> The idea is to add the ability to make default arguments conditional (i.e. 
> depend on generic constraints).  It is currently possible to emulate 
> conditional default arguments using an overload set.  This is verbose, 
> especially when several arguments are involved.  Here is an example use case 
> using 

Re: [swift-evolution] [Pitch] Raw mode string literals

2017-11-25 Thread Thorsten Seitz via swift-evolution

> Am 24.11.2017 um 20:13 schrieb Xiaodi Wu via swift-evolution 
> :
> 
>> On Thu, Nov 23, 2017 at 5:33 PM, Chris Lattner  wrote:
>>> On Nov 23, 2017, at 10:35 AM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> This proposed addition addresses a known pain point, to be sure, but I 
>>> think it has many implications for the future direction of the language and 
>>> I'd like to explore them here.
>> 
>> Thanks for writing this up Xiaodi,
>> 
>>> We should certainly move any discussion about regex literals into its own 
>>> thread, but to make it clear that I'm not simply suggesting that we 
>>> implement something in Swift 10 instead of addressing a known pain point 
>>> now, here's a sketch of how Swift 5 could make meaningful progress:
>>> 
>>> - Teach the lexer about basic /pattern/flag syntax.
>>> - Add an `ExpressibleByRegularExpressionLiteral`, where the initializer 
>>> would be something like `init(regularExpressionLiteralPattern: String, 
>>> flags: RegularExpressionFlags)` where RegularExpressionFlags would be an 
>>> OptionSet type.
>>> - Add conformance to `ExpressibleByRegularExpressionLiteral` to 
>>> `NSRegularExpression`.
>>> - Have no default `RegularExpressionLiteralType` for now so that, in the 
>>> future, we can discuss and design a Swift standard library regular 
>>> expression type, which is justifiable because we've baked in language 
>>> support for the literal. This can be postponed.
>> 
>> This approach could make sense, but it makes a couple of assumptions that 
>> I’m not certain are the right way to go (to be clear, I’m not certain that 
>> they’re wrong either!).
>> 
>> Things I’d like to carefully consider:
>> 
>> 1) We could make the compiler parse and validate regex literals at compile 
>> time:
>> 
>> a) this allows the compiler to emit diagnostics (with fixits!) on malformed 
>> literals.  
>> 
>> b) When the compiler knows the grammar of the regex, it can precompile the 
>> regex into a DFA table or static executable code, rather than runtime 
>> compiling into a bytecode.
>> 
>> c) however, the compiler can’t parse the literal unless it knows the dialect 
>> it corresponds to.  While we could parameterize this somehow (e.g. as a 
>> requirement in ExpressibleByRegularExpressionLiteral), if we weren’t bound 
>> by backwards compatibility, we would just keep things simple and say “there 
>> is one and only one grammar”.  I’d argue that having exactly one grammar 
>> supported by the // syntax is also *better* for users, rather than saying 
>> “it depends on what library you’re passing the regex into”.
> 
> I think we've circled back to a topic that we've discussed here before. I do 
> agree that having more of this validation at compile time would improve the 
> experience. However, I can see a few drawbacks to the _compiler_ doing the 
> validation:
> 
> - In the absence of a `constexpr`-like facility, supporting runtime 
> expressions would mean we'd be writing the same code twice, once in C++ for 
> compile-time validation of literal expressions and another time in Swift for 
> runtime expressions.
> 
> - As seen in these discussions about string literals where users want to copy 
> and paste text and have it "just work," supporting only one dialect in regex 
> literals will inevitably lead users to ask for other types of regex literals 
> for each individual flavor of regex they encounter.
> 
> Just like ExpressibleByDictionaryLiteral doesn't deduplicate keys, leaving 
> that to Dictionary, I think regex literals are better off not validating 
> literal expressions (or, maybe, doing only the barest sanity check), leaving 
> the rest to concrete regex types. As you point out with validation of integer 
> overflows during constant folding, we could get enough compile-time 
> validation even without teaching the compiler itself how to validate the 
> literal.
> 
>> 2) I’d like to explore the idea of making // syntax be *patterns* instead of 
>> simply literals.  As a pattern, it should be possible to bind submatches 
>> directly into variable declarations, eliminating the need to count parens in 
>> matches or other gross things.  Here is strawman syntax with a dumb example:
>> 
>> if case /([a-zA-Z]+: let firstName) ([a-zA-Z]+: let lastName)/ = 
>> getSomeString() {
>>print(firstName, lastName)
>> }
> 
> This is an interesting idea. But is it significantly more usable than the 
> same type having a collection of named matches using the usual Perl syntax?
> 
>   if case /(?[a-zA-Z]+) (?[a-zA-Z]+)/ = getSomeString() {
> print(Regex.captured["firstName"], Regex.captured["lastName"])
>   }
> 

Definitely. Not only is it much more readable, it is much safer as well, as the 
compiler will tell you that a name is not defined on a typo. Furthermore, as 
Chris suggested, this can be extended to directly get out other types than 
strings in a typesafe was (which should be extendible to user 

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

2017-11-25 Thread Tony Allevato via swift-evolution
On Fri, Nov 24, 2017 at 7:18 PM Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

It's kludgy, but we could have something like:
>
> ```
> @defaultArgument(configuration = (), where R.Configuration == Void)
> @defaultArgument(actionHandler = { _ in }, where R.Action == Never)
> func makeResource(with configuration: R.Configuration, actionHandler:
> @escaping (R.Action) -> Void) -> R { ... }
> ```
>
> I don't like that we'd be setting a default argument on something
> lexically before even encountering it in the declaration, but it's
> serviceable.
>
What if we could take advantage of the fact that you can have non-constant
expressions in default arguments? Overload resolution could already do most
of the job—what we need on top of that is a way for the author to say that
“if no overload matches, then it’s not an error—just don’t have a default
argument in that case”. Something like SFINAE in C++, but more explicit.

I’m imagining something like this:

func defaultConfiguration() -> Void {
  return ()
}
func defaultActionHandler() -> (Never) -> Void {
  return { _ in }
}
struct ResourceDescription {
  func makeResource(
with configuration: R.Configuration *=?* defaultConfiguration(),
actionHandler: @escaping (R.Action) -> Void *=?* defaultActionHandler()
  ) -> R {
// create a resource using the provided configuration
// connect the action handler
// return the resource
  }
}

The main difference here is the strawman =? syntax, which would indicate
that “the default argument exists if there is a way the RHS can be
satisfied for some instances of the generic arguments; otherwise, there is
no default”, instead of today’s behavior where it would be an error. There
could be multiple overloads of defaultConfiguration and defaultActionHandler
(even ones that are themselves generic) and it would do the right thing
when there are matches and when there aren’t.

I like this approach because it mostly takes advantage of existing language
features and is fairly lightweight in terms of how it’s expressed in code
compared to regular default arguments—we’d just need to design the new
operator and type-checker logic around it.



>
> On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I am all for this. are many types where there is an obvious 'zero' or
>> 'default' value and the ability to express "use that when possible" without
>> an overload is welcome.
>>
>>
>> The best thing that I can think of right now, in terms of syntax, is
>> actually using @overload
>>
>> ```
>> struct ResourceDescription {
>>
>>   func makeResource(with configuration: R.Configuration, actionHandler:
>> @escaping (R.Action) -> Void) -> R
>>  @overload(R.Configuration == Void) func makeResource(actionHandler:
>> @escaping (R.Action) -> Void) -> R
>> @overload(R.Action == Never)  func makeResource(with configuration:
>> R.Configuration) -> R
>> {
>> // create a resource using the provided configuration
>> // connect the action handler
>> // return the resource
>>   }
>> }
>> ```
>>
>>
>> This isn't great though…
>>
>> On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> As mentioned in my prior message, I currently have a PR open to update
>>> the generics manifesto (https://github.com/apple/swift/pull/13012).  I
>>> removed one topic from that update at Doug Gregor’s request that it be
>>> discussed on the list first.
>>>
>>> The idea is to add the ability to make default arguments conditional
>>> (i.e. depend on generic constraints).  It is currently possible to emulate
>>> conditional default arguments using an overload set.  This is verbose,
>>> especially when several arguments are involved.  Here is an example use
>>> case using the overload method to emulate this feature:
>>>
>>> ```swift
>>> protocol Resource {
>>>   associatedtype Configuration
>>>   associatedtype Action
>>> }
>>> struct ResourceDescription {
>>>   func makeResource(with configuration: R.Configuration, actionHandler:
>>> @escaping (R.Action) -> Void) -> R {
>>> // create a resource using the provided configuration
>>> // connect the action handler
>>> // return the resource
>>>   }
>>> }
>>>
>>> extension ResourceDescription where R.Configuration == Void {
>>>   func makeResource(actionHandler: @escaping (R.Action) -> Void) -> R {
>>> return makeResource(with: (), actionHandler: actionHandler)
>>>   }
>>> }
>>>
>>> extension ResourceDescription where R.Action == Never {
>>>   func makeResource(with configuration: R.Configuration) -> R {
>>> return makeResource(with: configuration, actionHandler: { _ in })
>>>   }
>>> }
>>>
>>> extension ResourceDescription where R.Configuration == Void, R.Action ==
>>> Never {
>>>   func makeResource() -> R {
>>> return makeResource(with: (), actionHandler: { _ in })
>>>   }
>>> }
>>>
>>> ```
>>>
>>> Adding language support for defining these more 

Re: [swift-evolution] [Pitch] Raw mode string literals

2017-11-25 Thread Magnus Ahltorp via swift-evolution

> 24 Nov. 2017 08:33 Chris Lattner via swift-evolution 
>  wrote:
> 
> 2) I’d like to explore the idea of making // syntax be *patterns* instead of 
> simply literals.  As a pattern, it should be possible to bind submatches 
> directly into variable declarations, eliminating the need to count parens in 
> matches or other gross things.  Here is strawman syntax with a dumb example:
> 
> if case /([a-zA-Z]+: let firstName) ([a-zA-Z]+: let lastName)/ = 
> getSomeString() {
>print(firstName, lastName)
> }

Erlang has something very similar for binaries, where constructing and matching 
a binary is part of the syntax.

For example:

C = <>

constructs a 64-bit binary C where the first bit comes from the integer 
variable A, and the rest from the integer variable B. In Erlang, this syntax is 
exactly the same when matching and constructing, so the corresponding syntax 
for matching is:

<> = C

where the 64-bit binary C is matched so that the first bit is put in the 
integer variable A and the rest is put in the integer variable B. If we don't 
want to match a variable to an integer but keep it as a binary, we can just 
mark the variable matching as a binary:

<> = C

which means that A will still be an integer (but in this case 8 bits wide) and 
B will be a binary.

Or if we want to do different things based on the first bit:

case C of
<<0:1, B:63>> ->
B;
<<1:1, B:63>> ->
B + 10
end

Making this kind of powerful syntax work for regular expressions would be very 
nice in Swift.

(And I would like it for binaries as well)

/Magnus

___
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-25 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 06:35 Mike Kluev  wrote:

> On 25 November 2017 at 03:12, Xiaodi Wu  wrote:
>
>> On Fri, Nov 24, 2017 at 9:08 PM, Mike Kluev via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On 24 November 2017 at 23:47, Douglas Gregor  wrote:
>>>

 e.g., making all tuples of Equatable elements Equatable


>>> that's already the case.. (all tuples of equatable elements are
>>> equatable). no?
>>>
>>
>> No, tuples do not conform to any protocols. There are hardcoded
>> implementations of `==` up to some arity in the stdlib to partially
>> mitigate the lack of protocol conformance.
>>
>>
> to me as a user the end result is the same...
> probably we need a better convincing example of what users may want that
> doesn't have a workaround now.
>

The workaround substantially bloats the standard library, and the result is
nothing close to the same because your type is still not Equatable. This
means that it cannot benefit from any generic algorithms. For example, an
array of such tuples cannot be Equatable in turn.

>
speaking of ugliness, the ellipsis on the left of names is quite ugly:
>
>  extension<...Elements : Equatable> (Elements...) : Equatable
>

Seems perfectly fine to me.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Generalized supertype constraints

2017-11-25 Thread Dennis Weissmann via swift-evolution
I would also love to have generic associated types in the language, I have a 
lot of uses for them and, IIUC, supertype constraint would enable me to express 
the following:

protocol Service {}

protocol WikiService: Service {} // methods not shown for conciseness
class DefaultWikiService: WikiService {}
class DemoWikiService: WikiService {}

class DataServiceManager {

private var registry = [String: Service]()

func register(_ service: Service, ofType type: S.Type) where S: Service {
let key = "\(Swift.type(of: type))"
registry[key] = service
}

func service(ofType type: S.Type) -> S where S: Service {
let key = "\(Swift.type(of: type))"

// It is a programmer error to expect a value for a not yet registered 
type
guard let service = registry[key] as? S else {
fatalError("Service of type \(type) cannot be found. Please 
register a service for that type before accessing it.")
}
return service
}

}

let manager = DataServiceManager()
if isDemoMode {
manager.register(DemoWikiService(), ofType: WikiService.self) // Currently: 
error: in argument type 'WikiService.Protocol', 'WikiService' does not conform 
to expected type 'Service'
} else {
manager.register(DefaultWikiService(), ofType: WikiService.self) // 
Currently: error: in argument type 'WikiService.Protocol', 'WikiService' does 
not conform to expected type 'Service'
}

If that's right, I'm also +1 on this :)

- Dennis

> On Nov 25, 2017, at 12:13 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> In general this is more then welcome, so +1 for me.
> 
> However I have one question:
> 
> Could this allow support, or at least be a first step towards Swift allowing 
> the following behaviour?
> 
> ```
> extension MyProtocol where Self : SomeClass {
>   static func getSubtypes(ofType _: T.Type = T.self) -> [T] where T : 
> Self { ... }
> }
> ```
> 
> I would like to be able to upgrade `Self` to a class constraint, which then 
> will allow me to only accept subtypes from T at compile time.
> 
> Am 25. November 2017 um 00:03:23, Matthew Johnson via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> One of the most frequent frustrations I encounter when writing generic code 
>> in Swift is the requirement that supertype constraints be concrete.  When I 
>> mentioned this on Twitter 
>> (https://twitter.com/anandabits/status/929958479598534656 
>> ) Doug Gregor 
>> mentioned that this feature is smaller and mostly straightforward to design 
>> and implement (https://twitter.com/dgregor79/status/929975472779288576 
>> ).
>> 
>> I currently have a PR open to add the high-level description of this feature 
>> found below to the generics manifesto 
>> (https://github.com/apple/swift/pull/13012 
>> ):
>> 
>> Currently, supertype constraints may only be specified using a concrete 
>> class or protocol type.  This prevents us from abstracting over the 
>> supertype.
>> 
>> ```swift
>> protocol P {
>>   associatedtype Base
>>   associatedtype Derived: Base
>> }
>> ```
>> 
>> In the above example `Base` may be any type.  `Derived` may be the same as 
>> `Base` or may be _any_ subtype of `Base`.  All subtype relationships 
>> supported by Swift should be supported in this context including, but not 
>> limited to, classes and subclasses, existentials and conforming concrete 
>> types or refining existentials, `T?` and  `T`, `((Base) -> Void)` and 
>> `((Derived) -> Void)`, etc.
>> 
>> Generalized supertype constraints would be accepted in all syntactic 
>> locations where generic constraints are accepted.
>> 
>> I would like to see generalized supertype constraints make it into Swift 5 
>> if possible.  I am not an implementer so I will not be able to bring a 
>> proposal forward alone but am interested in collaborating with anyone 
>> interested in working on implementation.
>> 
>> I am also interested in hearing general feedback on this feature from the 
>> community at large.  Have you also found this limitation frustrating?  In 
>> what contexts?  Does anyone have reservations about introducing this 
>> capability?  If so, what are they?
>> 
>> Matthew
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org

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

2017-11-25 Thread Mike Kluev via swift-evolution
On 25 November 2017 at 03:12, Xiaodi Wu  wrote:

> On Fri, Nov 24, 2017 at 9:08 PM, Mike Kluev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On 24 November 2017 at 23:47, Douglas Gregor  wrote:
>>
>>>
>>> e.g., making all tuples of Equatable elements Equatable
>>>
>>>
>> that's already the case.. (all tuples of equatable elements are
>> equatable). no?
>>
>
> No, tuples do not conform to any protocols. There are hardcoded
> implementations of `==` up to some arity in the stdlib to partially
> mitigate the lack of protocol conformance.
>
>
to me as a user the end result is the same...
probably we need a better convincing example of what users may want that
doesn't have a workaround now.

speaking of ugliness, the ellipsis on the left of names is quite ugly:

 extension<...Elements : Equatable> (Elements...) : Equatable

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