Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Douglas Gregor via swift-evolution


Sent from my iPhone

> On Aug 9, 2017, at 10:37 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> Well, if there is one, then I apologize for bothering anyone. I just assumed 
> it would be included in the proposal itself, and I couldn't find it myself.  
> ;)

This is a good point. We'll update the proposal template with a link to the 
implementation. 

  - Doug

> 
> Thank you David.
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> Am 10. August 2017 um 07:30:16, David Hart (da...@hartbit.com) schrieb:
> 
>> 
>>> On 10 Aug 2017, at 07:20, Adrian Zubarev via swift-evolution 
>>>  wrote:
>>> 
>>> Hi there, I don’t mean to be rude or something, nor do I want to hold the 
>>> review process up from succeeding, but where is the branch with the 
>>> implementation? 
>>> 
>>> Quote: 
>>> 
>>> The proposal phase for Swift 4 is now officially over
>>> I hope that the core team does not pick proposals they like, for instance 
>>> their own ones, and just skip the restriction of an implementation. I just 
>>> want to make sure that everyone plays with the same rules, so that it will 
>>> be fair for everyone
>>> 
>> I don’t know what gave you the impression the Core Team would bend the rules 
>> or play favorites. It’s not authored from an Apple engineer and, if you have 
>> a look at the PR for the proposal, there is a link to the implementation: 
>> https://github.com/apple/swift/pull/9619
>>> To strengthen up my criticism, here is a PR of a different proposal which 
>>> didn’t made it into Swift 4 but which was asked for an implementation 
>>> yesterday: 
>>> 
>>> https://github.com/apple/swift-evolution/pull/707
>>> 
>>> Have a nice review ;)
>>> 
>>> 
>>> 
>>> 
>>> 
>>> Am 10. August 2017 um 01:15:00, Chris Lattner via swift-evolution 
>>> (swift-evolution@swift.org) schrieb:
>>> 
 And of course, the correct proposal link is:
 https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
 
 
 > On Aug 9, 2017, at 4:10 PM, Chris Lattner  wrote:
 > 
 > I forgot to mention that the implementation of this feature is available 
 > here:
 > https://github.com/apple/swift/pull/9619
 > 
 > -Chris
 > 
 >> On Aug 9, 2017, at 4:08 PM, Chris Lattner  wrote:
 >> 
 >> Hello Swift community,
 >> 
 >> The review of SE-0185 - "Synthesizing Equatable and Hashable 
 >> conformance" begins now and runs through August 15, 2017. The proposal 
 >> is available here:
 >> https://github.com/apple/swift-evolution/blob/master/proposals/0182-newline-escape-in-strings.md
 >> 
 >> Reviews are an important part of the Swift evolution process. All 
 >> reviews should be sent to the swift-evolution mailing list at
 >> https://lists.swift.org/mailman/listinfo/swift-evolution
 >> 
 >> or, if you would like to keep your feedback private, directly to the 
 >> review manager. When replying, please try to keep the proposal link at 
 >> the top of the message:
 >> 
 >> What goes into a review?
 >> 
 >> The goal of the review process is to improve the proposal under review 
 >> through constructive criticism and, eventually, determine the direction 
 >> of Swift. When writing your review, here are some questions you might 
 >> want to answer in your review:
 >> 
 >> • What is your evaluation of the proposal?
 >> • Is the problem being addressed significant enough to warrant a change 
 >> to Swift?
 >> • Does this proposal fit well with the feel and direction of Swift?
 >> • If you have used other languages or libraries with a similar feature, 
 >> how do you feel that this proposal compares to those?
 >> • How much effort did you put into your review? A glance, a quick 
 >> reading, or an in-depth study?
 >> 
 >> More information about the Swift evolution process is available at:
 >> https://github.com/apple/swift-evolution/blob/master/process.md
 >> 
 >> 
 >> Thank you,
 >> 
 >> Chris Lattner
 >> Review Manager
 >> 
 >> 
 > 
 > ___
 > swift-evolution-announce mailing list
 > swift-evolution-annou...@swift.org
 > https://lists.swift.org/mailman/listinfo/swift-evolution-announce
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread David Ungar via swift-evolution
This strikes me as another good way to look at it.

Thanks guys,

- David

> On Aug 10, 2017, at 2:54 PM, Robert Bennett  wrote:
> 
> @Xiaodi I have a slightly different view of this. Currently, if you have a 
> type that conforms to a protocol, and you do not need to write any additional 
> code in order for the type to conform to the protocol, then the protocol must 
> have default implementations of its requirements. Because some types will be 
> able to conform to Equatable/Hashable without writing out the code to satisfy 
> the == and hashValue requirements, that logic (which you may or may not 
> subscribe to) would dictate that there is a default implementation of those 
> requirements (in this case, a magical default implementation that works for 
> many different types; maybe it uses Mirrors) — it certainly “feels” like 
> there is a default implementation to the user. And thus from an ergonomic 
> standpoint, these issues are not really orthogonal, even if they are distinct 
> implementation-wise.
> 
>> On Aug 10, 2017, at 5:41 PM, David Ungar > > wrote:
>> 
>> As long as I've been clear that the adoption of *this* proposal would 
>> transform a misspelling from a bug that the compiler catches to a bug that 
>> the compiler does not catch, I feel that my objection has been heard.
>> 
>> Thank you all,
>> 
>> - David
>> 
>>> On Aug 10, 2017, at 1:51 PM, Xiaodi Wu >> > wrote:
>>> 
>>> Right. The objection raised is applicable to the overriding of any default 
>>> implementation. However. _this_ proposal under review is about the 
>>> synthesis of a default implementation, and we shouldn’t try to invent new 
>>> syntax to address an orthogonal issue—and only partially at that.
>>> On Thu, Aug 10, 2017 at 14:45 Robert Bennett via swift-evolution 
>>> > wrote:
>>> Yes, thanks! Here’s the full proposal for those interested: 
>>> https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md
>>>  
>>> 
>>> 
>>> I think that if we want to deal with the issue of some mistake arising from 
>>> conforming to Equatable and/or Hashable, it should be through that 
>>> proposal, not something specific to Equatable and Hashable. This sort of 
>>> issue should not count against this Equatable/Hashable proposal.
>>> 
 On Aug 10, 2017, at 3:39 PM, Chris Lattner > wrote:
 
> 
> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
> > wrote:
> 
> I could have sworn that this sort of issue came up on this list earlier 
> this year… Someone proposed a mechanism encompassing all protocols, not 
> just Equatable and Hashable, to handle the issue of mistakenly believing 
> you’re overriding a default implementation. Having trouble finding it at 
> the moment.
 
 Is this what you’re thinking of?
 https://github.com/apple/swift-evolution/pull/724 
 
 
 -Chris
 
 
 
> .
> 
>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>> > wrote:
>> 
>> If I understand it, merely adding Equatable or Hashable will cause the 
>> compiler to synthesize requirements. This syntax opens up the 
>> possibility for errors:
>> 
>> struct Snort: Hashable {
>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>> }
>> 
>> In the above example, the programmer meant to implement hashValue but 
>> misspelled it.
>> With the proposal as-is, the error could be covered up.
>> 
>> I would prefer to see a different syntax than merely adding conformance 
>> to "HashValue", in order to distinguish the two cases: explicit 
>> supplying the requirement vs synthesis.
>> 
>> Also, what if we want to extend this idea to other protocols? Perhaps 
>> some sort of modifier on the protocol name would be more orthogonal:
>> 
>> struct Foo: Synth Hashable, Equatable 
>> 
>> Would say that Hashable requirements get synthesized but Equatable ones 
>> do not.
>> 
>> Alternatively, it might be clearer, though more verbose to move the 
>> signalling inside:
>> 
>> struct Snort: Hashable {
>> synth hashValue
>> }
>> 
>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>> possibly making it clearer to read the code.
>> 
>> TL;DR: I favor the proposal but would prefer modification to make it 
>> more 

Re: [swift-evolution] Enums and Source Compatibility - defaults

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 10, 2017, at 13:00, David Hart  wrote:
> 
> 
> 
> On 10 Aug 2017, at 19:19, Jordan Rose  > wrote:
> 
>> 
>> 
>>> On Aug 9, 2017, at 22:46, David Hart >> > wrote:
>>> 
>>> 
 On 10 Aug 2017, at 02:42, Jordan Rose > wrote:
 
 :-) As you've all noted, there are some conflicting concerns for the 
 default:
 
 - Source compatibility: the existing behavior for an unannotated enum is 
 "closed".
 - Intuition: if you show someone an enum without an explicit annotation, 
 they'll probably expect they can switch over it. (I'm going to say this is 
 why Zach calls it a "sensible default".)
 - Consistency: switches on an enum in the same module can always be 
 exhaustive, so having it be different across modules is a bit annoying. 
 (But 'public' already acts like this.)
 
 vs.
 
 - Library evolution: the default should promise less, so that you have the 
 opportunity to change it.
 - Flexibility: you can emulate an exhaustive switch with a non-exhaustive 
 switch using fatalError, but not the other way around.
 
 All of this is why I suggested it be an explicit annotation in either 
 direction, but Matthew brought up the "keyword soup" problem—if you have 
 to write (say) "public finite enum" and "public infinite enum", but would 
 never write "private finite enum" or "private infinite enum", something is 
 redundant here. Still, I'm uncomfortable with the default case being the 
 one that constrains library authors, so at least for binary frameworks 
 (those compiled "with resilience") I would want that to be explicit. That 
 brings us to one more concern: how different should binary frameworks be 
 from source frameworks?
>>> 
>>> In terms of intuition and consistency, I think we should really try to 
>>> learn from the simplicity of public/open:
>>> 
>>> * When internal, classes are sub-classable by default for convenience, but 
>>> can be closed with the final keyword
>>> * When public, classes are closed to sub-classing for safety, but can be 
>>> opened up with the open keyword (which implies public).
>>> 
>>> If we try to mirror this behaviour (the keywords are just suggestions, not 
>>> important):
>>> 
>>> * When internal, enums are exhaustive by default for convenience, but can 
>>> be opened-up with the partial keyword
>>> * When public, enums are non-exhaustive by default for safety, but can be 
>>> made exhaustive with the exhaustive keyword (which implies public).
>> 
>> This is not a correct understanding of the internal/public distinction for 
>> classes, though. From inside a module, a public-but-not-open class is still 
>> subclassable, and similarly a public-but-not-"closed" enum will still be 
>> exhaustively switched. You don't have to worry about your own module 
>> changing out from under you.
> 
> Correct. Thanks for the clarification! But you still agree with the argument, 
> right? Convenience for same module enums (exhaustive by default), safety for 
> clients of the module (not-exhaustive when public from outside the module), 
> with the option to be explicit?

That's the "library evolution" criterion above, yes. But the behavior of enums 
inside the module doesn't need to affect what we do across modules.

> And what do you think of the idea of having the « exhaustiveness » modifier 
> imply public, like open does?

I'm a little less sure about that. It does help with the keyword soup problem, 
but it's also not as obviously about access as "open" was, and "open" can also 
appear where other access modifiers can appear (on methods, properties, and 
subscripts).

Jordan

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


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Jordan Rose via swift-evolution
Both you and Vladimir are bringing up this point, with Vladimir explicitly 
suggesting a "future" case that's different from "default". Again, the pushback 
we get here is that the "future" case is untestable…but maybe that's still an 
option worth having. (At the very least, it's worth recording in any eventual 
proposal why we don't have it, and it could be added later if it turns out that 
was wrong.)

Thank you both for pushing on it.

Jordan


> On Aug 9, 2017, at 21:55, Charlie Monroe  wrote:
> 
> Hi Jordan,
> 
> let's say I'm writing my custom number formatter and I switch over 
> NSNumberFormatterStyle (NumberFormatter.Style in Swift) - the question always 
> is what to do with the default case - it's a value that I am not 
> programmatically counting with. I would personally just put in fatalError 
> with a description that it was passed an unhandled style. Listing all enums 
> in Foundation, I can see using most of them this way.
> 
> I personally have most of my switches exhaustive, mainly for the sake of 
> being warned/error'ed when a new case is introduced - I've just done a quick 
> search through my projects and I use default: usually for switching over 
> non-enums (strings, object matching, ints, ...).
> 
> Maybe I'm in the minority here... Seemed like a good practice to me - usually 
> the enum doesn't have but a few items on the list and you usually don't 
> handle just 1-2 cases in your switch, which makes the default label save you 
> 1-2 lines of code that can save you from unnnecessarily crashing during 
> runtime...
> 
>> On Aug 10, 2017, at 1:57 AM, Jordan Rose > > wrote:
>> 
>> Hi, Charlie. This is fair—if you're switching over an open enum at all, 
>> presumably you have a reason for doing so and therefore might want to handle 
>> all known cases every time you update your SDK. However, I think in practice 
>> that's going to be rare—do you have examples of exhaustive switches on SDK 
>> enums that exist in your own app?
>> 
>> (There's an additional piece about how to handle cases with different 
>> availability—there's nowhere obvious to write the #available.)
>> 
>> I suspect marking SDK enums "closed" will be much easier than nullability, 
>> simply because there are so few of them. Here's some data to that effect: 
>> out of all  60 or so NS_ENUMs in Foundation, only 6 of them are ones I would 
>> definitely mark "closed":
>> 
>> - NSComparisonResult
>> - NSKeyValueChange / NSKeyValueSetMutationKind
>> - NSRectEdge
>> - NSURLRelationship
>> - maybe NSCalculationError
>> 
>> There are a few more, like NSURLHandleStatus, where I could see someone 
>> wanting to exhaustively switch as well, but the main point is that there is 
>> a clear default for public enums, at least in Objective-C, and that even in 
>> a large framework it's not too hard to look at all of them.
>> 
>> (Note that NSComparisonResult is technically not part of Foundation; it 
>> lives in the ObjectiveC module as /usr/include/objc/NSObject.h.)
>> 
>> Jordan
>> 
>> 
>>> On Aug 8, 2017, at 21:53, Charlie Monroe >> > wrote:
>>> 
>>> While I agree with the entire idea and would actually use behavior like 
>>> this in a few instances, I feel that in most cases, you would simply put 
>>> 
>>> default:
>>> fatalError()
>>> 
>>> The huge downside of this is that you no longer get warned by the compiler 
>>> that you are missing a case that was added - a common thing I personally do 
>>> (and I have a feeling I'm not alone) - add an enum case, build the app, see 
>>> what broke and fix it - as you get warnings/errors about the switch not 
>>> being exhaustive. You find this out during runtime (if you're lucky), 
>>> otherwise your end user.
>>> 
>>> As you've noted all enums from ObjC would need to be marked with an 
>>> annotation marking if they are closed - which given the way nullability is 
>>> still missing in many frameworks out there, I think would take years.
>>> 
>>> I'd personally expand this proposal by introducing switch! (with the 
>>> exclamation mark) which would allow to treat open enums as closed. Example:
>>> 
>>> // Imported from ObjC
>>> open enum NSAlert.Style { ... }
>>> 
>>> switch! alert.style {
>>> case .warning:
>>> // ...
>>> case .informational:
>>> // ...
>>> case .critical:
>>> // ...
>>> }
>>> 
>>> The force-switch would implicitely create the default label crashing, 
>>> logging the rawValue of the enum.
>>> 
>>> Thoughts?
>>> 
 On Aug 9, 2017, at 12:28 AM, Jordan Rose via swift-evolution 
 > wrote:
 
 Hi, everyone. Now that Swift 5 is starting up, I'd like to circle back to 
 an issue that's been around for a while: the source compatibility of 
 enums. Today, it's an error to switch over an enum without handling all 
 the cases, but this 

Re: [swift-evolution] Enums and Source Compatibility - defaults

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 9, 2017, at 20:00, Zach Waldowski via swift-evolution 
>  wrote:
> 
> On Wed, Aug 9, 2017, at 08:49 PM, Jordan Rose via swift-evolution wrote:
>> Ah, I forgot to mention: per my response to Charlie, the vast majority of 
>> enums in ObjC Foundation (80-90%) seem to be "open". I should have put that 
>> in the "open" side of the list. I'm not convinced that "APIs are designed 
>> differently in Swift" to the extent where you'd actually expect most enums 
>> to be closed; rather, I suspect most Swift API designers haven't been 
>> thinking too hard about exhaustive switches, and certainly not about binary 
>> compatibility, which becomes relevant at least for Apple once Swift 
>> libraries become part of the SDK.
> 
> Let me expound a bit. I was erroneously including string enums in my 
> supposition that APIs are designed differently, but overall I still stand 
> behind it.
> 
> Foundation is designed for paper over lots of different computing concepts 
> and underlying libraries with similar-ish APIs — in a good way! From the eyes 
> of an API consumer, configuring something like a formatter to behave how they 
> want is basically a write-only proposition. This makes simple enum cases a 
> great design choice for hiding swaths of different underlying implementations 
> (ex: NSDateFormatterShortStyle having a different meaning per-locale.)
> 
> Say we split up Foundation's enums roughly into categories. You have your 
> policies (NSURLCacheStoragePolicy, NSDateFormatterStyle), states/answers 
> (NSURLSessionTaskState, NSQualityOfService), and, well, lists 
> (NSSearchPathDirectory, NSStringEncoding). Given those, I’d say protocols, 
> generics, and zero-cost abstractions are frequently a better choice (but not 
> always). For instance, IMHO a closed protocol better models commonly-used 
> styles.
> 
> I know you ask to only consider open/closed enums in isolation to make it 
> most likely to succeed, but there’s the frequent complaint that Swift has 
> many ways to accomplish the same thing; I think resilience will land best 
> with the community if it has a few really solid throughlines with the rest of 
> the language, open/closed I hope being among them.

For what it's worth, the rest of "resilience" mostly doesn't have semantic 
effects at all. Enums are special because of the source-affecting aspects. 
(That'll certainly make it weird to talk about the rest of resilience; I 
suspect most of the group won't be interested.)

Thanks for listing this out, Zach. I don't think I agree with the conclusion 
that enums should and will be used less in Swift, but I'm not the only one 
whose opinion matters on this.

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 10, 2017, at 15:34, Tony Allevato  wrote:
> 
> Do you mean something like this, then?
> 
> ```
> struct Foo: Equatable {
>   let x: Int
> }
> 
> func test(_ lhs: T, _ rhs: T) -> Bool {
>   return lhs == rhs
> }
> 
> extension Foo {
>   static func == (lhs: Foo, rhs: Foo) -> Bool {
> return lhs.x % 2 == rhs.x % 2
>   }
> }
> 
> print(test(Foo(x: 5), Foo(x: 7)))  // true
> ```
> 
> That seems to work.

Ah, yes, this works in a source file. It may even work in the REPL, if the REPL 
delays evaluating input until it sees an actual statement. However, the 
original REPL transcript you pasted in would not have worked.

> 
> I just tested the Annoying example as well and yes, the version from the 
> Annoying extension is what gets called in my implementation.
> 
> I agree with you that that seems like the correct behavior—the manually 
> written version takes precedence over the synthesized version, even though it 
> comes from a different protocol extension; synthesized versions should always 
> be the last resort because they're not controlled by the user, correct?
> 
> This also seems consistent with the way regular methods are resolved if we 
> take synthesis completely out of the equation:
> 
> ```
> protocol Fooquatable {
>   static func foo(lhs: Self, rhs: Self) -> Bool
> }
> 
> protocol Annoying {}
> extension Annoying {
>   static func foo(lhs: Self, rhs: Self) -> Bool {
> print("annoying")
> return true
>   }
> }
> struct Foo: Fooquatable, Annoying {
>   let x: Int
> }
> 
> func foo(_ lhs: T, _ rhs: T) -> Bool {
>   return T.foo(lhs: lhs, rhs: rhs)
> }
> 
> print(foo(Foo(x: 5), Foo(x: 6)))  // annoying, true
> ```
> 
> Does this seems reasonable? (Assuming I'm testing the right thing. :)

Yep, that's why I think this is the right behavior as well. It does mean that 
this synthesis doesn't quite behave like a usual default implementation, 
because that would make this code ambiguous. If we really wanted it to match 
that behavior we'd have to rank it like a kind of protocol extension member. I 
think it's okay not to do that, though.

Jordan

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Tony Allevato via swift-evolution
Do you mean something like this, then?

```
struct Foo: Equatable {
  let x: Int
}

func test(_ lhs: T, _ rhs: T) -> Bool {
  return lhs == rhs
}

extension Foo {
  static func == (lhs: Foo, rhs: Foo) -> Bool {
return lhs.x % 2 == rhs.x % 2
  }
}

print(test(Foo(x: 5), Foo(x: 7)))  // true
```

That seems to work.

I just tested the Annoying example as well and yes, the version from the
Annoying extension is what gets called in my implementation.

I agree with you that that seems like the correct behavior—the manually
written version takes precedence over the synthesized version, even though
it comes from a different protocol extension; synthesized versions should
always be the last resort because they're not controlled by the user,
correct?

This also seems consistent with the way regular methods are resolved if we
take synthesis completely out of the equation:

```
protocol Fooquatable {
  static func foo(lhs: Self, rhs: Self) -> Bool
}

protocol Annoying {}
extension Annoying {
  static func foo(lhs: Self, rhs: Self) -> Bool {
print("annoying")
return true
  }
}
struct Foo: Fooquatable, Annoying {
  let x: Int
}

func foo(_ lhs: T, _ rhs: T) -> Bool {
  return T.foo(lhs: lhs, rhs: rhs)
}

print(foo(Foo(x: 5), Foo(x: 6)))  // annoying, true
```

Does this seems reasonable? (Assuming I'm testing the right thing. :)


On Thu, Aug 10, 2017 at 2:58 PM Jordan Rose  wrote:

>
>
> On Aug 10, 2017, at 14:48, Tony Allevato  wrote:
>
> On Thu, Aug 10, 2017 at 11:05 AM Jordan Rose 
> wrote:
>
>> [Proposal:
>> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
>> ]
>>
>> Hi, Tony. Glad to see this back again!
>>
>> Overall I'm an enthusiastic +1. The restrictions and future work you've
>> listed make sense, and I think this is the right starting place. I just
>> have one thing I'd want to clarify:
>>
>> Any user-provided implementations of == or hashValue will override the
>> default implementations that would be provided by the compiler.
>>
>>
>> Does this include implementations in (possibly constrained) protocol
>> extensions? I assume yes, but that's probably worth calling out explicitly.
>> Still, it could be confusing to some users.
>>
>
> Yes, manual implementations added in extensions override the
> compiler-synthesized default:
>
> Without constraints:
> (swift) struct Foo: Equatable { let x: Int }
> (swift) Foo(x: 5) == Foo(x: 6)
> // r0 : Bool = false
> (swift) Foo(x: 5) == Foo(x: 5)
> // r1 : Bool = true
> (swift) extension Foo { static func ==(lhs: Foo, rhs: Foo) -> Bool {
> return lhs.x % 2 == rhs.x % 2 } }
> (swift) Foo(x: 5) == Foo(x: 6)
> // r2 : Bool = false
> (swift) Foo(x: 5) == Foo(x: 7)
> // r3 : Bool = true
>
> With constraints:
> (swift) struct Foo: Equatable { let t: T }
> (swift) extension Foo where T == String { static func ==(lhs: Foo, rhs:
> Foo) -> Bool { return lhs.t.characters.count == rhs.t.characters.count }
> }
> (swift) Foo(t: "foo") == Foo(t: "bar")
> // r0 : Bool = true
> (swift) Foo(t: 5) == Foo(t: 7)
> // r1 : Bool = false
>
> I can update the text to make this explicit.
>
>
> Ah, that's not quite the example I meant, *and* your example isn't a
> correct demonstration for the REPL. If you want to test the == that's used
> in the Equatable conformance, you have to call a function that's generic on
> Equatable.
>
> Anyway, this is the example I meant:
>
> protocol Annoying {}
> extension Annoying {
>
>   static func ==(lhs: Self, rhs: Self) -> Bool {
>
> print("annoying")
> return true
>   }
> }
> struct Foo: Equatable, Annoying {
>   let x: Int
> }
> print(Foo(x: 5) == Foo(x: 6))
>
>
> I think the correct behavior here is to call the version from Annoying,
> but I can also see how that would be surprising.
>
> Jordan
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Brent Royal-Gordon via swift-evolution
> On Aug 10, 2017, at 3:40 AM, Haravikk via swift-evolution 
>  wrote:
> 
> This is not the same as a default protocol implementation

Actually, I could easily imagine that a future version of Swift with macro 
support might do this with a default protocol implementation:

extension Equatable {
#generated static func == (lhs: Self, rhs: Self) -> Bool {
switch self {
case let self as Struct:
let propertyPairs = properties.map { property in
guard let property = property as? 
Property else {
throw 
SynthesisError.invalidType(property, expected: Generated.Equatable.self)
}
return 
DependentExpressionPair(
original: Expression { 
lhs.#property },
dependent: Expression { 
rhs.#property }
)
}
return FunctionBlock { return 
#equated(propertyPairs) }

case let self as Enum:
guard !all.isEmpty else {
throw SynthesisError.invalid(self, 
message: "is an empty enum")
}

let cases: SwitchBody<(Generated.Self, 
Generated.Self)> = all.map { aCase in
let valueCaptures = 
aCase.associatedValues.map { value in
guard let value = value as? 
AssociatedValue else {
throw 
SynthesisError.invalidType(value, expected: Generated.Equatable.self)
}
return 
DependentExpressionPair(
original: 
Variable(type: value.type),
dependent: 
Variable(type: value.type)
)
}

return SwitchBody {
case let (

#aCase.pattern(capturingInto: valueCaptures.map(\.original)),

#aCase.pattern(capturingInto: valueCaptures.map(\.dependent))
):
return 
#equated(valueCaptures)
}
}.joined()

return FunctionBlock { switch (lhs, rhs) { 
#cases } }

default:
throw SynthesisError.invalid(self, message: "is 
not a struct or enum")
}
}
}

private #func equated(_ exprPairs: 
[DependentExpressionPair]) -> 
Expression {
return exprPairs.map { pair in
Expression { #pair.original == #pair.dependent }
}
.reduce(Expression { true }) { earlier, this in
Expression { #earlier && #this }
}
} 

If the only difference were whether the default implementation was generated by 
a macro or not, would you still think auto-derivation should be marked with a 
keyword?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
Sorry, I think I misunderstood your earlier email. I believe we are in 
agreement.

> On Aug 10, 2017, at 5:54 PM, Xiaodi Wu  wrote:
> 
> Yes, but to be clear, this is an objection that is equally applicable to any 
> change where a protocol requirement is given a default implementation.
> 
> Unless I’m mistaken, ordinarily, the addition of such a default 
> implementation isn’t even considered an API change and doesn’t require Swift 
> Evolution approval.
>> On Thu, Aug 10, 2017 at 16:41 David Ungar  wrote:
>> As long as I've been clear that the adoption of *this* proposal would 
>> transform a misspelling from a bug that the compiler catches to a bug that 
>> the compiler does not catch, I feel that my objection has been heard.
>> 
>> Thank you all,
>> 
>> - David
>> 
>> 
>>> On Aug 10, 2017, at 1:51 PM, Xiaodi Wu  wrote:
>>> 
>>> Right. The objection raised is applicable to the overriding of any default 
>>> implementation. However. _this_ proposal under review is about the 
>>> synthesis of a default implementation, and we shouldn’t try to invent new 
>>> syntax to address an orthogonal issue—and only partially at that.
>>> On Thu, Aug 10, 2017 at 14:45 Robert Bennett via swift-evolution 
>>>  wrote:
 Yes, thanks! Here’s the full proposal for those interested: 
 https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md
 
 I think that if we want to deal with the issue of some mistake arising 
 from conforming to Equatable and/or Hashable, it should be through that 
 proposal, not something specific to Equatable and Hashable. This sort of 
 issue should not count against this Equatable/Hashable proposal.
 
>> On Aug 10, 2017, at 3:39 PM, Chris Lattner  wrote:
>> 
>> 
>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>>  wrote:
>> 
>> I could have sworn that this sort of issue came up on this list earlier 
>> this year… Someone proposed a mechanism encompassing all protocols, not 
>> just Equatable and Hashable, to handle the issue of mistakenly believing 
>> you’re overriding a default implementation. Having trouble finding it at 
>> the moment.
> 
> Is this what you’re thinking of?
> https://github.com/apple/swift-evolution/pull/724
> 
> -Chris
> 
> 
> 
>> .
>> 
>>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>>>  wrote:
>>> 
>>> If I understand it, merely adding Equatable or Hashable will cause the 
>>> compiler to synthesize requirements. This syntax opens up the 
>>> possibility for errors:
>>> 
>>> struct Snort: Hashable {
>>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>>> }
>>> 
>>> In the above example, the programmer meant to implement hashValue but 
>>> misspelled it.
>>> With the proposal as-is, the error could be covered up.
>>> 
>>> I would prefer to see a different syntax than merely adding conformance 
>>> to "HashValue", in order to distinguish the two cases: explicit 
>>> supplying the requirement vs synthesis.
>>> 
>>> Also, what if we want to extend this idea to other protocols? Perhaps 
>>> some sort of modifier on the protocol name would be more orthogonal:
>>> 
>>> struct Foo: Synth Hashable, Equatable 
>>> 
>>> Would say that Hashable requirements get synthesized but Equatable ones 
>>> do not.
>>> 
>>> Alternatively, it might be clearer, though more verbose to move the 
>>> signalling inside:
>>> 
>>> struct Snort: Hashable {
>>> synth hashValue
>>> }
>>> 
>>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>>> possibly making it clearer to read the code.
>>> 
>>> TL;DR: I favor the proposal but would prefer modification to make it 
>>> more explicit.
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 10, 2017, at 14:48, Tony Allevato  wrote:
> 
> On Thu, Aug 10, 2017 at 11:05 AM Jordan Rose  > wrote:
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
>  
> ]
> 
> Hi, Tony. Glad to see this back again!
> 
> Overall I'm an enthusiastic +1. The restrictions and future work you've 
> listed make sense, and I think this is the right starting place. I just have 
> one thing I'd want to clarify:
> 
>> Any user-provided implementations of == or hashValue will override the 
>> default implementations that would be provided by the compiler.
> 
> Does this include implementations in (possibly constrained) protocol 
> extensions? I assume yes, but that's probably worth calling out explicitly. 
> Still, it could be confusing to some users.
> 
> Yes, manual implementations added in extensions override the 
> compiler-synthesized default:
> 
> Without constraints:
> (swift) struct Foo: Equatable { let x: Int }
> (swift) Foo(x: 5) == Foo(x: 6)
> // r0 : Bool = false
> (swift) Foo(x: 5) == Foo(x: 5)
> // r1 : Bool = true
> (swift) extension Foo { static func ==(lhs: Foo, rhs: Foo) -> Bool { return 
> lhs.x % 2 == rhs.x % 2 } }
> (swift) Foo(x: 5) == Foo(x: 6)
> // r2 : Bool = false
> (swift) Foo(x: 5) == Foo(x: 7)
> // r3 : Bool = true
> 
> With constraints:
> (swift) struct Foo: Equatable { let t: T }
> (swift) extension Foo where T == String { static func ==(lhs: Foo, rhs: 
> Foo) -> Bool { return lhs.t.characters.count == rhs.t.characters.count } }
> (swift) Foo(t: "foo") == Foo(t: "bar")
> // r0 : Bool = true
> (swift) Foo(t: 5) == Foo(t: 7)
> // r1 : Bool = false
> 
> I can update the text to make this explicit.

Ah, that's not quite the example I meant, and your example isn't a correct 
demonstration for the REPL. If you want to test the == that's used in the 
Equatable conformance, you have to call a function that's generic on Equatable.

Anyway, this is the example I meant:

protocol Annoying {}
extension Annoying {
  static func ==(lhs: Self, rhs: Self) -> Bool {
print("annoying")
return true
  }
}
struct Foo: Equatable, Annoying {
  let x: Int
}
print(Foo(x: 5) == Foo(x: 6))

I think the correct behavior here is to call the version from Annoying, but I 
can also see how that would be surprising.

Jordan

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


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Xiaodi Wu via swift-evolution
Yes, but to be clear, this is an objection that is equally applicable to
any change where a protocol requirement is given a default implementation.

Unless I’m mistaken, ordinarily, the addition of such a default
implementation isn’t even considered an API change and doesn’t require
Swift Evolution approval.
On Thu, Aug 10, 2017 at 16:41 David Ungar  wrote:

> As long as I've been clear that the adoption of *this* proposal would
> transform a misspelling from a bug that the compiler catches to a bug that
> the compiler does not catch, I feel that my objection has been heard.
>
> Thank you all,
>
> - David
>
>
> On Aug 10, 2017, at 1:51 PM, Xiaodi Wu  wrote:
>
> Right. The objection raised is applicable to the overriding of any default
> implementation. However. _this_ proposal under review is about the
> synthesis of a default implementation, and we shouldn’t try to invent new
> syntax to address an orthogonal issue—and only partially at that.
> On Thu, Aug 10, 2017 at 14:45 Robert Bennett via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Yes, thanks! Here’s the full proposal for those interested:
>> https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md
>>
>> I think that if we want to deal with the issue of some mistake arising
>> from conforming to Equatable and/or Hashable, it should be through that
>> proposal, not something specific to Equatable and Hashable. This sort of
>> issue should not count against this Equatable/Hashable proposal.
>>
>> On Aug 10, 2017, at 3:39 PM, Chris Lattner  wrote:
>>
>>
>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> I could have sworn that this sort of issue came up on this list earlier
>> this year… Someone proposed a mechanism encompassing all protocols, not
>> just Equatable and Hashable, to handle the issue of mistakenly believing
>> you’re overriding a default implementation. Having trouble finding it at
>> the moment.
>>
>>
>> Is this what you’re thinking of?
>> https://github.com/apple/swift-evolution/pull/724
>>
>> -Chris
>>
>>
>>
>> .
>>
>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> If I understand it, merely adding Equatable or Hashable will cause the
>> compiler to synthesize requirements. This syntax opens up the possibility
>> for errors:
>>
>> struct Snort: Hashable {
>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>> }
>>
>> In the above example, the programmer meant to implement hashValue but
>> misspelled it.
>> With the proposal as-is, the error could be covered up.
>>
>> I would prefer to see a different syntax than merely adding conformance
>> to "HashValue", in order to distinguish the two cases: explicit supplying
>> the requirement vs synthesis.
>>
>> Also, what if we want to extend this idea to other protocols? Perhaps
>> some sort of modifier on the protocol name would be more orthogonal:
>>
>> struct Foo: Synth Hashable, Equatable
>>
>> Would say that Hashable requirements get synthesized but Equatable ones
>> do not.
>>
>> Alternatively, it might be clearer, though more verbose to move the
>> signalling inside:
>>
>> struct Snort: Hashable {
>> synth hashValue
>> }
>>
>> (I don't advocate this specific syntax, btw.) But it has the virtual of
>> possibly making it clearer to read the code.
>>
>> TL;DR: I favor the proposal but would prefer modification to make it more
>> explicit.
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread David Ungar via swift-evolution
As long as I've been clear that the adoption of *this* proposal would transform 
a misspelling from a bug that the compiler catches to a bug that the compiler 
does not catch, I feel that my objection has been heard.

Thank you all,

- David

> On Aug 10, 2017, at 1:51 PM, Xiaodi Wu  wrote:
> 
> Right. The objection raised is applicable to the overriding of any default 
> implementation. However. _this_ proposal under review is about the synthesis 
> of a default implementation, and we shouldn’t try to invent new syntax to 
> address an orthogonal issue—and only partially at that.
> On Thu, Aug 10, 2017 at 14:45 Robert Bennett via swift-evolution 
> > wrote:
> Yes, thanks! Here’s the full proposal for those interested: 
> https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md
>  
> 
> 
> I think that if we want to deal with the issue of some mistake arising from 
> conforming to Equatable and/or Hashable, it should be through that proposal, 
> not something specific to Equatable and Hashable. This sort of issue should 
> not count against this Equatable/Hashable proposal.
> 
>> On Aug 10, 2017, at 3:39 PM, Chris Lattner > > wrote:
>> 
>>> 
>>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>>> > wrote:
>>> 
>>> I could have sworn that this sort of issue came up on this list earlier 
>>> this year… Someone proposed a mechanism encompassing all protocols, not 
>>> just Equatable and Hashable, to handle the issue of mistakenly believing 
>>> you’re overriding a default implementation. Having trouble finding it at 
>>> the moment.
>> 
>> Is this what you’re thinking of?
>> https://github.com/apple/swift-evolution/pull/724 
>> 
>> 
>> -Chris
>> 
>> 
>> 
>>> .
>>> 
 On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
 > wrote:
 
 If I understand it, merely adding Equatable or Hashable will cause the 
 compiler to synthesize requirements. This syntax opens up the possibility 
 for errors:
 
 struct Snort: Hashable {
 static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
 }
 
 In the above example, the programmer meant to implement hashValue but 
 misspelled it.
 With the proposal as-is, the error could be covered up.
 
 I would prefer to see a different syntax than merely adding conformance to 
 "HashValue", in order to distinguish the two cases: explicit supplying the 
 requirement vs synthesis.
 
 Also, what if we want to extend this idea to other protocols? Perhaps some 
 sort of modifier on the protocol name would be more orthogonal:
 
 struct Foo: Synth Hashable, Equatable 
 
 Would say that Hashable requirements get synthesized but Equatable ones do 
 not.
 
 Alternatively, it might be clearer, though more verbose to move the 
 signalling inside:
 
 struct Snort: Hashable {
 synth hashValue
 }
 
 (I don't advocate this specific syntax, btw.) But it has the virtual of 
 possibly making it clearer to read the code.
 
 TL;DR: I favor the proposal but would prefer modification to make it more 
 explicit.
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Matthew Johnson via swift-evolution
> 
>   • What is your evaluation of the proposal?

Very large +1 in general.  I really wanted to see this happen in Swift 4.  I’m 
very happy that it’s up for review right at the beginning of the Swift 5 
process.

That said, I do think the concern others have voiced regarding implicit 
synthesis has some merit.  Most languages I am familiar with that synthesize 
memberwise implementations do so using an explicit request (`deriving` or 
similar).  It adds a small amount of boilerplate in exchange for precise 
control.  It seems to me that this tradeoff is in line with Swift’s motto of 
clarity over concision.  If we do make a change to this proposal we should also 
make the same change for basic enums as well as Codable for the sake of 
consistency.

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

Yes.  Manually writing memberwise implementations is a big enough annoyance 
that it can influence designs.  For example, a library author may be more 
likely to try and avoid requiring user types to conform when users are required 
to write those conformances manually. 

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

Very much so.

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

It is very similar, although as mentioned, it might make sense to require 
explicit opt-in to memberwise synthesis.

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

Quick glance this time around, but I have participated heavily in the previous 
discussions.

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


Re: [swift-evolution] Enums and Source Compatibility - defaults

2017-08-10 Thread David Hart via swift-evolution


> On 10 Aug 2017, at 19:19, Jordan Rose  wrote:
> 
> 
> 
>>> On Aug 9, 2017, at 22:46, David Hart  wrote:
>>> 
>>> 
>>> On 10 Aug 2017, at 02:42, Jordan Rose  wrote:
>>> 
>>> :-) As you've all noted, there are some conflicting concerns for the 
>>> default:
>>> 
>>> - Source compatibility: the existing behavior for an unannotated enum is 
>>> "closed".
>>> - Intuition: if you show someone an enum without an explicit annotation, 
>>> they'll probably expect they can switch over it. (I'm going to say this is 
>>> why Zach calls it a "sensible default".)
>>> - Consistency: switches on an enum in the same module can always be 
>>> exhaustive, so having it be different across modules is a bit annoying. 
>>> (But 'public' already acts like this.)
>>> 
>>> vs.
>>> 
>>> - Library evolution: the default should promise less, so that you have the 
>>> opportunity to change it.
>>> - Flexibility: you can emulate an exhaustive switch with a non-exhaustive 
>>> switch using fatalError, but not the other way around.
>>> 
>>> All of this is why I suggested it be an explicit annotation in either 
>>> direction, but Matthew brought up the "keyword soup" problem—if you have to 
>>> write (say) "public finite enum" and "public infinite enum", but would 
>>> never write "private finite enum" or "private infinite enum", something is 
>>> redundant here. Still, I'm uncomfortable with the default case being the 
>>> one that constrains library authors, so at least for binary frameworks 
>>> (those compiled "with resilience") I would want that to be explicit. That 
>>> brings us to one more concern: how different should binary frameworks be 
>>> from source frameworks?
>> 
>> In terms of intuition and consistency, I think we should really try to learn 
>> from the simplicity of public/open:
>> 
>> * When internal, classes are sub-classable by default for convenience, but 
>> can be closed with the final keyword
>> * When public, classes are closed to sub-classing for safety, but can be 
>> opened up with the open keyword (which implies public).
>> 
>> If we try to mirror this behaviour (the keywords are just suggestions, not 
>> important):
>> 
>> * When internal, enums are exhaustive by default for convenience, but can be 
>> opened-up with the partial keyword
>> * When public, enums are non-exhaustive by default for safety, but can be 
>> made exhaustive with the exhaustive keyword (which implies public).
> 
> This is not a correct understanding of the internal/public distinction for 
> classes, though. From inside a module, a public-but-not-open class is still 
> subclassable, and similarly a public-but-not-"closed" enum will still be 
> exhaustively switched. You don't have to worry about your own module changing 
> out from under you.

Correct. Thanks for the clarification! But you still agree with the argument, 
right? Convenience for same module enums (exhaustive by default), safety for 
clients of the module (not-exhaustive when public from outside the module), 
with the option to be explicit? And what do you think of the idea of having the 
« exhaustiveness » modifier imply public, like open does?

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


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
Yes, thanks! Here’s the full proposal for those interested: 
https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md

I think that if we want to deal with the issue of some mistake arising from 
conforming to Equatable and/or Hashable, it should be through that proposal, 
not something specific to Equatable and Hashable. This sort of issue should not 
count against this Equatable/Hashable proposal.

> On Aug 10, 2017, at 3:39 PM, Chris Lattner  wrote:
> 
>> 
>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>> > wrote:
>> 
>> I could have sworn that this sort of issue came up on this list earlier this 
>> year… Someone proposed a mechanism encompassing all protocols, not just 
>> Equatable and Hashable, to handle the issue of mistakenly believing you’re 
>> overriding a default implementation. Having trouble finding it at the moment.
> 
> Is this what you’re thinking of?
> https://github.com/apple/swift-evolution/pull/724 
> 
> 
> -Chris
> 
> 
> 
>> .
>> 
>>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>>>  wrote:
>>> 
>>> If I understand it, merely adding Equatable or Hashable will cause the 
>>> compiler to synthesize requirements. This syntax opens up the possibility 
>>> for errors:
>>> 
>>> struct Snort: Hashable {
>>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>>> }
>>> 
>>> In the above example, the programmer meant to implement hashValue but 
>>> misspelled it.
>>> With the proposal as-is, the error could be covered up.
>>> 
>>> I would prefer to see a different syntax than merely adding conformance to 
>>> "HashValue", in order to distinguish the two cases: explicit supplying the 
>>> requirement vs synthesis.
>>> 
>>> Also, what if we want to extend this idea to other protocols? Perhaps some 
>>> sort of modifier on the protocol name would be more orthogonal:
>>> 
>>> struct Foo: Synth Hashable, Equatable 
>>> 
>>> Would say that Hashable requirements get synthesized but Equatable ones do 
>>> not.
>>> 
>>> Alternatively, it might be clearer, though more verbose to move the 
>>> signalling inside:
>>> 
>>> struct Snort: Hashable {
>>> synth hashValue
>>> }
>>> 
>>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>>> possibly making it clearer to read the code.
>>> 
>>> TL;DR: I favor the proposal but would prefer modification to make it more 
>>> explicit.
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Chris Lattner via swift-evolution

> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>  wrote:
> 
> I could have sworn that this sort of issue came up on this list earlier this 
> year… Someone proposed a mechanism encompassing all protocols, not just 
> Equatable and Hashable, to handle the issue of mistakenly believing you’re 
> overriding a default implementation. Having trouble finding it at the moment.

Is this what you’re thinking of?
https://github.com/apple/swift-evolution/pull/724

-Chris



> .
> 
>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>>  wrote:
>> 
>> If I understand it, merely adding Equatable or Hashable will cause the 
>> compiler to synthesize requirements. This syntax opens up the possibility 
>> for errors:
>> 
>> struct Snort: Hashable {
>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>> }
>> 
>> In the above example, the programmer meant to implement hashValue but 
>> misspelled it.
>> With the proposal as-is, the error could be covered up.
>> 
>> I would prefer to see a different syntax than merely adding conformance to 
>> "HashValue", in order to distinguish the two cases: explicit supplying the 
>> requirement vs synthesis.
>> 
>> Also, what if we want to extend this idea to other protocols? Perhaps some 
>> sort of modifier on the protocol name would be more orthogonal:
>> 
>> struct Foo: Synth Hashable, Equatable 
>> 
>> Would say that Hashable requirements get synthesized but Equatable ones do 
>> not.
>> 
>> Alternatively, it might be clearer, though more verbose to move the 
>> signalling inside:
>> 
>> struct Snort: Hashable {
>> synth hashValue
>> }
>> 
>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>> possibly making it clearer to read the code.
>> 
>> TL;DR: I favor the proposal but would prefer modification to make it more 
>> explicit.
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
I could have sworn that this sort of issue came up on this list earlier this 
year… Someone proposed a mechanism encompassing all protocols, not just 
Equatable and Hashable, to handle the issue of mistakenly believing you’re 
overriding a default implementation. Having trouble finding it at the moment.

> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>  wrote:
> 
> If I understand it, merely adding Equatable or Hashable will cause the 
> compiler to synthesize requirements. This syntax opens up the possibility for 
> errors:
> 
> struct Snort: Hashable {
>  static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
> }
> 
> In the above example, the programmer meant to implement hashValue but 
> misspelled it.
> With the proposal as-is, the error could be covered up.
> 
> I would prefer to see a different syntax than merely adding conformance to 
> "HashValue", in order to distinguish the two cases: explicit supplying the 
> requirement vs synthesis.
> 
> Also, what if we want to extend this idea to other protocols? Perhaps some 
> sort of modifier on the protocol name would be more orthogonal:
> 
> struct Foo: Synth Hashable, Equatable 
> 
> Would say that Hashable requirements get synthesized but Equatable ones do 
> not.
> 
> Alternatively, it might be clearer, though more verbose to move the 
> signalling inside:
> 
> struct Snort: Hashable {
>  synth hashValue
> }
> 
> (I don't advocate this specific syntax, btw.) But it has the virtual of 
> possibly making it clearer to read the code.
> 
> TL;DR: I favor the proposal but would prefer modification to make it more 
> explicit.
> ___
> 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] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread David Ungar via swift-evolution
If I understand it, merely adding Equatable or Hashable will cause the compiler 
to synthesize requirements. This syntax opens up the possibility for errors:

struct Snort: Hashable {
  static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
}

In the above example, the programmer meant to implement hashValue but 
misspelled it.
With the proposal as-is, the error could be covered up.

I would prefer to see a different syntax than merely adding conformance to 
"HashValue", in order to distinguish the two cases: explicit supplying the 
requirement vs synthesis.

Also, what if we want to extend this idea to other protocols? Perhaps some sort 
of modifier on the protocol name would be more orthogonal:

struct Foo: Synth Hashable, Equatable 

Would say that Hashable requirements get synthesized but Equatable ones do not.

Alternatively, it might be clearer, though more verbose to move the signalling 
inside:

struct Snort: Hashable {
  synth hashValue
}

(I don't advocate this specific syntax, btw.) But it has the virtual of 
possibly making it clearer to read the code.

TL;DR: I favor the proposal but would prefer modification to make it more 
explicit.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Robert Bennett via swift-evolution
To me, regexes definitely feel like they belong in Foundation. Also, I don’t 
think they’d be well-served by a literal syntax (even just 
ExpressibleByStringLiteral) because this privileges using the default regex 
options over specifying non-default options. 

The compilation issue seems a bit tricky, especially if Regex is a value type. 
To avoid throwing away a cached compiled version of the Regex, you’d need to 
remember to compile it before passing it to a function. Perhaps the 
initializers could have a `precompile` argument so that you’d never forget to 
compile the regex. The Swift compiler could then optimize around that where 
possible. It should definitely be possible to create uncompiled regexes, 
though. I also agree that the compiler should warn about invalid regexes where 
possible.

> On Aug 10, 2017, at 2:30 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> 
>> On Aug 10, 2017, at 11:48 AM, Tino Heth via swift-evolution 
>>  wrote:
>> 
>> I guess everyone agrees that there should be support for regular expressions 
>> - I'm just not sure where, how and when to integrate it…
>> People seem to have a (sometimes unhealthy…) passion for regex, so I'd like 
>> to encourage a critical look on their importance.
>> For example, I don't think they belong into the stdlib — there are more 
>> basic (and much more simple) things like a Result-type or an operator for 
>> function concatenation which are not included, so why should we treat 
>> regular expressions differently?
>> But It doesn't look like we'll see a fitting library that's bundled with 
>> Swift anytime soon, and third-party regex Frameworks imho would cause big 
>> confusion.
> 
> This goes back to the idea of “non-standard libraries” that ship with Swift, 
> but aren’t imported by default. I think a “Swift.Regex” module would be 
> awesome, but I agree that it probably doesn’t need to be in the standard 
> library.
> 
> Dave
> 
>> 
>> Anyways, as you suggest a special syntax, it would be required to integrate 
>> support into Swift itself… although this is even deeper than the stdlib, I'm 
>> more positive towards that direction, as it would allow some neat tricks:
>> The expressions could not only be checked, but also translated at compile 
>> time — which could give Swift a real kickstart to beat established solutions 
>> in terms of execution speed.
>> It would, on the other hand, not work for non-literal strings, so regular 
>> expressions that are created at runtime would still need extra support…
>> 
>> If Core would consider to include compile-time regular expressions in the 
>> future, I'd support adding the new syntax, even if it's only used like 
>> NSExpression in the first implementation. Without that option, I think it's 
>> not worth it, and I'd rather try to use custom operators to build matchers 
>> that don't follow any regex standard, but are fast and safe to use.
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Michael Ilseman via swift-evolution
Thank you for bringing this up! Swift String has a lot of expressivity gaps 
we’re trying to tackle in Swift 5. I think that both language and library 
support for flexible matching and transformation is needed, likely through a 
regex-like construct. Libraries and prototypes like this help drive the 
discussion. Do you have a package that implements this?

Ben’s email highlights a lot of the design considerations that need to be 
thought through. We’ll likely be iterating over designs on swift-evolution for 
the various components, but we also need a high level vision for this. I’m 
working on a new version of the String Manifesto that incorporates lessons 
learned from the implementation of Swift 4 while fleshing out a vision for 
Swift 5 and beyond.

Part of that vision includes a declarative way for programmers to express 
string processing and transformation cleanly in Swift. Perl 6 is the gold 
standard for string processing in programming languages. Any insights shown in 
Perl 6’s design[1] is likely to be beneficial for Swift. I don’t think we 
should just cargo-cult its constructs verbatim, but our eventual design is 
likely to be influenced by it. Swift’s tendency for clarity over terseness 
means that these concepts might look different on the surface, and Swift’s type 
system is very different from Perl 6’s, but we should certainly steal the best 
ideas. Good languages copy; great languages steal!

This design discussion will likely unfold over the coming months. In the mean 
time, I’m interested in playing with your approach and the kinds of problems it 
solves cleanly and effectively. Could you link to an SPM package implementing 
this? Do you have example code using it?

[1] https://docs.perl6.org/language/regexes


> On Aug 10, 2017, at 2:58 AM, Ben Cohen via swift-evolution 
>  wrote:
> 
> 
> Hi Joshua,
> 
> Thanks for bringing this topic up. It may help to outline why regular 
> expressions were deferred until Swift 5. The work to create a regular 
> expression type itself, and even to add a regex literal protocol, is fairly 
> straightforward and probably could have been done in the Swift 4 timeframe 
> (maybe by making NSRegularExpression a value type and refreshing its API), 
> but there are other design aspects that we need to explore prior to that, 
> many of which have compiler impact, or would need to factor in the underlying 
> representation of string in order to be efficient, in order to make 
> Swift-native regular expressions really great.
> 
> Right now, the top priority for Swift 5 is ABI stability, and String plays a 
> fairly large part in that. We need to finalize the size of String (currently 
> 3 words, but 2 is the likely final size), implement the small string 
> optimization, and decide which parts of String need to be fragile/inlineable 
> and which need to be resilient.
> 
> Since ABI stability takes priority, this give us time in the mean-time to 
> consider the broader design questions of what Swift-native regular 
> expressions would look like. These design considerations probably need to 
> come ahead of designing an API for specific types like a regex, matches etc.
> 
> Some examples of these kind of questions include:
> 
> What syntax changes to the usual form of regexes should be considered? For 
> example, what should “.” mean in regular expressions? It would be out of 
> keeping for it to mean a code unit, when applied to Swift.String. 
> Alternatively, should regular expressions work on all the views? In which 
> case, “.” could mean a grapheme when applied to String, but a code unit when 
> applied to the UTF16 view.
> 
> How can let bindings work on capture groups i.e. rather than having named 
> capture groups like in Perl, can we bind directly to variables in switches 
> etc? Could types conform to a RegularExpressionCapturable that would consume 
> part of the string and initialize self, so that you could capture not just 
> Substring but any type? You can’t express this in the language today, and 
> would need compiler integration. This integration could start more hard-coded 
> in order to deliver value in the Swift 5 release, but hopefully be 
> generalizable in later releases.
> 
> What other std lib APIs should be changed once we have regular expressions? 
> For example, split ought to work with regexes e.g. let words = 
> sentence.split(separator: /\w+/). How can this generalize to Collections 
> where possible? E.g. [1,2,3,4].index(of: [2,3]) ought to work just as 
> “abcd”.index(of: /bc/) should.
> 
> On Aug 10, 2017, at 7:24 AM, Joshua Alvarado via swift-evolution 
> > wrote:
> 
>> Hey everyone,
>> 
>> I would like to pitch an implementation of Regex in Swift and gather all of 
>> your thoughts.
>> 
>> Motivation:
>> In the String Manifesto for Swift 4, addressing regular expressions was not 
>> in scope. Swift 5 would be a more fitting version to 

Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Dave DeLong via swift-evolution

> On Aug 10, 2017, at 11:48 AM, Tino Heth via swift-evolution 
>  wrote:
> 
> I guess everyone agrees that there should be support for regular expressions 
> - I'm just not sure where, how and when to integrate it…
> People seem to have a (sometimes unhealthy…) passion for regex, so I'd like 
> to encourage a critical look on their importance.
> For example, I don't think they belong into the stdlib — there are more basic 
> (and much more simple) things like a Result-type or an operator for function 
> concatenation which are not included, so why should we treat regular 
> expressions differently?
> But It doesn't look like we'll see a fitting library that's bundled with 
> Swift anytime soon, and third-party regex Frameworks imho would cause big 
> confusion.

This goes back to the idea of “non-standard libraries” that ship with Swift, 
but aren’t imported by default. I think a “Swift.Regex” module would be 
awesome, but I agree that it probably doesn’t need to be in the standard 
library.

Dave

> 
> Anyways, as you suggest a special syntax, it would be required to integrate 
> support into Swift itself… although this is even deeper than the stdlib, I'm 
> more positive towards that direction, as it would allow some neat tricks:
> The expressions could not only be checked, but also translated at compile 
> time — which could give Swift a real kickstart to beat established solutions 
> in terms of execution speed.
> It would, on the other hand, not work for non-literal strings, so regular 
> expressions that are created at runtime would still need extra support…
> 
> If Core would consider to include compile-time regular expressions in the 
> future, I'd support adding the new syntax, even if it's only used like 
> NSExpression in the first implementation. Without that option, I think it's 
> not worth it, and I'd rather try to use custom operators to build matchers 
> that don't follow any regex standard, but are fast and safe to use.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 10, 2017, at 09:15, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 10.08.2017 18:22, Adrian Zubarev via swift-evolution wrote:
>> I think this design does not avoid you writing something like `private enum 
>> Foo { default ... }`, which is redudant as Jordan already pointed out in his 
>> previous post, nor does it have a consistent way of declaration:
> 
> Why compiler can't require 'open' enums to be public only? So, you can write 
> but this will not compile. No?
> 
>> enum Foo {
>>   case abc
>>   case def
>>   default
>> }
>> enum Foo {
>>   case abc
>>   default
>>   case def
>> }
>> enum Foo {
>>   default
>>   case abc
>>   case def
>> }
>> 
> 
> Why compiler can't require 'default' be declared only after last 'case' ?
> 
>> On the other hand I'd be very much in favor of the design David has pitched, 
>> which makes `public` as a soft default for public API's and adds a stronger 
>> constraints with an extra keyword OR a different access modifier. In case of 
>> an access modifier it would be really interesting if someone knows other use 
>> cases where we could reuse `closed` for similar purposes.
>> Long story short:
>> - public is the soft default and all uses of an enum from module A in module 
>> B would require `default` in swithch statements
>> - closed is the stronger implied `public` which makes the enum finite and 
>> does not require `default` if you switch on all cases
> 
> Can't agree. Default-like 'public' for class also allows compiler to make its 
> optimizations as it is known that there can't be a subclass of published 
> class.
> 
> 'public' for enum will in inverse block optimizations, as there is no 
> guarantee that enum will be the same and will not change in future.

Without commenting on the rest of this at the moment, this is incorrect. A 
'public' class may have subclasses in the same module (public or non-public), 
and a 'public' class in a binary framework is also permitted to become 'open' 
in the future.

Jordan


> 
> IMO the developer of external API should explicitly mark public enum as 
> 'closed' or as 'open', to be concrete if changes in enum should/will lead to 
> new major version of framework(so can't be changed in current version) or 
> most likely this enum will be extended in next minor update and then "it 
> might suddenly grow a new case containing a struct with 5000 Strings in 
> it"(Jordan Rose)

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Jordan Rose via swift-evolution
[Proposal: 
https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
 
]

Hi, Tony. Glad to see this back again!

Overall I'm an enthusiastic +1. The restrictions and future work you've listed 
make sense, and I think this is the right starting place. I just have one thing 
I'd want to clarify:

> Any user-provided implementations of == or hashValue will override the 
> default implementations that would be provided by the compiler.

Does this include implementations in (possibly constrained) protocol 
extensions? I assume yes, but that's probably worth calling out explicitly. 
Still, it could be confusing to some users.

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


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Tino Heth via swift-evolution
I guess everyone agrees that there should be support for regular expressions - 
I'm just not sure where, how and when to integrate it…
People seem to have a (sometimes unhealthy…) passion for regex, so I'd like to 
encourage a critical look on their importance.
For example, I don't think they belong into the stdlib — there are more basic 
(and much more simple) things like a Result-type or an operator for function 
concatenation which are not included, so why should we treat regular 
expressions differently?
But It doesn't look like we'll see a fitting library that's bundled with Swift 
anytime soon, and third-party regex Frameworks imho would cause big confusion.

Anyways, as you suggest a special syntax, it would be required to integrate 
support into Swift itself… although this is even deeper than the stdlib, I'm 
more positive towards that direction, as it would allow some neat tricks:
The expressions could not only be checked, but also translated at compile time 
— which could give Swift a real kickstart to beat established solutions in 
terms of execution speed.
It would, on the other hand, not work for non-literal strings, so regular 
expressions that are created at runtime would still need extra support…

If Core would consider to include compile-time regular expressions in the 
future, I'd support adding the new syntax, even if it's only used like 
NSExpression in the first implementation. Without that option, I think it's not 
worth it, and I'd rather try to use custom operators to build matchers that 
don't follow any regex standard, but are fast and safe to use.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enums and Source Compatibility - defaults

2017-08-10 Thread Jordan Rose via swift-evolution


> On Aug 9, 2017, at 22:46, David Hart  wrote:
> 
> 
>> On 10 Aug 2017, at 02:42, Jordan Rose > > wrote:
>> 
>> :-) As you've all noted, there are some conflicting concerns for the default:
>> 
>> - Source compatibility: the existing behavior for an unannotated enum is 
>> "closed".
>> - Intuition: if you show someone an enum without an explicit annotation, 
>> they'll probably expect they can switch over it. (I'm going to say this is 
>> why Zach calls it a "sensible default".)
>> - Consistency: switches on an enum in the same module can always be 
>> exhaustive, so having it be different across modules is a bit annoying. (But 
>> 'public' already acts like this.)
>> 
>> vs.
>> 
>> - Library evolution: the default should promise less, so that you have the 
>> opportunity to change it.
>> - Flexibility: you can emulate an exhaustive switch with a non-exhaustive 
>> switch using fatalError, but not the other way around.
>> 
>> All of this is why I suggested it be an explicit annotation in either 
>> direction, but Matthew brought up the "keyword soup" problem—if you have to 
>> write (say) "public finite enum" and "public infinite enum", but would never 
>> write "private finite enum" or "private infinite enum", something is 
>> redundant here. Still, I'm uncomfortable with the default case being the one 
>> that constrains library authors, so at least for binary frameworks (those 
>> compiled "with resilience") I would want that to be explicit. That brings us 
>> to one more concern: how different should binary frameworks be from source 
>> frameworks?
> 
> In terms of intuition and consistency, I think we should really try to learn 
> from the simplicity of public/open:
> 
> * When internal, classes are sub-classable by default for convenience, but 
> can be closed with the final keyword
> * When public, classes are closed to sub-classing for safety, but can be 
> opened up with the open keyword (which implies public).
> 
> If we try to mirror this behaviour (the keywords are just suggestions, not 
> important):
> 
> * When internal, enums are exhaustive by default for convenience, but can be 
> opened-up with the partial keyword
> * When public, enums are non-exhaustive by default for safety, but can be 
> made exhaustive with the exhaustive keyword (which implies public).

This is not a correct understanding of the internal/public distinction for 
classes, though. From inside a module, a public-but-not-open class is still 
subclassable, and similarly a public-but-not-"closed" enum will still be 
exhaustively switched. You don't have to worry about your own module changing 
out from under you.

Jordan

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


Re: [swift-evolution] private extension

2017-08-10 Thread Xiaodi Wu via swift-evolution
Vladimir, please follow the link for the previous discussion. There are
several reasons outlined by core team members why they felt this was not a
bug, so it is definitely not the case that there are no opinions to that
effect. It was a very thorough conversation on the topic, and I’m not sure
what further statement you’d want from them.
On Thu, Aug 10, 2017 at 09:12 Vladimir.S via swift-evolution <
swift-evolution@swift.org> wrote:

> FWIW, I can't agree that this particular subject leads to huge
> discussion/battle
> about all the access modifiers. It is just about 'private extension'
> inconsistency,
> not more. And it seems like there no(?) opinions that current situation
> with private
> extension has any sense. It really looks like a bug.
>
> So, I'd like to ask, if it is possible, some note about the subject from
> core team. I
> hope they can revisit their decision to not even discuss *this particular*
> confusing
> case with private extension.
>
> On 10.08.2017 16:28, Tino Heth via swift-evolution wrote:
> >
> >> I agree, but after having originally raised the issue, members of the
> core team
> >> clearly disagreed. Therefore, it's clear that this is going to have to
> go through
> >> Swift Evolution or not be changed at all. And I also agree with the
> notion that
> >> further discussions of access modifiers, which will most certainly lead
> to a rehash
> >> of the whole sordid past, is unhealthy.
> > I guess that is the price to pay for stability… I personally am quite
> sad that Swift
> > reached that phase already.
> > But who knows — maybe after some years of collecting legacy, this might
> be discussed
> > again in a cleanup release of Swift.
> >
> > Still, I think the current situation is a pity, as everyone seems to
> agree that we
> > ended up with a flawed solution for access control :-(
> >
> >
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Vladimir.S via swift-evolution

On 10.08.2017 18:22, Adrian Zubarev via swift-evolution wrote:
I think this design does not avoid you writing something like `private enum Foo { 
default ... }`, which is redudant as Jordan already pointed out in his previous post, 
nor does it have a consistent way of declaration:


Why compiler can't require 'open' enums to be public only? So, you can write but this 
will not compile. No?




enum Foo {
   case abc
   case def
   default
}

enum Foo {
   case abc
   default
   case def
}

enum Foo {
   default
   case abc
   case def
}




Why compiler can't require 'default' be declared only after last 'case' ?



On the other hand I'd be very much in favor of the design David has pitched, which 
makes `public` as a soft default for public API's and adds a stronger constraints 
with an extra keyword OR a different access modifier. In case of an access modifier 
it would be really interesting if someone knows other use cases where we could reuse 
`closed` for similar purposes.


Long story short:
- public is the soft default and all uses of an enum from module A in module B would 
require `default` in swithch statements
- closed is the stronger implied `public` which makes the enum finite and does not 
require `default` if you switch on all cases


Can't agree. Default-like 'public' for class also allows compiler to make its 
optimizations as it is known that there can't be a subclass of published class.


'public' for enum will in inverse block optimizations, as there is no guarantee that 
enum will be the same and will not change in future.


IMO the developer of external API should explicitly mark public enum as 'closed' or 
as 'open', to be concrete if changes in enum should/will lead to new major version of 
framework(so can't be changed in current version) or most likely this enum will be 
extended in next minor update and then "it might suddenly grow a new case containing 
a struct with 5000 Strings in it"(Jordan Rose)


Vladimir.


--
Adrian Zubarev
Sent with Airmail

Am 10. August 2017 um 16:55:00, Matthew Johnson via swift-evolution 
(swift-evolution@swift.org ) schrieb:




On Aug 10, 2017, at 9:25 AM, Vladimir.S > wrote:


On 10.08.2017 16:46, Matthew Johnson via swift-evolution wrote:

On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution
> wrote:
Since it seems to have been lost in the noise, I want to second with support for
Xiaodi's syntax of having `default` appearing in the enum declaration itself.
It's much clearer in its intention, feels very ‘Swifty’, and more importantly it
doesn't prompt whole threads debating the semantics of `open` vs `public`.

I think Xiaodi’s syntax is very elegant if we want to avoid the access control
style syntax.  However, it does one problem: the “error of omission” (not 
thinking
about open vs closed) leaves a library author with a closed enum, preventing 
them
from adding cases in the future without breaking compatibility.  I’m not sure 
this
is acceptable.


Then, doesn't this mean that any 'usual' enum should be 'open' by default, and 
only enum declared with some marker (like 'final' or 'enum(sealed)') can be 'closed'?


Otherwise we need to require an explicit marker for *each* enum, and so break the 
source compatibility? (we'll have to append that marker to each enum in your 
current code)


This is a good point.  A good first decision is whether we prioritize source 
compatibility or the more conservative “default”.  If source compatibility is 
prioritized Xiaodi’s proposed syntax is probably hard to beat.




Also I'd suggest this for closed enum:

enum MyClosedEnum {
 case a
 case b
 case c
 final
}

So, for public closed enum it will looks like:

public enum MyClosedEnum {
 case a
 case b
 case c
 final
}

Also, if we need to explicitly mark open enum, probably we can consider 'continue' 
keyword, as IMO is not clear what 'default' is saying on declaration site('you 
must insert `default` in switch'? 'there are other `default` cases'?) :


public enum MyOpenEnum {
 case a
 case b
 case c
 continue // to be continue...
}


 Begin Message  Group: gmane.comp.lang.swift.evolution 
MsgID: 

Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Jacob Williams via swift-evolution
Disclaimer: I am not well versed in the various complexities of regex 
implementations.

That being said, I would very much like to see better regex support in Swift. 
Preferably one that is easier to pick up than the NSRegularExpression of ObjC 
and possibly as easy to start using as python or ruby.

Just some things to consider for the implementation:

- Plain old searching for a match
- Multiple (named) capture groups
- I liked the suggestion of binding straight to variables (perhaps with 
closures)
- Replacements
- I’m also not a fan of using the backslash for instantiating a regex literal. 
Many other languages use the forward slash (Off the top of my head all I can 
think of is Ruby, but I’m sure there are others)


> On Aug 10, 2017, at 4:28 AM, Omar Charif via swift-evolution 
>  wrote:
> 
> Hi Joshua,
> 
> I also feel a huge gap when it comes to string matching, whether it is 
> implementation or performance.
> I also wrote a library for String matching called StringMap and it has been 
> way for performant than regular expressions.
> I recently proposed to include it in core foundation but it seems that I was 
> a bit late and the team was busy finishing their unimplemented functions so 
> they advised me to ship the code in SPM instead.
> So I am also willing to work in this issue.
> 
> 
> 
> 
>> On Aug 10, 2017, at 8:25 AM, Joshua Alvarado via swift-evolution 
>> > wrote:
>> 
>> Hey everyone,
>> 
>> I would like to pitch an implementation of Regex in Swift and gather all of 
>> your thoughts.
>> 
>> Motivation:
>> In the String Manifesto for Swift 4, addressing regular expressions was not 
>> in scope. Swift 5 would be a more fitting version to address the 
>> implementation of Regex in Swift. NSRegularExpression is a suitable solution 
>> for pattern matching but the API is in unfitting for the future direction of 
>> Swift.
>> 
>> Implementation:
>> The Regular expression API will be implemented by a Regex structure object 
>> which is a regular expression that you can apply to Unicode strings. The 
>> Regex struct will conform to the RegexProtocol, which is a type that can 
>> represent a regular expression. ExpressibleByRegexLiteral will be used to 
>> initialize a regex literal creating an easy to use syntax and a Match 
>> structure will be used to represent a match found with a Regex.
>> 
>> Draft of implementation:
>> 
>> protocol ExpressibleByRegexLiteral {
>> associatedtype RegexLiteralType
>> 
>> init(regexLiteral value: Self.RegexLiteralType)
>> }
>> 
>> // Structure of information about a match of regex on a string
>> struct Match {
>> var regex: Regex
>> var start: String.Index
>> var end: String.Index
>> }
>> 
>> protocol RegexProtocol {
>> init(pattern: String) throws
>> 
>> var pattern: String { get } // string representation of the pattern
>> func search(string: String) -> Bool // used to check if a match is found 
>> at all in the string
>> func match(string: String) -> [Match] // returns an array of all the 
>> matches
>> func match(string: String, using: ((Match) -> Void)) // enmuerate over 
>> matches
>> }
>> 
>> struct Regex: RegexProtocol {
>> init(pattern: Regex, options: Regex.Options)
>> let options: [Regex.Options]
>> static let word: Regex // \w
>> // other useful regexes can be added as well
>> }
>> 
>> // Examples
>> 
>> let regex = \[a-zA-Z]+\
>> let matches = regex.match("Matching words in text.")
>> 
>> for match in matches {
>> print("Found a match at in string at \(match.start) to \(match.end)")
>> }
>> 
>> let helloStr = "Hello world"
>> 
>> Regex.word.match(helloStr) { match in
>> print("Matched \(helloStr[match.start..> }
>>  
>> Of course this is a scratch implementation I made but it is to open 
>> discussion on the topic. I feel the Regex struct itself will need more 
>> methods and variables such as for flags and number of groups. Please provide 
>> feedback with improvements to the code, concerns on the topic, or just open 
>> up discussion. Thank you!
>> 
>> Joshua Alvarado
>> alvaradojosh...@gmail.com 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Shawn Erickson via swift-evolution
> My hunch is that structs and enums where such volatile data exists are the
> exception, not the norm, when it comes to considering equality. This
> proposal is very much intended to be useful syntactic sugar for the common
> case while not preventing any existing behavior (providing your own
> implementation) and alluding to future directions where the behavior can be
> extended to other use cases.
>

I have similar concerns to Haravikk and I also understand the reasoning you
outline.

Reviewing code of ours and thinking back in time to prior (pre-swift
projects) I currently think that automatic synthesis by simple statement of
adopting Equat/Hashable would only be possible for the simplest of data
structs and classes. It is often that more (slightly) complex structs and
classes have various bookkeeping, metadata, and/or caching properties that
should not be considered in the synthesized code however theses object are
maintained in data structures that depend on Equat/Hashable conformance. In
other words I would have to write an implementation myself (despite a
synthesized version could be done if a subset of properties could be
excluded) or possibly I would adopt one of those protocols and mistakenly
forget to write my own implementation because automatic synthesis kicks in
causing a lurking problem (so hopefully be quickly discovered).

Also for data structs/classes built to deal with data exchange, say with a
server API using JSON, the resulting data objects that leverage the new
codable stuff in Swift 4 will almost universally have things that would
allow automatic synthesis of Equat/Hashable however equally universally the
equality of two objects decoded would depend on a small subset of the
properties contained in the object (say a server id and some number of
additional scoping ids). So I doubt that simply using something that would
opt-out elements from automatic coding would map directly to opt-out of
automatic compatibility, it wouldn't be a 1:1 mapping... likely seldom
would it be in my experience.

So at this time this feature would likely be of little utility to me in my
code.

With all that said... I want this feature +1 but with some futur things
being omitted I won't gain much near term benefit form it.

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


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Adrian Zubarev via swift-evolution
I think this design does not avoid you writing something like `private enum Foo 
{ default ... }`, which is redudant as Jordan already pointed out in his 
previous post, nor does it have a consistent way of declaration:  

enum Foo {  
 case abc
 case def
 default
}

enum Foo {  
 case abc
 default
 case def
}


enum Foo {  
 default
 case abc
 case def
}

  

On the other hand I'd be very much in favor of the design David has pitched, 
which makes `public` as a soft default for public API's and adds a stronger 
constraints with an extra keyword OR a different access modifier. In case of an 
access modifier it would be really interesting if someone knows other use cases 
where we could reuse `closed` for similar purposes.  

Long story short:  
- public is the soft default and all uses of an enum from module A in module B 
would require `default` in swithch statements
- closed is the stronger implied `public` which makes the enum finite and does 
not require `default` if you switch on all cases
--  
Adrian Zubarev
Sent with Airmail  

Am 10. August 2017 um 16:55:00, Matthew Johnson via swift-evolution 
(swift-evolution@swift.org(mailto:swift-evolution@swift.org)) schrieb:

>  
>  
> > On Aug 10, 2017, at 9:25 AM, Vladimir.S 
> >  wrote:  
> > On 10.08.2017 16:46, Matthew Johnson via swift-evolution wrote:
> > > > On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution
> > > >  wrote:
> > > > Since it seems to have been lost in the noise, I want to second with 
> > > > support for
> > > > Xiaodi's syntax of having `default` appearing in the enum declaration 
> > > > itself.
> > > > It's much clearer in its intention, feels very ‘Swifty’, and more 
> > > > importantly it
> > > > doesn't prompt whole threads debating the semantics of `open` vs 
> > > > `public`.
> > > I think Xiaodi’s syntax is very elegant if we want to avoid the access 
> > > control
> > > style syntax. However, it does one problem: the “error of omission” (not 
> > > thinking
> > > about open vs closed) leaves a library author with a closed enum, 
> > > preventing them
> > > from adding cases in the future without breaking compatibility. I’m not 
> > > sure this
> > > is acceptable.
> >  
> > Then, doesn't this mean that any 'usual' enum should be 'open' by default, 
> > and only enum declared with some marker (like 'final' or 'enum(sealed)') 
> > can be 'closed'?
> >  
> > Otherwise we need to require an explicit marker for *each* enum, and so 
> > break the source compatibility? (we'll have to append that marker to each 
> > enum in your current code)
>  
> This is a good point. A good first decision is whether we prioritize source 
> compatibility or the more conservative “default”. If source compatibility is 
> prioritized Xiaodi’s proposed syntax is probably hard to beat.  
> >  
> > Also I'd suggest this for closed enum:
> >  
> > enum MyClosedEnum {
> > case a
> > case b
> > case c
> > final
> > }
> >  
> > So, for public closed enum it will looks like:
> >  
> > public enum MyClosedEnum {
> > case a
> > case b
> > case c
> > final
> > }
> >  
> > Also, if we need to explicitly mark open enum, probably we can consider 
> > 'continue' keyword, as IMO is not clear what 'default' is saying on 
> > declaration site('you must insert `default` in switch'? 'there are other 
> > `default` cases'?) :
> >  
> > public enum MyOpenEnum {
> > case a
> > case b
> > case c
> > continue // to be continue...
> > }
> >  
> >  
> > > >  Begin Message  Group: 
> > > > gmane.comp.lang.swift.evolution MsgID: 
> > > > 

Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Tony Allevato via swift-evolution
On Thu, Aug 10, 2017 at 3:40 AM Haravikk via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On 10 Aug 2017, at 10:32, Martin Waitz  wrote:
>
> Hi Haravikk,
>
> Am 2017-08-10 11:07, schrieb Haravikk via swift-evolution:
>
> I don't feel that conforming to
> Equatable/Hashable is sufficient as an opt-in. Consider for example
> someone who declares their type as Equatable/Hashable, then sets to
> work on the details of their type, forgetting to implement the actual
> equatable/hashable behaviour they want.
>
>
> This is no different than a default implementation of the protocol.
> In fact, the proposal just adds something like this:
>
>extension Struct: Equatable where A: Equatable, B:
> Equatable, ... {
>static func ==(lhs: Self, rhs: Self) -> Bool { /* insert
> implementation here */ }
>}
>
> We don't require/support some special keywords for other protocols with
> default implementation either,
> so I see no reason to add them here.
>
> Your concerns are orthogonal to this proposal and should be discussed
> independently.
>
>
> I disagree.
>
> This is not the same as a default protocol implementation, as a default
> implementation can only act upon properties/methods that are clearly
> defined by the protocol itself. This feature by comparison is an automatic
> implementation that by design must make assumptions about the contents of a
> concrete type.
>
> Consider a type that contains some kind of "volatile" data, i.e-
> properties that are not necessarily crucial to the type, and so should not
> be considered during equality. If I make a mistake and end up using the
> synthesised test for equality, then two values that should be identified as
> equal, will not be equated as such because the synthesised option cannot
> account for implementation details that it has no awareness of.
>

>
This has come up in discussion in the past, where I argued for some means
> of marking values to prevent them from being included in the synthesised
> method(s). This is covered in alternatives as "transient" values, but I
> disagree with the conclusion that this can simply be added later, as it is
> IMO crucial to the way this feature would work.
>

Thanks for your feedback, Haravikk!

My hunch is that structs and enums where such volatile data exists are the
exception, not the norm, when it comes to considering equality. This
proposal is very much intended to be useful syntactic sugar for the common
case while not preventing any existing behavior (providing your own
implementation) and alluding to future directions where the behavior can be
extended to other use cases.

I disagree that @transient is crucial for this feature to work—that feature
only applies to the set of types that contain volatile data, that volatile
data and all the other fields are all Equatable/Hashable, and the user
wants to synthesize Eq/Hash for a subset of its fields. I certainly agree
that such a set is non-empty, but I it's also small enough that it can be
considered at a later date.

It's important for a proposal like this to be as focused and targeted as
possible, and leave features that are not absolutely required for future
directions. For the record, I would *love* to see something like @transient
proposed after this (which is why I call it out in the proposal), but such
a feature would also affect Codable and this proposal should not mix
concerns.


> Even if there were a @transient attribute or whatever from the start, I'd
> still prefer to set this within the context of having explicitly asked for
> Equatable/Hashable to be synthesised, and without such a feature it only
> makes it more crucial that the opt-in occur in a manner more explicit than
> conforming to Equatable/Hashable.
>
> My disagreement pretty much boils down to the fact that I do not feel that
> opting in simply by conforming is sufficient given that the desired
> behaviour is assumed; I strongly feel that a more explicit declaration of
> "I specifically want to use this automatic behaviour" is required, either
> via attribute or conforming to a more explicit protocol.
>

> I actually *like* the fact that conforming to Equatable requires me to
> implement ==, as it ensures that I do-so, and prefer that that behaviour
> remain, as it forces me to do something about it. Even with synthesised
> behaviour as an option, it should be exactly that, an option; i.e- when my
> conformance to Equatable fails, I can choose either to implement ==, or
> opt-in to an automatic substitute.
>

I sympathize with these concerns, and a great deal of thought and
discussion was done around the best way to surface this feature in the last
couple of mailing list threads about this topic. But at the time this
proposal and its implementation were written, the synthesis for Codable had
already been implemented and this proposal adopts the same synthesis
conditions that were used by Codable. Core team members expressed that the

Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Vladimir.S via swift-evolution

On 10.08.2017 3:58, Jordan Rose wrote:
Hi, Vladimir. I think framing this as a consumer decision is the wrong place to 
start. There are some enums that definitely make sense to be "closed", all the time, 
with no additional annotations, including Foundation.NSComparisonResult and, well, 
Swift.Optional. (Yes, Optional is special, and we could always handle it specially if 
we needed to, but it would be /nice/ if it used the same logic as everything else.)


Beyond that, I think something like what you and Charlie describe (your 
'@exhaustive', Charlie's 'switch!') could make sense, as a way to provide a 
deterministic behavior while still getting compiler warnings for not being 
exhaustive. (Probably the only supported behavior here would be trapping, since there 
is no way to test such a scenario with the libraries you currently have.) But I'd 
like to see a real-world example of exhaustively switching over an enum in the SDK 
before designing a feature around this; I strongly suspect it's not something we need…


…/in the binary framework case/. It may still be interesting for source frameworks, 
particularly C enums in those source frameworks.




Hi Jordan. Thank you for comments. It seems like I'm missing something important.. 
Will only SDK framework contains open enums? Can't I wish to have an exhaustive 
switch in my own code regarding some open enum coming from some other's framework and 
to be sure I'm processing all the cases during the compilation time of my code with 
that framework?


I assume everybody(ok,most of us) thanks Swift for helping us keep switch exhaustive 
when we *need* this, so we will not forget to process new *known* cases, and I don't 
understand why this can be changed with 'open' enums.


Yes, for open enums we *have to* process 'future' cases in switch(even if it is 
exhaustive at the moment of compilation), but also for some open enums we *will* need 
a help from Swift compiler to keep our switch exhaustive for the moment of compilation.


And for such switch(exhaustive for known at compilation time cases of open enum), we 
probably should introduce some 'future' keyword:


switch openEnum {
  case .yes: ..
  case .no: ..
  future: ...  // this is for future cases only, all known cases should be 
processed
}

And you can use 'default' as usual, if you don't care of *any* other cases(including 
future cases) in this open enum:


switch openEnum {
  case .yes: ..
  case .no: ..
  default: ...
}

The 'future' or 'default' would be then required for switch on open enum 
instance.

Vladimir.


Jordan


On Aug 9, 2017, at 09:57, Vladimir.S > 
wrote:


Sorry if I misunderstood the subject, but shouldn't this also be a *consumer* 
decision, when one wants to keep own switch exhaustive or it is OK to process all 
possible future cases in 'default'?


If enum is 'closed' - nothing is changed, as I understand, we have the same rules 
for switch as currently.


If 'external' enum, from other framework, was marked as 'closed' but was actually 
changed in new version of framework/module - our source code will fail to compile 
(because we need fix our switch cases) and our binary module(built with previous 
version of framework) will crash.


With 'open' enums, depending on situations, I as a consumer of external framework, 
can decide that it is important to me, in my code, check *each* value of external 
enum in switch. If new enum case added/changed in external framework - my code must 
fail to compile and notify me that new case should be processed.
Once we added 'default' case in 'switch' in our code for 'open' enum - we lost 
compiler's support to keep our 'switch' exhaustive.


But from other side, in other situation, I want to process all new cases for 'open' 
enum in 'default' branch, and so allow my source/compiled code to work with new 
version of framework(with added cases).


So, it seems like in both situations we need to explicitly tell what is our decided 
behavior for new cases for 'open' enum in exhaustive switch : crash/fail to compile 
or process in 'default' block.


What if in case of exhaustive switch on 'open' enum, compiler warns us saying "this 
is an exhaustive switch on 'open' enum, but cases can be added later. clarify what 
is your decided behaviour. by default your code will crash if new cases are added"
, then we can add 'default' block to process new future cases or somehow mark that 
switch as explicitly exhaustive... something like this:


@exhaustive
switch openEnum {
 case .yes : ...
 case .no : ...
}

What I'm missing?

On 09.08.2017 1:27, Jordan Rose via swift-evolution wrote:
Hi, everyone. Now that Swift 5 is starting up, I'd like to circle back to an issue 
that's been around for a while: the source compatibility of enums. Today, it's an 
error to switch over an enum without handling all the cases, but this breaks down 
in a number of ways:
- A C enum may have "private cases" that aren't defined 

Re: [swift-evolution] Enums and Source Compatibility

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

> On Aug 10, 2017, at 9:25 AM, Vladimir.S  wrote:
> 
> On 10.08.2017 16:46, Matthew Johnson via swift-evolution wrote:
>>> On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution
>>> > wrote:
>>> Since it seems to have been lost in the noise, I want to second with 
>>> support for
>>> Xiaodi's syntax of having `default` appearing in the enum declaration 
>>> itself.
>>> It's much clearer in its intention, feels very ‘Swifty’, and more 
>>> importantly it
>>> doesn't prompt whole threads debating the semantics of `open` vs `public`.
>> I think Xiaodi’s syntax is very elegant if we want to avoid the access 
>> control
>> style syntax.  However, it does one problem: the “error of omission” (not 
>> thinking
>> about open vs closed) leaves a library author with a closed enum, preventing 
>> them
>> from adding cases in the future without breaking compatibility.  I’m not 
>> sure this
>> is acceptable.
> 
> Then, doesn't this mean that any 'usual' enum should be 'open' by default, 
> and only enum declared with some marker (like 'final' or 'enum(sealed)') can 
> be 'closed'?
> 
> Otherwise we need to require an explicit marker for *each* enum, and so break 
> the source compatibility? (we'll have to append that marker to each enum in 
> your current code)

This is a good point.  A good first decision is whether we prioritize source 
compatibility or the more conservative “default”.  If source compatibility is 
prioritized Xiaodi’s proposed syntax is probably hard to beat.

> 
> Also I'd suggest this for closed enum:
> 
> enum MyClosedEnum {
>  case a
>  case b
>  case c
>  final
> }
> 
> So, for public closed enum it will looks like:
> 
> public enum MyClosedEnum {
>  case a
>  case b
>  case c
>  final
> }
> 
> Also, if we need to explicitly mark open enum, probably we can consider 
> 'continue' keyword, as IMO is not clear what 'default' is saying on 
> declaration site('you must insert `default` in switch'? 'there are other 
> `default` cases'?) :
> 
> public enum MyOpenEnum {
>  case a
>  case b
>  case c
>  continue // to be continue...
> }
> 
> 
>>>  Begin Message  Group: 
>>> gmane.comp.lang.swift.evolution MsgID: 
>>> 

Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Vladimir.S via swift-evolution

On 10.08.2017 16:46, Matthew Johnson via swift-evolution wrote:



On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution
 wrote:

Since it seems to have been lost in the noise, I want to second with support for
Xiaodi's syntax of having `default` appearing in the enum declaration itself.

It's much clearer in its intention, feels very ‘Swifty’, and more importantly it
doesn't prompt whole threads debating the semantics of `open` vs `public`.


I think Xiaodi’s syntax is very elegant if we want to avoid the access control
style syntax.  However, it does one problem: the “error of omission” (not 
thinking
about open vs closed) leaves a library author with a closed enum, preventing 
them
from adding cases in the future without breaking compatibility.  I’m not sure 
this
is acceptable.


Then, doesn't this mean that any 'usual' enum should be 'open' by default, and only 
enum declared with some marker (like 'final' or 'enum(sealed)') can be 'closed'?


Otherwise we need to require an explicit marker for *each* enum, and so break the 
source compatibility? (we'll have to append that marker to each enum in your current 
code)


Also I'd suggest this for closed enum:

enum MyClosedEnum {
  case a
  case b
  case c
  final
}

So, for public closed enum it will looks like:

public enum MyClosedEnum {
  case a
  case b
  case c
  final
}

Also, if we need to explicitly mark open enum, probably we can consider 'continue' 
keyword, as IMO is not clear what 'default' is saying on declaration site('you must 
insert `default` in switch'? 'there are other `default` cases'?) :


public enum MyOpenEnum {
  case a
  case b
  case c
  continue // to be continue...
}






 Begin Message  Group: gmane.comp.lang.swift.evolution 
MsgID: 

Re: [swift-evolution] private extension

2017-08-10 Thread Vladimir.S via swift-evolution
FWIW, I can't agree that this particular subject leads to huge discussion/battle 
about all the access modifiers. It is just about 'private extension' inconsistency, 
not more. And it seems like there no(?) opinions that current situation with private 
extension has any sense. It really looks like a bug.


So, I'd like to ask, if it is possible, some note about the subject from core team. I 
hope they can revisit their decision to not even discuss *this particular* confusing 
case with private extension.


On 10.08.2017 16:28, Tino Heth via swift-evolution wrote:


I agree, but after having originally raised the issue, members of the core team 
clearly disagreed. Therefore, it's clear that this is going to have to go through 
Swift Evolution or not be changed at all. And I also agree with the notion that 
further discussions of access modifiers, which will most certainly lead to a rehash 
of the whole sordid past, is unhealthy.
I guess that is the price to pay for stability… I personally am quite sad that Swift 
reached that phase already.
But who knows — maybe after some years of collecting legacy, this might be discussed 
again in a cleanup release of Swift.


Still, I think the current situation is a pity, as everyone seems to agree that we 
ended up with a flawed solution for access control :-(



___
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] Enums and Source Compatibility

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

> On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution 
>  wrote:
> 
> Since it seems to have been lost in the noise, I want to second with support 
> for Xiaodi's syntax of having `default` appearing in the enum declaration 
> itself.
> 
> It's much clearer in its intention, feels very ‘Swifty’, and more importantly 
> it doesn't prompt whole threads debating the semantics of `open` vs `public`.

I think Xiaodi’s syntax is very elegant if we want to avoid the access control 
style syntax.  However, it does one problem: the “error of omission” (not 
thinking about open vs closed) leaves a library author with a closed enum, 
preventing them from adding cases in the future without breaking compatibility. 
 I’m not sure this is acceptable.

> 
>  Begin Message  
> Group: gmane.comp.lang.swift.evolution 
> MsgID: 

Re: [swift-evolution] private extension

2017-08-10 Thread Tino Heth via swift-evolution

> I agree, but after having originally raised the issue, members of the core 
> team clearly disagreed. Therefore, it's clear that this is going to have to 
> go through Swift Evolution or not be changed at all. And I also agree with 
> the notion that further discussions of access modifiers, which will most 
> certainly lead to a rehash of the whole sordid past, is unhealthy.
I guess that is the price to pay for stability… I personally am quite sad that 
Swift reached that phase already.
But who knows — maybe after some years of collecting legacy, this might be 
discussed again in a cleanup release of Swift.

Still, I think the current situation is a pity, as everyone seems to agree that 
we ended up with a flawed solution for access control :-(___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread James Froggatt via swift-evolution
Since it seems to have been lost in the noise, I want to second with support 
for Xiaodi's syntax of having `default` appearing in the enum declaration 
itself.

It's much clearer in its intention, feels very ‘Swifty’, and more importantly 
it doesn't prompt whole threads debating the semantics of `open` vs `public`.

 Begin Message  
Group: gmane.comp.lang.swift.evolution 
MsgID: 

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-08-10 Thread Tino Heth via swift-evolution
Imho this topic was much better than that other one ;-) — and I just realised 
that of metaprogramming build on top of reflection wasn't discussed in its own 
thread yet…
I fear "constexpr" is already burned, because people associate it with things 
like calculating Fibonacci numbers at compile time (which is kind of cool, but 
doesn't have much merit for most of us).

Right now, there is SE-185, which allows to synthesise Equatable and Hashable.
To do so, nearly 1500 lines of C++ are needed, and even if we assume that two 
thirds are comments and whitespace, it's still a big piece of code that could 
only be written by someone with deep knowledge about C++ and the Swift compiler.
Compile time metaprogramming could do the same, but in probably less than 
twenty lines of Swift that could be written rather easily by anyone who knows 
the language…

So to update my list of things that might be added, there are also some points 
that are already there and whose implementation could have been simplified 
drastically:
> - Forwarding of protocol conformance (Kotlin, for example, has this: When a 
> member conforms to a protocol, you don't have to write a bunch of methods 
> that just say "let my member do this")
> - init with reduced boilerplate
> - Subtyping for non-class types, including a "newtype" option
> - Property behaviours
- Equatable, Hashabable
- Encoding/Decoding

I still wonder that virtually no one else seems to be thrilled about the power 
of the idea… @gor.f.gyolchanyan would you like join an attempt to raise the 
attention?

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Elviro Rocca via swift-evolution
Huge +1

This should have been there from Swift 1, and basically forced me to use 
Sourcery to automatically generate all that code.


Elviro

> Il giorno 10 ago 2017, alle ore 01:09, Chris Lattner via swift-evolution 
>  ha scritto:
> 
> Hello Swift community,
> 
> The review of SE-0185 - "Synthesizing Equatable and Hashable conformance" 
> begins now and runs through August 15, 2017. The proposal is available here:
> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at:
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   • What is your evaluation of the proposal?
>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   • Does this proposal fit well with the feel and direction of Swift?
>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at:
> https://github.com/apple/swift-evolution/blob/master/process.md
> 
> 
> Thank you,
> 
> Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Haravikk via swift-evolution

> On 10 Aug 2017, at 10:32, Martin Waitz  wrote:
> 
> Hi Haravikk,
> 
> Am 2017-08-10 11:07, schrieb Haravikk via swift-evolution:
>> I don't feel that conforming to
>> Equatable/Hashable is sufficient as an opt-in. Consider for example
>> someone who declares their type as Equatable/Hashable, then sets to
>> work on the details of their type, forgetting to implement the actual
>> equatable/hashable behaviour they want.
> 
> This is no different than a default implementation of the protocol.
> In fact, the proposal just adds something like this:
> 
>extension Struct: Equatable where A: Equatable, B: Equatable, 
> ... {
>static func ==(lhs: Self, rhs: Self) -> Bool { /* insert 
> implementation here */ }
>}
> 
> We don't require/support some special keywords for other protocols with 
> default implementation either,
> so I see no reason to add them here.
> 
> Your concerns are orthogonal to this proposal and should be discussed 
> independently.

I disagree.

This is not the same as a default protocol implementation, as a default 
implementation can only act upon properties/methods that are clearly defined by 
the protocol itself. This feature by comparison is an automatic implementation 
that by design must make assumptions about the contents of a concrete type.

Consider a type that contains some kind of "volatile" data, i.e- properties 
that are not necessarily crucial to the type, and so should not be considered 
during equality. If I make a mistake and end up using the synthesised test for 
equality, then two values that should be identified as equal, will not be 
equated as such because the synthesised option cannot account for 
implementation details that it has no awareness of.

This has come up in discussion in the past, where I argued for some means of 
marking values to prevent them from being included in the synthesised 
method(s). This is covered in alternatives as "transient" values, but I 
disagree with the conclusion that this can simply be added later, as it is IMO 
crucial to the way this feature would work. Even if there were a @transient 
attribute or whatever from the start, I'd still prefer to set this within the 
context of having explicitly asked for Equatable/Hashable to be synthesised, 
and without such a feature it only makes it more crucial that the opt-in occur 
in a manner more explicit than conforming to Equatable/Hashable.

My disagreement pretty much boils down to the fact that I do not feel that 
opting in simply by conforming is sufficient given that the desired behaviour 
is assumed; I strongly feel that a more explicit declaration of "I specifically 
want to use this automatic behaviour" is required, either via attribute or 
conforming to a more explicit protocol.

I actually like the fact that conforming to Equatable requires me to implement 
==, as it ensures that I do-so, and prefer that that behaviour remain, as it 
forces me to do something about it. Even with synthesised behaviour as an 
option, it should be exactly that, an option; i.e- when my conformance to 
Equatable fails, I can choose either to implement ==, or opt-in to an automatic 
substitute.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Omar Charif via swift-evolution
Hi Joshua,

I also feel a huge gap when it comes to string matching, whether it is 
implementation or performance.
I also wrote a library for String matching called StringMap and it has been way 
for performant than regular expressions.
I recently proposed to include it in core foundation but it seems that I was a 
bit late and the team was busy finishing their unimplemented functions so they 
advised me to ship the code in SPM instead.
So I am also willing to work in this issue.




> On Aug 10, 2017, at 8:25 AM, Joshua Alvarado via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I would like to pitch an implementation of Regex in Swift and gather all of 
> your thoughts.
> 
> Motivation:
> In the String Manifesto for Swift 4, addressing regular expressions was not 
> in scope. Swift 5 would be a more fitting version to address the 
> implementation of Regex in Swift. NSRegularExpression is a suitable solution 
> for pattern matching but the API is in unfitting for the future direction of 
> Swift.
> 
> Implementation:
> The Regular expression API will be implemented by a Regex structure object 
> which is a regular expression that you can apply to Unicode strings. The 
> Regex struct will conform to the RegexProtocol, which is a type that can 
> represent a regular expression. ExpressibleByRegexLiteral will be used to 
> initialize a regex literal creating an easy to use syntax and a Match 
> structure will be used to represent a match found with a Regex.
> 
> Draft of implementation:
> 
> protocol ExpressibleByRegexLiteral {
> associatedtype RegexLiteralType
> 
> init(regexLiteral value: Self.RegexLiteralType)
> }
> 
> // Structure of information about a match of regex on a string
> struct Match {
> var regex: Regex
> var start: String.Index
> var end: String.Index
> }
> 
> protocol RegexProtocol {
> init(pattern: String) throws
> 
> var pattern: String { get } // string representation of the pattern
> func search(string: String) -> Bool // used to check if a match is found 
> at all in the string
> func match(string: String) -> [Match] // returns an array of all the 
> matches
> func match(string: String, using: ((Match) -> Void)) // enmuerate over 
> matches
> }
> 
> struct Regex: RegexProtocol {
> init(pattern: Regex, options: Regex.Options)
> let options: [Regex.Options]
> static let word: Regex // \w
> // other useful regexes can be added as well
> }
> 
> // Examples
> 
> let regex = \[a-zA-Z]+\
> let matches = regex.match("Matching words in text.")
> 
> for match in matches {
> print("Found a match at in string at \(match.start) to \(match.end)")
> }
> 
> let helloStr = "Hello world"
> 
> Regex.word.match(helloStr) { match in
> print("Matched \(helloStr[match.start.. }
>  
> Of course this is a scratch implementation I made but it is to open 
> discussion on the topic. I feel the Regex struct itself will need more 
> methods and variables such as for flags and number of groups. Please provide 
> feedback with improvements to the code, concerns on the topic, or just open 
> up discussion. Thank you!
> 
> Joshua Alvarado
> alvaradojosh...@gmail.com 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Ben Cohen via swift-evolution

Hi Joshua,

Thanks for bringing this topic up. It may help to outline why regular 
expressions were deferred until Swift 5. The work to create a regular 
expression type itself, and even to add a regex literal protocol, is fairly 
straightforward and probably could have been done in the Swift 4 timeframe 
(maybe by making NSRegularExpression a value type and refreshing its API), but 
there are other design aspects that we need to explore prior to that, many of 
which have compiler impact, or would need to factor in the underlying 
representation of string in order to be efficient, in order to make 
Swift-native regular expressions really great.

Right now, the top priority for Swift 5 is ABI stability, and String plays a 
fairly large part in that. We need to finalize the size of String (currently 3 
words, but 2 is the likely final size), implement the small string 
optimization, and decide which parts of String need to be fragile/inlineable 
and which need to be resilient.

Since ABI stability takes priority, this give us time in the mean-time to 
consider the broader design questions of what Swift-native regular expressions 
would look like. These design considerations probably need to come ahead of 
designing an API for specific types like a regex, matches etc.

Some examples of these kind of questions include:

What syntax changes to the usual form of regexes should be considered? For 
example, what should “.” mean in regular expressions? It would be out of 
keeping for it to mean a code unit, when applied to Swift.String. 
Alternatively, should regular expressions work on all the views? In which case, 
“.” could mean a grapheme when applied to String, but a code unit when applied 
to the UTF16 view.

How can let bindings work on capture groups i.e. rather than having named 
capture groups like in Perl, can we bind directly to variables in switches etc? 
Could types conform to a RegularExpressionCapturable that would consume part of 
the string and initialize self, so that you could capture not just Substring 
but any type? You can’t express this in the language today, and would need 
compiler integration. This integration could start more hard-coded in order to 
deliver value in the Swift 5 release, but hopefully be generalizable in later 
releases.

What other std lib APIs should be changed once we have regular expressions? For 
example, split ought to work with regexes e.g. let words = 
sentence.split(separator: /\w+/). How can this generalize to Collections where 
possible? E.g. [1,2,3,4].index(of: [2,3]) ought to work just as 
“abcd”.index(of: /bc/) should.

> On Aug 10, 2017, at 7:24 AM, Joshua Alvarado via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I would like to pitch an implementation of Regex in Swift and gather all of 
> your thoughts.
> 
> Motivation:
> In the String Manifesto for Swift 4, addressing regular expressions was not 
> in scope. Swift 5 would be a more fitting version to address the 
> implementation of Regex in Swift. NSRegularExpression is a suitable solution 
> for pattern matching but the API is in unfitting for the future direction of 
> Swift.
> 
> Implementation:
> The Regular expression API will be implemented by a Regex structure object 
> which is a regular expression that you can apply to Unicode strings. The 
> Regex struct will conform to the RegexProtocol, which is a type that can 
> represent a regular expression. ExpressibleByRegexLiteral will be used to 
> initialize a regex literal creating an easy to use syntax and a Match 
> structure will be used to represent a match found with a Regex.
> 
> Draft of implementation:
> 
> protocol ExpressibleByRegexLiteral {
> associatedtype RegexLiteralType
> 
> init(regexLiteral value: Self.RegexLiteralType)
> }
> 
> // Structure of information about a match of regex on a string
> struct Match {
> var regex: Regex
> var start: String.Index
> var end: String.Index
> }
> 
> protocol RegexProtocol {
> init(pattern: String) throws
> 
> var pattern: String { get } // string representation of the pattern
> func search(string: String) -> Bool // used to check if a match is found 
> at all in the string
> func match(string: String) -> [Match] // returns an array of all the 
> matches
> func match(string: String, using: ((Match) -> Void)) // enmuerate over 
> matches
> }
> 
> struct Regex: RegexProtocol {
> init(pattern: Regex, options: Regex.Options)
> let options: [Regex.Options]
> static let word: Regex // \w
> // other useful regexes can be added as well
> }
> 
> // Examples
> 
> let regex = \[a-zA-Z]+\
> let matches = regex.match("Matching words in text.")
> 
> for match in matches {
> print("Found a match at in string at \(match.start) to \(match.end)")
> }
> 
> let helloStr = "Hello world"
> 
> Regex.word.match(helloStr) { match in
> print("Matched \(helloStr[match.start.. }
>  
> Of course this is a scratch 

Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Martin Waitz via swift-evolution

Hi Haravikk,

Am 2017-08-10 11:07, schrieb Haravikk via swift-evolution:

I don't feel that conforming to
Equatable/Hashable is sufficient as an opt-in. Consider for example
someone who declares their type as Equatable/Hashable, then sets to
work on the details of their type, forgetting to implement the actual
equatable/hashable behaviour they want.


This is no different than a default implementation of the protocol.
In fact, the proposal just adds something like this:

extension Struct: Equatable where A: Equatable, B: 
Equatable, ... {
static func ==(lhs: Self, rhs: Self) -> Bool { /* insert 
implementation here */ }

}

We don't require/support some special keywords for other protocols with 
default implementation either,

so I see no reason to add them here.

Your concerns are orthogonal to this proposal and should be discussed 
independently.


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


Re: [swift-evolution] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Haravikk via swift-evolution

> On 10 Aug 2017, at 00:08, Chris Lattner via swift-evolution 
>  wrote:
> 
>   • What is your evaluation of the proposal?

Generally positive, but I don't feel that conforming to Equatable/Hashable is 
sufficient as an opt-in. Consider for example someone who declares their type 
as Equatable/Hashable, then sets to work on the details of their type, 
forgetting to implement the actual equatable/hashable behaviour they want.

I would suggest either that there be a keyword/attribute to indicate when the 
synthesised solution be used, or that there be alternate protocols such as 
AutoEquatable and AutoHashable; the idea being that the more explicit 
declaration results in the synthesised behaviour, or produces errors if it 
isn't possible or if a custom implementation is provided. An advantage of these 
methods is that the synthesis could potentially then be allowed for extensions 
(unless there's some other reason they aren't?), since they're absolutely 
explicit in what they want.

I'm just wary of these being implemented automatically cases where someone 
forgets to do it themselves, or if they accidentally define the requirements 
incorrectly (e.g- they provide a hash_value property instead of hashValue). I 
think for this to count as opt-in behaviour the developer should be 
specifically opting in to synthesised implementations, rather than just 
declaring conformance as normal and having it kick-in in certain circumstances.

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

While it's a somewhat minor problem, it does commonly involve a lot of 
boiler-plate where it can also be easy to introduce mistakes. So I do feel a 
change is warranted.

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

Other than the means of opting in I'd say so, yes.

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

Quick re-read of the proposal, otherwise been following discussion for a while.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enums and Source Compatibility

2017-08-10 Thread Brent Royal-Gordon via swift-evolution
> On Aug 8, 2017, at 3:28 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> Let's now flip this to the other side of the equation. I've been talking 
> about us disallowing exhaustive switching, i.e. "if the enum might grow new 
> cases you must have a 'default' in a switch". In previous (in-person) 
> discussions about this feature, it's been pointed out that the code in an 
> otherwise-fully-covered switch is, by definition, unreachable, and therefore 
> untestable. This also isn't a desirable situation to be in, but it's 
> mitigated somewhat by the fact that there probably aren't many framework 
> enums you should exhaustively switch over anyway. (Think about Apple's 
> frameworks again.) I don't have a great answer, though.
> 
> For people who like exhaustive switches, we thought about adding a new kind 
> of 'default'—let's call it 'unknownCase' just to be able to talk about it. 
> This lets you get warnings when you update to a new SDK, but is even more 
> likely to be untested code. We didn't think this was worth the complexity.

A question: Does it make sense to switch on a non-exhuastive enum at all? 
Maybe, from the public vantage point, a closed enum should be indistinguishable 
from a struct with static properties/methods—if you can switch over one, it's 
only through its conformance to `Equatable` or its implementation of a public 
`~=` operator.

(IIRC, we ended up somewhere quite similar to this with our "import Objective-C 
string constants as enums" feature—it actually ends up creating structs 
instead.)

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Charlie Monroe via swift-evolution
Hi Joshua,

while this is a great idea, I'm afraid that this needs to be more 
thought-through. For example, which regex standards would you like to include? 
I really hope that Swift's regex support will not get stuck with plain ICU 
regexes like NSRegularExpression. I personally would love to see Perl-syntax 
improvements such as named groups (any many others):

let regexString = "NS_ENUM\((?P\w+), (?P\w+)\)"

let mySource = "NS_ENUM(NSInteger, NSComparisonResult)"
mySource.match("TYPE", in: regexString) // NSInteger

Of course, it would be great if the compiler support could be extended so that 
the TYPE and NAME variables can be extracted without using string literals, 
e.g. Regex(regexString).firstMatch(in: mySource)?.TYPE

I have written myself an ObjC wrapper arround C++ implementation of such regex 
(re2) and use that from Swift instead of using NSRegularExpression.

Regarding your snippet:

- it's always good to keep in mind that in many usecases you only need the 
first match, not all of them
- instead of search(_:), consider matches(_:)
- huge part of regex power is in replacing occurrences, which is missing



> On Aug 10, 2017, at 8:25 AM, Joshua Alvarado via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I would like to pitch an implementation of Regex in Swift and gather all of 
> your thoughts.
> 
> Motivation:
> In the String Manifesto for Swift 4, addressing regular expressions was not 
> in scope. Swift 5 would be a more fitting version to address the 
> implementation of Regex in Swift. NSRegularExpression is a suitable solution 
> for pattern matching but the API is in unfitting for the future direction of 
> Swift.
> 
> Implementation:
> The Regular expression API will be implemented by a Regex structure object 
> which is a regular expression that you can apply to Unicode strings. The 
> Regex struct will conform to the RegexProtocol, which is a type that can 
> represent a regular expression. ExpressibleByRegexLiteral will be used to 
> initialize a regex literal creating an easy to use syntax and a Match 
> structure will be used to represent a match found with a Regex.
> 
> Draft of implementation:
> 
> protocol ExpressibleByRegexLiteral {
> associatedtype RegexLiteralType
> 
> init(regexLiteral value: Self.RegexLiteralType)
> }
> 
> // Structure of information about a match of regex on a string
> struct Match {
> var regex: Regex
> var start: String.Index
> var end: String.Index
> }
> 
> protocol RegexProtocol {
> init(pattern: String) throws
> 
> var pattern: String { get } // string representation of the pattern
> func search(string: String) -> Bool // used to check if a match is found 
> at all in the string
> func match(string: String) -> [Match] // returns an array of all the 
> matches
> func match(string: String, using: ((Match) -> Void)) // enmuerate over 
> matches
> }
> 
> struct Regex: RegexProtocol {
> init(pattern: Regex, options: Regex.Options)
> let options: [Regex.Options]
> static let word: Regex // \w
> // other useful regexes can be added as well
> }
> 
> // Examples
> 
> let regex = \[a-zA-Z]+\
> let matches = regex.match("Matching words in text.")
> 
> for match in matches {
> print("Found a match at in string at \(match.start) to \(match.end)")
> }
> 
> let helloStr = "Hello world"
> 
> Regex.word.match(helloStr) { match in
> print("Matched \(helloStr[match.start.. }
>  
> Of course this is a scratch implementation I made but it is to open 
> discussion on the topic. I feel the Regex struct itself will need more 
> methods and variables such as for flags and number of groups. Please provide 
> feedback with improvements to the code, concerns on the topic, or just open 
> up discussion. Thank you!
> 
> Joshua Alvarado
> alvaradojosh...@gmail.com 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


[swift-evolution] Draft: Regular Expression in Swift

2017-08-10 Thread Joshua Alvarado via swift-evolution
Hey everyone,

I would like to pitch an implementation of Regex in Swift and gather all of 
your thoughts.

Motivation:
In the String Manifesto for Swift 4, addressing regular expressions was not in 
scope. Swift 5 would be a more fitting version to address the implementation of 
Regex in Swift. NSRegularExpression is a suitable solution for pattern matching 
but the API is in unfitting for the future direction of Swift.

Implementation:
The Regular expression API will be implemented by a Regex structure object 
which is a regular expression that you can apply to Unicode strings. The Regex 
struct will conform to the RegexProtocol, which is a type that can represent a 
regular expression. ExpressibleByRegexLiteral will be used to initialize a 
regex literal creating an easy to use syntax and a Match structure will be used 
to represent a match found with a Regex.

Draft of implementation:

protocol ExpressibleByRegexLiteral {
associatedtype RegexLiteralType

init(regexLiteral value: Self.RegexLiteralType)
}

// Structure of information about a match of regex on a string
struct Match {
var regex: Regex
var start: String.Index
var end: String.Index
}

protocol RegexProtocol {
init(pattern: String) throws

var pattern: String { get } // string representation of the pattern
func search(string: String) -> Bool // used to check if a match is found at 
all in the string
func match(string: String) -> [Match] // returns an array of all the matches
func match(string: String, using: ((Match) -> Void)) // enmuerate over 
matches
}

struct Regex: RegexProtocol {
init(pattern: Regex, options: Regex.Options)
let options: [Regex.Options]
static let word: Regex // \w
// other useful regexes can be added as well
}

// Examples

let regex = \[a-zA-Z]+\
let matches = regex.match("Matching words in text.")

for match in matches {
print("Found a match at in string at \(match.start) to \(match.end)")
}

let helloStr = "Hello world"

Regex.word.match(helloStr) { match in
print("Matched \(helloStr[match.start..