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

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 25, 2017 at 12:08 AM, Chris Lattner  wrote:

>
>
> On Nov 24, 2017, at 7:52 PM, Xiaodi Wu  wrote:
>
> etc.  Even if we don’t have a “default regex” for types, it would still be
>> awesome to be able to write:
>>
>>
>> if case /(let name: [a-zA-Z]+) (let count: Int: [0-9]+)/ =
>> getSomeString() {
>>print(name, count)
>> }
>>
>> and have that transparently invoke and check the Int?(string) failable
>> initializer.
>>
>
> Yes, these are very interesting options to explore, and you're right that
> if we want to go down this road, then we'd need to imbue regex literals
> with certain "smarts" as opposed to having lenient regex literal parsing
> that entirely defers validation to a concrete regex type conforming to
> ExpressibleByRegularExpressionLiteral.
>
> I don't think it's an all-or-nothing proposition, though, as to whether
> the literal or the conforming type performs the validation. Personally, I
> think one of the strengths of Swift's literals is that they are
> intrinsically untyped and that multiple concrete types are expressible by
> them.
>
>
> Right, but the string literal syntaxes we have (single and multiline) do
> not allow different grammars (e.g. escape sequences) depending on what type
> they are inferred to.  Wouldn’t it be odd if a string literal accepted
> “\x12\u1212\U1212” when it converts to a "const char *” but accepted
> “\u{12345}” when passed to a bridged Dart API?
>

...And here we come full circle. The original proposal is precisely to have
a different type of string literal that accepts/rejects different escape
sequences. In my initial reply, I wrote that (should raw strings be
sufficiently motivated that some sort of solution is clearly desirable) one
avenue to explore is redesigning literals to allow conforming types to
access the "raw" literal, free of all but the most minimal processing, so
that the type can choose the grammar rather than the literal. In so doing,
we avoid having to hardcode new "flavors" of string literal.

It is precisely in observing these repeated requests for now flavors of
string literals, as well as existing shortcomings of integer and float
literals for supporting BigInt and Decimal types, that leads me to think
that we should exactly allow what you describe as "odd."
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-11-24 Thread Chris Lattner via swift-evolution


> On Nov 24, 2017, at 7:52 PM, Xiaodi Wu  wrote:
> 
> etc.  Even if we don’t have a “default regex” for types, it would still be 
> awesome to be able to write:
> 
> 
> if case /(let name: [a-zA-Z]+) (let count: Int: [0-9]+)/ = getSomeString() {
>print(name, count)
> }
> 
> and have that transparently invoke and check the Int?(string) failable 
> initializer.
> 
> Yes, these are very interesting options to explore, and you're right that if 
> we want to go down this road, then we'd need to imbue regex literals with 
> certain "smarts" as opposed to having lenient regex literal parsing that 
> entirely defers validation to a concrete regex type conforming to 
> ExpressibleByRegularExpressionLiteral.
> 
> I don't think it's an all-or-nothing proposition, though, as to whether the 
> literal or the conforming type performs the validation. Personally, I think 
> one of the strengths of Swift's literals is that they are intrinsically 
> untyped and that multiple concrete types are expressible by them.

Right, but the string literal syntaxes we have (single and multiline) do not 
allow different grammars (e.g. escape sequences) depending on what type they 
are inferred to.  Wouldn’t it be odd if a string literal accepted 
“\x12\u1212\U1212” when it converts to a "const char *” but accepted 
“\u{12345}” when passed to a bridged Dart API?

-Chris

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


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

2017-11-24 Thread Chris Lattner via swift-evolution
On Nov 24, 2017, at 9:20 PM, Douglas Gregor  wrote:
>> Ok, so you just happened to pick a simple one:
> 
> Yup. Try to make a nominal type to describe labeled tuples.

People keep talking about adding integer values to generics, why not strings 
too? ;-)

>> what is the benefit of plumbing knowledge of metatypes through the entire 
>> generics system,
> 
> That’s not how one would implement this in the compiler. Most of the compiler 
> doesn’t care whether the subject of a protocol conformance is a nominal type 
> or not, and those scattered (but numerous) places that do care should be 
> straightforward to generalize to include structural types. It’s not 
> metatype-specific work.

Sure, I can buy that.  The thing that you’re leaving out is that you have to 
also generalize those (numerous) places to handle all the complexities of those 
non-nominal types.  The system has to handle keywords, inout arguments, etc 
somehow, and therefore the complexity to handle them needs to go somewhere.

The question is only whether one design or the other produces a lower energy 
state of complexity.  Given that I don’t know this code at all, if you think 
that your way is the best way to model it, then I’ll happily believe you. :-)

-Chris

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


Re: [swift-evolution] [Proposal] Random Unification

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Fri, Nov 24, 2017 at 10:59 PM, TellowKrinkle 
wrote:

> So why is it more important for the random method on a collection to have
> a special method that guarantees a discrete uniform distribution than it is
> for an Int?  If you’re going to split on guaranteed-discrete-uniform vs
> maybe-discrete-uniform, why not split on discrete-uniform vs
> not-discrete-uniform (note: I would not want either of these)?
>
> Why not just let everything be maybe-discrete-uniform and then specify:
> - Things involving discrete sets (including collections and ranges of
> discrete values like ints) return a discrete uniform distribution
> - Things involving continuous ranges (including ranges of floating-point
> types) return a continuous uniform distribution
> I don’t really see the point in differentiating between a discrete and
> continuous distribution, since it makes no sense to use a continuous
> distribution for things that are discrete, and it also makes no sense to
> use a discrete distribution for things that are continuous.
>

One of the arguments that others have raised against the proposed
`Randomizable` protocol and the static method `random` is precisely this:
that static `random` guarantees no semantics about the nature of the random
value, including the distribution from which it is drawn. I agree with this
criticism; so you are correct: I do not want a "maybe-discrete-uniform"
method at all, let alone one that shares its name with methods that do
guarantee a particular distribution.

As for optional vs non-optional, I’d say this is similar to conforming to
> RawRepresentable (where you can implement its `init?(rawValue:)` with an
> `init(rawValue:)` if your type doesn’t ever fail to initialize) where
> you’re simply indicating that for whatever reason, your type is less likely
> to fail than whatever the most likely to fail type is.
>
> Personally, I don’t care whether or not `Int.random` stays, but it’s
> functionally identical to `Int.random(in:)` with a default argument so it
> doesn’t make much of a difference for this decision since removing it
> wouldn’t affect the issue you’re having between `Int.random(in:)` and
> `Collection.random`.
>

There is certainly a difference. `Int.random(in:)` is failable, like
`Collection.random` is failable, because it is selecting one of a set of
values and that set may be empty. `Int.random` is not failable. Moreover,
as I wrote earlier, I'm concerned about this multiplication of methods that
do in fact do the same thing. It is unclear to me in what way
`Int.random(in: [1, 2, 3])` differs from `[1, 2, 3].random`. If there is no
semantic distinction, there should only be one facility. If there is a
semantic distinction, then there should be two facilities with distinct
names. In either case, there should not be two facilities with the same
name.

2017/11/24 21:39、Xiaodi Wu のメール:
>
> On Fri, Nov 24, 2017 at 9:05 PM, TellowKrinkle 
> wrote:
>
>> You say that all the `.random`s have different semantics, but to me (at
>> least), they are all very similar.
>>
>
> Of course they are _similar_: this is precisely why it's so important to
> be clear about the differences in the naming.
>
>
>> All the methods can be summarized as selecting a single random element
>> from a collection
>> `[0, 2, 3].random` selects a single element from the given collection
>> `Int.random(in: 0…8)` selects a single element from the given range
>> `Int.random` has no range, but selects a single element from the
>> collection of all ints (equivalent to if the above method had a default
>> value for its range)
>> So to me these are all doing the same operation, just with different
>> types of inputs
>>
>
> There are many subtle but important differences. For example:
>
> `[1, 2, 3].random` is a sampling operation based on a discrete uniform
> distribution. All operations that choose an element from a Collection would
> behave similarly: that is, instance `random` guarantees sampling based on a
> discrete uniform distribution. It does so happen that `Int.random` gives
> values in a discrete uniform distribution. However, `Float.random` most
> certainly does not: it would sample from a _continuous_ uniform
> distribution. In general, static `random` does not guarantee any particular
> distribution at all. This is a huge semantic distinction.
>
> Static `random` (e.g., `Int.random`) will always return a value, whereas
> instance `random` (e.g., `[1, 2, 3].random`) might not. This is because all
> types that implement static `random` must be instantiable, whereas
> collections can be empty. One might conclude that it makes sense for static
> `random` to be of type `T`, whereas instance `random` would be most
> fittingly of type `T?`. However, because they're both named "random",
> people have been misled into thinking that they're in fact the same
> operation and must therefore have the same return type. Alejandro has
> argued 

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

2017-11-24 Thread Douglas Gregor via swift-evolution


Sent from my iPhone

> On Nov 24, 2017, at 4:06 PM, Chris Lattner  wrote:
> 
>> On Nov 24, 2017, at 3:47 PM, Douglas Gregor via swift-evolution 
>>  wrote:
>> One could imagine adding a “curry” operation to function types:
> 
> Right, having non-nominal types participate in the generics system would be 
> undoubtably awesome! :)
> 
>> Or perhaps making metatypes Hashable so they can be used as keys into a 
>> Dictionary:
>> 
>>  extension T.Type: Hashable {
> 
> Ok, so you just happened to pick a simple one:

Yup. Try to make a nominal type to describe labeled tuples. 

> what is the benefit of plumbing knowledge of metatypes through the entire 
> generics system,

That’s not how one would implement this in the compiler. Most of the compiler 
doesn’t care whether the subject of a protocol conformance is a nominal type or 
not, and those scattered (but numerous) places that do care should be 
straightforward to generalize to include structural types. It’s not 
metatype-specific work.

> rather than define a “Swift.Metatype” type, and defining stuff against it?

It would be a nominal type in name only (pun intended!), with special cases 
throughout the compiler and ABI—like we have with Optional, except with poorer 
test coverage. Worse, unlike the generalization I discuss above, where one 
generalization refactoring makes all structural types work, we’d have to  put 
in all of the not-really-nominal hacks for each currently-structural type on a 
case-by-case basis. 

  - Doug

> 
> -Chris
> 
> 
> 
>>var hashValue: Int {
>>  return ObjectIdentifier(self).hashValue
>>}
>> 
>>   static func ==(lhs: T.Type, rhs: T.Type) -> Bool { /* standard library 
>> magic */ }
>>  }
>> 
>>- Doug
>> 
>> 
>> ___
>> 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] Fwd: [Pre-pitch] Conditional default arguments

2017-11-24 Thread Dave Abrahams via swift-evolution


Sent from my iPhone

Begin forwarded message:

> From: Matthew Johnson 
> Date: November 24, 2017 at 3:55:34 PM PST
> To: Dave Abrahams 
> Subject: Re: [swift-evolution] [Pre-pitch] Conditional default arguments
> 
> You posted off-list.  If that wasn’t intentional feel free to forward my 
> reply to the list.
> 
> Sent from my iPad
> 
>> On Nov 24, 2017, at 5:32 PM, Dave Abrahams  wrote:
>> 
>> 
>>> On Nov 24, 2017, at 3:11 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> Adding language support for defining these more directly would eliminate a 
>>> lot of boilerplate
>> 
>> I think I understand what you’re trying to do, but it’s not obvious to me 
>> that this  pattern is common enough to warrant investing language design 
>> resources or the increased language complexity of a dedicated feature.
> 
> It’s not obvious to me either.  It’s not something I come across frequently, 
> but the overloads get painful pretty quickly in the cases where I do.
> 
> When I initially added it to the manifesto I put it in the “maybe”section and 
> called it a “pre-pitch” for this reason.  I posted on list because Doug had a 
> positive response to the idea.  It may well be a case where solving it 
> directly at the language level isn’t appropriate.  
> 
> I don’t plan to push hard for it if the response is lukewarm.  I’m primarily 
> interested in finding out what the response is at this point.  :)
> 
>> When you say “a lot of boilerplate,” how much do you mean?  
> 
> It’s a combinatoric explosion of overloads so it depends on the number of 
> conditionally defaulted arguments.
> 
> The example I gave above is a simplification based on some code I have 
> written.  This code already requires an overload set for other reasons.  Each 
> of the base overloads requires a set providing emulated default arguments.  
> The total size of the set is uncomfortable.  
> 
>> Is this a pattern you’ve observed outside your own code?
> 
> No, but I haven’t been actively looking for it.  Part of the reason for 
> posting to the list is to seek feedback and see if others have had similar 
> cases arise.  
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Fri, Nov 24, 2017 at 6:25 PM, Chris Lattner  wrote:

>
>
> On Nov 24, 2017, at 4:15 PM, Chris Lattner  wrote:
>
>
> than the same type having a collection of named matches using the usual
> Perl syntax?
>
>   if case /(?[a-zA-Z]+) (?[a-zA-Z]+)/ =
> getSomeString() {
> print(Regex.captured["firstName"], Regex.captured["lastName"])
>   }
>
>
> Personally, I really don’t like this.  It turns a structured problem into
> one that violates DRY and loses the structure inherent in the solution.
> Also, while theoretically the dictionary could be optimized away, in
> practice that would be difficult to do without heroics.
>
>
> One other minor and obscure point: if the compiler is aware of the regex
> grammar it can properly type the matches, I can imagine the following cases:
>
> if case /(let name: [a-zA-Z]+) (let count: Int)/ = getSomeString() {
>print(name, count)
> }
>
>
> -> name has type String, count has type Int (and matches [0-9]+)
>
>
> if case /(let name: [a-zA-Z]+)? (let count: Int)/ = getSomeString() {
>print(name, count)
> }
>
> -> name has type String?
>
> if case /(let name: [a-zA-Z]+)* (let count: Int)/ = getSomeString() {
>print(name, count)
> }
>
> -> name has type [String]
>
> etc.  Even if we don’t have a “default regex” for types, it would still be
> awesome to be able to write:
>
>
> if case /(let name: [a-zA-Z]+) (let count: Int: [0-9]+)/ = getSomeString()
> {
>print(name, count)
> }
>
> and have that transparently invoke and check the Int?(string) failable
> initializer.
>

Yes, these are very interesting options to explore, and you're right that
if we want to go down this road, then we'd need to imbue regex literals
with certain "smarts" as opposed to having lenient regex literal parsing
that entirely defers validation to a concrete regex type conforming to
ExpressibleByRegularExpressionLiteral.

I don't think it's an all-or-nothing proposition, though, as to whether the
literal or the conforming type performs the validation. Personally, I think
one of the strengths of Swift's literals is that they are intrinsically
untyped and that multiple concrete types are expressible by them. Whether
or not we think one or another regex syntax is best doesn't necessarily
mean we need to preclude other regex engines from interacting with a regex
literal. Rather, just like string interpolation literals allow the compiler
to parse some "stuff" inside the quotation marks, we can have some syntax
that allows for regex patterns to have segments parsed by the compiler for
binding without locking down regex syntax entirely. For instance, just as
the compiler parses `\(...)` inside string literals, suppose it parses
`(let...)` and `(var...)` inside regex literals.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Random Unification

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Fri, Nov 24, 2017 at 9:05 PM, TellowKrinkle 
wrote:

> You say that all the `.random`s have different semantics, but to me (at
> least), they are all very similar.
>

Of course they are _similar_: this is precisely why it's so important to be
clear about the differences in the naming.


> All the methods can be summarized as selecting a single random element
> from a collection
> `[0, 2, 3].random` selects a single element from the given collection
> `Int.random(in: 0…8)` selects a single element from the given range
> `Int.random` has no range, but selects a single element from the
> collection of all ints (equivalent to if the above method had a default
> value for its range)
> So to me these are all doing the same operation, just with different types
> of inputs
>

There are many subtle but important differences. For example:

`[1, 2, 3].random` is a sampling operation based on a discrete uniform
distribution. All operations that choose an element from a Collection would
behave similarly: that is, instance `random` guarantees sampling based on a
discrete uniform distribution. It does so happen that `Int.random` gives
values in a discrete uniform distribution. However, `Float.random` most
certainly does not: it would sample from a _continuous_ uniform
distribution. In general, static `random` does not guarantee any particular
distribution at all. This is a huge semantic distinction.

Static `random` (e.g., `Int.random`) will always return a value, whereas
instance `random` (e.g., `[1, 2, 3].random`) might not. This is because all
types that implement static `random` must be instantiable, whereas
collections can be empty. One might conclude that it makes sense for static
`random` to be of type `T`, whereas instance `random` would be most
fittingly of type `T?`. However, because they're both named "random",
people have been misled into thinking that they're in fact the same
operation and must therefore have the same return type. Alejandro has
argued that `[1, 2, 3].random` should be of type `T` *because* it would not
be ergonomic for `Int.random` to be of type `T?`. Meanwhile, others have
argued that, because `[].random` should be failable, `Int.random` should be
as well. This perceived need for the two distinct facilities to return the
same type is completely due to them having the same proposed name. However,
as described above, one is failable and the other is not *because of their
differing semantics*.

Meanwhile, we have had a debate as to whether `random` should be spelled as
a property or a function. Alejandro has argued that `random` is like
`first` or `last` and is a property of a collection, while others have
argued that `Int.random()` should be spelled like a function because it
instantiates a different value each time. Notionally, of course, instance
`random` selects one already-existing element from a collection, whereas
static `random` creates a new value that doesn't exist yet and truly could
be considered like a factory method. However, because again they've both
been proposed to have the name "random", people are using arguments about
one type of "random" to decide questions of syntax for the other type of
"random".

All of this goes away when we clarify that these two are distinct
facilities: they have different semantics. Of course, elsewhere, I've
advocated for `Int.random` to be removed altogether due to large potential
for incorrect use. If so, then that's one fewer "random" to be confused
with one another.


> 2017/11/24 20:07、Alejandro Alonso のメール:
>
>
> - Alejandro
>
> -- Forwarded message --
> *From:* Xiaodi Wu 
> *Date:* Nov 24, 2017, 3:05 PM -0600
> *To:* Alejandro Alonso 
> *Cc:* Brent Royal-Gordon , Steve Canon via
> swift-evolution 
> *Subject:* Re: [swift-evolution] [Proposal] Random Unification
>
> On Fri, Nov 24, 2017 at 2:55 PM, Alejandro Alonso 
> wrote:
>
>> Regarding naming too many things “random”, I’ve talked to many developers
>> on my end and they all don’t find it confusing. This proposal is aimed to
>> make it obvious what the operation is doing when regarding random. I still
>> agree that the proposed solution does just that and in practice feels good
>> to write.
>>
>
> I must disagree quite strongly here. The various facilities you name
> "random" have different semantics, and differences in semantics should be
> reflected in differences in names. It doesn't matter that some people don't
> find it confusing; it is objectively the case that you have named multiple
> distinct facilities with the same name, which leads to confusion. I, for
> one, get confused, and you can see on this list that people are using
> arguments about one property named "random" to discuss another property
> named "random". This is quite an intolerable situation.
>
> I disagree that sample is the 

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

2017-11-24 Thread Xiaodi Wu via swift-evolution
It's kludgy, but we could have something like:

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

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


On Fri, Nov 24, 2017 at 8:36 PM, T.J. Usiyan via swift-evolution <
swift-evolution@swift.org> wrote:

> I am all for this. are many types where there is an obvious 'zero' or
> 'default' value and the ability to express "use that when possible" without
> an overload is welcome.
>
>
> The best thing that I can think of right now, in terms of syntax, is
> actually using @overload
>
> ```
> struct ResourceDescription {
>
>   func makeResource(with configuration: R.Configuration, actionHandler:
> @escaping (R.Action) -> Void) -> R
>  @overload(R.Configuration == Void) func makeResource(actionHandler:
> @escaping (R.Action) -> Void) -> R
> @overload(R.Action == Never)  func makeResource(with configuration:
> R.Configuration) -> R
> {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
> ```
>
>
> This isn't great though…
>
> On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> As mentioned in my prior message, I currently have a PR open to update
>> the generics manifesto (https://github.com/apple/swift/pull/13012).  I
>> removed one topic from that update at Doug Gregor’s request that it be
>> discussed on the list first.
>>
>> The idea is to add the ability to make default arguments conditional
>> (i.e. depend on generic constraints).  It is currently possible to emulate
>> conditional default arguments using an overload set.  This is verbose,
>> especially when several arguments are involved.  Here is an example use
>> case using the overload method to emulate this feature:
>>
>> ```swift
>> protocol Resource {
>>   associatedtype Configuration
>>   associatedtype Action
>> }
>> struct ResourceDescription {
>>   func makeResource(with configuration: R.Configuration, actionHandler:
>> @escaping (R.Action) -> Void) -> R {
>> // create a resource using the provided configuration
>> // connect the action handler
>> // return the resource
>>   }
>> }
>>
>> extension ResourceDescription where R.Configuration == Void {
>>   func makeResource(actionHandler: @escaping (R.Action) -> Void) -> R {
>> return makeResource(with: (), actionHandler: actionHandler)
>>   }
>> }
>>
>> extension ResourceDescription where R.Action == Never {
>>   func makeResource(with configuration: R.Configuration) -> R {
>> return makeResource(with: configuration, actionHandler: { _ in })
>>   }
>> }
>>
>> extension ResourceDescription where R.Configuration == Void, R.Action ==
>> Never {
>>   func makeResource() -> R {
>> return makeResource(with: (), actionHandler: { _ in })
>>   }
>> }
>>
>> ```
>>
>> Adding language support for defining these more directly would eliminate
>> a lot of boilerplate and reduce the need for overloads.  Doug mentioned
>> that it may also help simplify associated type inference (
>> https://github.com/apple/swift/pull/13012#discussion_r152124535).
>>
>> The reason that I call this a pre-pitch and one reason Doug requested it
>> be discussed on list is that I haven’t thought of a good way to express
>> this syntactically.  I am interested in hearing general feedback on the
>> idea.  I am also looking for syntax suggestions.
>>
>> Matthew
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Fri, Nov 24, 2017 at 9:08 PM, Mike Kluev via swift-evolution <
swift-evolution@swift.org> wrote:

> On 24 November 2017 at 23:47, Douglas Gregor  wrote:
>
>>
>> e.g., making all tuples of Equatable elements Equatable
>>
>>
> that's already the case.. (all tuples of equatable elements are
> equatable). no?
>

No, tuples do not conform to any protocols. There are hardcoded
implementations of `==` up to some arity in the stdlib to partially
mitigate the lack of protocol conformance.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-11-24 Thread Mike Kluev via swift-evolution
On 24 November 2017 at 23:47, Douglas Gregor  wrote:

>
> e.g., making all tuples of Equatable elements Equatable
>
>
that's already the case.. (all tuples of equatable elements are equatable).
no?

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


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

2017-11-24 Thread T.J. Usiyan via swift-evolution
I am all for this. are many types where there is an obvious 'zero' or
'default' value and the ability to express "use that when possible" without
an overload is welcome.


The best thing that I can think of right now, in terms of syntax, is
actually using @overload

```
struct ResourceDescription {

  func makeResource(with configuration: R.Configuration, actionHandler:
@escaping (R.Action) -> Void) -> R
 @overload(R.Configuration == Void) func makeResource(actionHandler:
@escaping (R.Action) -> Void) -> R
@overload(R.Action == Never)  func makeResource(with configuration:
R.Configuration) -> R
{
// create a resource using the provided configuration
// connect the action handler
// return the resource
  }
}
```


This isn't great though…

On Fri, Nov 24, 2017 at 6:11 PM, Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> As mentioned in my prior message, I currently have a PR open to update the
> generics manifesto (https://github.com/apple/swift/pull/13012).  I
> removed one topic from that update at Doug Gregor’s request that it be
> discussed on the list first.
>
> The idea is to add the ability to make default arguments conditional (i.e.
> depend on generic constraints).  It is currently possible to emulate
> conditional default arguments using an overload set.  This is verbose,
> especially when several arguments are involved.  Here is an example use
> case using the overload method to emulate this feature:
>
> ```swift
> protocol Resource {
>   associatedtype Configuration
>   associatedtype Action
> }
> struct ResourceDescription {
>   func makeResource(with configuration: R.Configuration, actionHandler:
> @escaping (R.Action) -> Void) -> R {
> // create a resource using the provided configuration
> // connect the action handler
> // return the resource
>   }
> }
>
> extension ResourceDescription where R.Configuration == Void {
>   func makeResource(actionHandler: @escaping (R.Action) -> Void) -> R {
> return makeResource(with: (), actionHandler: actionHandler)
>   }
> }
>
> extension ResourceDescription where R.Action == Never {
>   func makeResource(with configuration: R.Configuration) -> R {
> return makeResource(with: configuration, actionHandler: { _ in })
>   }
> }
>
> extension ResourceDescription where R.Configuration == Void, R.Action ==
> Never {
>   func makeResource() -> R {
> return makeResource(with: (), actionHandler: { _ in })
>   }
> }
>
> ```
>
> Adding language support for defining these more directly would eliminate a
> lot of boilerplate and reduce the need for overloads.  Doug mentioned that
> it may also help simplify associated type inference (
> https://github.com/apple/swift/pull/13012#discussion_r152124535).
>
> The reason that I call this a pre-pitch and one reason Doug requested it
> be discussed on list is that I haven’t thought of a good way to express
> this syntactically.  I am interested in hearing general feedback on the
> idea.  I am also looking for syntax suggestions.
>
> Matthew
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-11-24 Thread Chris Lattner via swift-evolution


> On Nov 24, 2017, at 4:15 PM, Chris Lattner  wrote:
> 
>> 
>> than the same type having a collection of named matches using the usual Perl 
>> syntax?
>> 
>>   if case /(?[a-zA-Z]+) (?[a-zA-Z]+)/ = getSomeString() 
>> {
>> print(Regex.captured["firstName"], Regex.captured["lastName"])
>>   }
> 
> Personally, I really don’t like this.  It turns a structured problem into one 
> that violates DRY and loses the structure inherent in the solution.  Also, 
> while theoretically the dictionary could be optimized away, in practice that 
> would be difficult to do without heroics.
> 

One other minor and obscure point: if the compiler is aware of the regex 
grammar it can properly type the matches, I can imagine the following cases:

if case /(let name: [a-zA-Z]+) (let count: Int)/ = getSomeString() {
   print(name, count)
}

-> name has type String, count has type Int (and matches [0-9]+)


if case /(let name: [a-zA-Z]+)? (let count: Int)/ = getSomeString() {
   print(name, count)
}

-> name has type String?

if case /(let name: [a-zA-Z]+)* (let count: Int)/ = getSomeString() {
   print(name, count)
}

-> name has type [String]

etc.  Even if we don’t have a “default regex” for types, it would still be 
awesome to be able to write:


if case /(let name: [a-zA-Z]+) (let count: Int: [0-9]+)/ = getSomeString() {
   print(name, count)
}

and have that transparently invoke and check the Int?(string) failable 
initializer.

-Chris

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


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

2017-11-24 Thread Chris Lattner via swift-evolution
:

On Nov 24, 2017, at 11:12 AM, Xiaodi Wu  wrote:
> I think we've circled back to a topic that we've discussed here before. I do 
> agree that having more of this validation at compile time would improve the 
> experience. However, I can see a few drawbacks to the _compiler_ doing the 
> validation:
> 
> - As seen in these discussions about string literals where users want to copy 
> and paste text and have it "just work," supporting only one dialect in regex 
> literals will inevitably lead users to ask for other types of regex literals 
> for each individual flavor of regex they encounter.

Focusing first on the user model instead of implementation details: 

I don’t see why this is desirable at all.  If someone came to the Perl 
community and said “I want to use unmodified tcl regexp syntax”, the Perl 
community would politely tell them to buzz off.  They can just use string 
literals.

Allowing // syntax to support different grammars makes the Swift language more 
complex for users (independent of implementation details) and I don’t see any 
benefit to allowing that.  IMO, we’d be much better off by having a single 
blessed syntax, make it work as well as possible, and steer the community 
strongly towards using it.

Someone wanting to use NSRegularExpression or a bsd regex library or whatever 
can use string literals, just like they do now.  This has the *advantage* that 
you don’t look at the code using //’s and think it does something it doesn’t.

> - In the absence of a `constexpr`-like facility, supporting runtime 
> expressions would mean we'd be writing the same code twice, once in C++ for 
> compile-time validation of literal expressions and another time in Swift for 
> runtime expressions.

Agreed.  There are various ways we could factor this logic, including having 
the regex parser + tree representation be literally linked into both the 
compiler and stdlib.  I don’t think the cost is great, and we definitely do 
such things already.  If we do this right, the functionality can subsume tools 
like flex as well, which means we’d get a net reduction of complexity in the 
whole system.


> 2) I’d like to explore the idea of making // syntax be *patterns* instead of 
> simply literals.  As a pattern, it should be possible to bind submatches 
> directly into variable declarations, eliminating the need to count parens in 
> matches or other gross things.  Here is strawman syntax with a dumb example:
> 
> if case /([a-zA-Z]+: let firstName) ([a-zA-Z]+: let lastName)/ = 
> getSomeString() {
>print(firstName, lastName)
> }
> 
> This is an interesting idea. But is it significantly more usable

I don’t know if this is the ideal way to do this, as I mentioned before, I 
think we need to have a concerted design effort that considers such things.  
Regex functionality does fit naturally with pattern matching though, so I don’t 
think we should discard it too early.

> than the same type having a collection of named matches using the usual Perl 
> syntax?
> 
>   if case /(?[a-zA-Z]+) (?[a-zA-Z]+)/ = getSomeString() {
> print(Regex.captured["firstName"], Regex.captured["lastName"])
>   }

Personally, I really don’t like this.  It turns a structured problem into one 
that violates DRY and loses the structure inherent in the solution.  Also, 
while theoretically the dictionary could be optimized away, in practice that 
would be difficult to do without heroics.

> 3) I see regex string matching as the dual to string interpolation.  We 
> already provide the ability for types to specify a default way to print 
> themselves, and it would be great to have default regex’s associated with 
> many types, so you can just say “match an Int here” instead of having to 
> match [0-9]+ and then do a failable conversion to Int outside the regex.
> 
> 
> 4) I’d like to consider some of the advances that Perl 6 added to its regex 
> grammar.  Everyone knows that modern regex’s aren’t actually regular anyway, 
> so it begs the question of how far to take it.  If nothing else, I appreciate 
> the freeform structure supported (including inline comments) which make them 
> more readable.
> 
> Sounds like we want multiline regex literals :)

Yes, I absolutely do, but I want the // syntax to imply them.  It’s “single 
line” literal syntax that we should eliminate by default. 

-Chris


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


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

2017-11-24 Thread Chris Lattner via swift-evolution
On Nov 24, 2017, at 3:47 PM, Douglas Gregor via swift-evolution 
 wrote:
> One could imagine adding a “curry” operation to function types:

Right, having non-nominal types participate in the generics system would be 
undoubtably awesome! :)

> Or perhaps making metatypes Hashable so they can be used as keys into a 
> Dictionary:
> 
>   extension T.Type: Hashable {

Ok, so you just happened to pick a simple one: what is the benefit of plumbing 
knowledge of metatypes through the entire generics system, rather than define a 
“Swift.Metatype” type, and defining stuff against it?

-Chris



> var hashValue: Int {
>   return ObjectIdentifier(self).hashValue
> }
> 
>static func ==(lhs: T.Type, rhs: T.Type) -> Bool { /* standard library 
> magic */ }
>   }
> 
>   - Doug
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


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

2017-11-24 Thread Douglas Gregor via swift-evolution


> On Nov 22, 2017, at 2:59 PM, Mike Kluev  wrote:
> 
> on Date: Tue, 21 Nov 2017 22:54:21 -0800 Douglas Gregor  > wrote:
> 
> > On Nov 21, 2017, at 10:48 PM, David Hart  > > wrote:
> >
> > On 22 Nov 2017, at 07:41, Douglas Gregor via swift-evolution 
> >  
> > >> 
> > wrote:
> >
> >>
> >> I think it’s straightforward and less ugly to make structural types allow 
> >> extensions and protocol conformances.
> >
> > Can somebody explain to me what is less ugly about that? I would have 
> > naturally thought that the language would be simpler as a whole if there 
> > only existed nominal types and all structural types were just sugar over 
> > them.
> 
> See Thorsten’s response with, e.g.,
> 
>   Function
> 
> which handles “inout” by adding wrappers around the parameter types (which 
> one would have to cope with in any user of Function), but still doesn’t 
> handle argument labels. To handle argument labels, we would need something 
> like strings as generic arguments. We’d also need to handle calling 
> conventions and anything else we invent for function types.
> 
> 
> can you outline how extensions and protocol conformances might look for 
> structural types? to compare the ugliness of both approaches.

There are some examples at


https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types

e.g., making all tuples of Equatable elements Equatable (which also mixes in 
conditional conformances and variadic generics):

extension<...Elements : Equatable> (Elements...) : Equatable { // 
extending the tuple type "(Elements...)" to be Equatable
}

One could imagine adding a “curry” operation to function types:

  extension (Param1, Param2) -> Result {
var curried: (Param1) -> (Param2) -> Result {
  return { (arg1: Param1) in { (arg2: Param2) in self(arg1, arg2) } }
}
  }

Or perhaps making metatypes Hashable so they can be used as keys into a 
Dictionary:

  extension T.Type: Hashable {
var hashValue: Int {
  return ObjectIdentifier(self).hashValue
}

   static func ==(lhs: T.Type, rhs: T.Type) -> Bool { /* standard library magic 
*/ }
  }

- Doug


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


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

2017-11-24 Thread Adrian Zubarev via swift-evolution
In general this is more then welcome, so +1 for me.

However I have one question:

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

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

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

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

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

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

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

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

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

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

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

I am also interested in hearing general feedback on this feature from the 
community at large.  Have you also found this limitation frustrating?  In what 
contexts?  Does anyone have reservations about introducing this capability?  If 
so, what are they?

Matthew

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


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

2017-11-24 Thread Matthew Johnson via swift-evolution
As mentioned in my prior message, I currently have a PR open to update the 
generics manifesto (https://github.com/apple/swift/pull/13012 
).  I removed one topic from that 
update at Doug Gregor’s request that it be discussed on the list first.  

The idea is to add the ability to make default arguments conditional (i.e. 
depend on generic constraints).  It is currently possible to emulate 
conditional default arguments using an overload set.  This is verbose, 
especially when several arguments are involved.  Here is an example use case 
using the overload method to emulate this feature:

```swift
protocol Resource {
  associatedtype Configuration
  associatedtype Action
}
struct ResourceDescription {
  func makeResource(with configuration: R.Configuration, actionHandler: 
@escaping (R.Action) -> Void) -> R {
// create a resource using the provided configuration
// connect the action handler
// return the resource
  }
}

extension ResourceDescription where R.Configuration == Void {
  func makeResource(actionHandler: @escaping (R.Action) -> Void) -> R {
return makeResource(with: (), actionHandler: actionHandler)
  }
}

extension ResourceDescription where R.Action == Never {
  func makeResource(with configuration: R.Configuration) -> R {
return makeResource(with: configuration, actionHandler: { _ in })
  }
}

extension ResourceDescription where R.Configuration == Void, R.Action == Never {
  func makeResource() -> R {
return makeResource(with: (), actionHandler: { _ in })
  }
}

```

Adding language support for defining these more directly would eliminate a lot 
of boilerplate and reduce the need for overloads.  Doug mentioned that it may 
also help simplify associated type inference 
(https://github.com/apple/swift/pull/13012#discussion_r152124535 
).

The reason that I call this a pre-pitch and one reason Doug requested it be 
discussed on list is that I haven’t thought of a good way to express this 
syntactically.  I am interested in hearing general feedback on the idea.  I am 
also looking for syntax suggestions.

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


[swift-evolution] [Pitch] Generalized supertype constraints

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

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

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

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

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

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

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

I am also interested in hearing general feedback on this feature from the 
community at large.  Have you also found this limitation frustrating?  In what 
contexts?  Does anyone have reservations about introducing this capability?  If 
so, what are they?

Matthew

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


Re: [swift-evolution] [Proposal] Random Unification

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Fri, Nov 24, 2017 at 2:55 PM, Alejandro Alonso 
wrote:

> Regarding naming too many things “random”, I’ve talked to many developers
> on my end and they all don’t find it confusing. This proposal is aimed to
> make it obvious what the operation is doing when regarding random. I still
> agree that the proposed solution does just that and in practice feels good
> to write.
>

I must disagree quite strongly here. The various facilities you name
"random" have different semantics, and differences in semantics should be
reflected in differences in names. It doesn't matter that some people don't
find it confusing; it is objectively the case that you have named multiple
distinct facilities with the same name, which leads to confusion. I, for
one, get confused, and you can see on this list that people are using
arguments about one property named "random" to discuss another property
named "random". This is quite an intolerable situation.

I disagree that sample is the correct naming to use here. Getting a sample
> is a verb in this context which would make it break API guidelines just as
> well as `pick()`. To sample is to “take a sample or samples of (something)
> for analysis.” I can agree to use `sampling()` which follows API
> guidelines. This would result in the following grammar for `[“hi”, “hello”,
> “hey”].sampling(2)`, “From array, get a sampling of 2"
>

"Sampling" is fine.


On Nov 23, 2017, 12:54 AM -0600, Xiaodi Wu , wrote:
>
> On Wed, Nov 22, 2017 at 23:01 Alejandro Alonso 
> wrote:
>
>> Like I’ve said, python has different syntax grammar. We have to read each
>> call site and form a sentence from it. `random.choice([1, 2, 3])` to me
>> this reads, “Get a random choice from array”. This makes sense. Slapping
>> the word choice as an instance property like `[1, 2, 3].choice` reads,
>> “From array, get choice”. What is choice? This doesn’t make sense at all to
>> me. To me, the only good solution is `[1, 2, 3].random` which reads, “From
>> array, get random”. I actually think most users will be able to understand
>> this at first glance rather than choice (or any or some).
>>
>
> Again, my concern here is that you are proposing to name multiple things
> "random". If this property should be called "random"--which I'm fine
> with--then the static method "random(in:)" should be named something else,
> and the static property "random" should be dropped altogether (as I
> advocate for reasons we just discussed) or renamed as well. It is simply
> too confusing that there are so many different "random" methods or
> properties. Meanwhile, isn't your default RNG also going to be called
> something like "DefaultRandom"?
>
> In regards to the sample() function on collections, I have added this as I
>> do believe this is something users need. The name I gave it was pick() as
>> this reads, “From array, pick 2”.
>>
>
> The name "sample" has been used to good effect in other languages, has a
> well understood meaning in statistics, and is consistent with Swift
> language guidelines. The operation here is a sampling, and per Swift
> guidelines the name must be a noun: therefore, 'sample' is fitting. "Pick"
> does not intrinsically suggest randomness, whereas sample does, and your
> proposed reading uses it as a verb, whereas Swift guidelines tell us it
> must be a noun. I would advocate strongly for using well-established
> terminology and sticking with "sample."
>
>
> On Nov 17, 2017, 8:32 PM -0600, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org>, wrote:
>>
>> On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon <
>> br...@architechies.com> wrote:
>>
>>> On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> But actually, Int.random followed by % is the much bigger issue and a
>>> very good cautionary tale for why T.random is not a good idea. Swift should
>>> help users do the correct thing, and getting a random value across the full
>>> domain and computing an integer modulus is never the correct thing to do
>>> because of modulo bias, yet it's a very common error to make. We are much
>>> better off eliminating this API and encouraging use of the correct API,
>>> thereby reducing the likelihood of users making this category of error.
>>>
>>>
>>> Amen.
>>>
>>> If (and I agree with this) the range-based notation is less intuitive
>>> (0..<10.random is certainly less discoverable than Int.random), then we
>>> ought to offer an API in the form of `Int.random(in:)` but not
>>> `Int.random`. This does not preclude a `Collection.random` API as Alejandro
>>> proposes, of course, and that has independent value as Gwendal says.
>>>
>>>
>>> If we're not happy with the range syntax, maybe we should put
>>> `random(in:)`-style methods on the RNG protocol as extension methods
>>> instead. Then there's a nice, uniform style:
>>>
>>> let diceRoll = rng.random(in: 1...6)
>>> let card = rng.random(in: deck)
>>> let 

Re: [swift-evolution] [Proposal] Random Unification

2017-11-24 Thread Alejandro Alonso via swift-evolution
Regarding naming too many things “random”, I’ve talked to many developers on my 
end and they all don’t find it confusing. This proposal is aimed to make it 
obvious what the operation is doing when regarding random. I still agree that 
the proposed solution does just that and in practice feels good to write.

I disagree that sample is the correct naming to use here. Getting a sample is a 
verb in this context which would make it break API guidelines just as well as 
`pick()`. To sample is to “take a sample or samples of (something) for 
analysis.” I can agree to use `sampling()` which follows API guidelines. This 
would result in the following grammar for `[“hi”, “hello”, “hey”].sampling(2)`, 
“From array, get a sampling of 2"

- Alejandro


On Nov 23, 2017, 12:54 AM -0600, Xiaodi Wu , wrote:
On Wed, Nov 22, 2017 at 23:01 Alejandro Alonso 
> wrote:
Like I’ve said, python has different syntax grammar. We have to read each call 
site and form a sentence from it. `random.choice([1, 2, 3])` to me this reads, 
“Get a random choice from array”. This makes sense. Slapping the word choice as 
an instance property like `[1, 2, 3].choice` reads, “From array, get choice”. 
What is choice? This doesn’t make sense at all to me. To me, the only good 
solution is `[1, 2, 3].random` which reads, “From array, get random”. I 
actually think most users will be able to understand this at first glance 
rather than choice (or any or some).

Again, my concern here is that you are proposing to name multiple things 
"random". If this property should be called "random"--which I'm fine with--then 
the static method "random(in:)" should be named something else, and the static 
property "random" should be dropped altogether (as I advocate for reasons we 
just discussed) or renamed as well. It is simply too confusing that there are 
so many different "random" methods or properties. Meanwhile, isn't your default 
RNG also going to be called something like "DefaultRandom"?

In regards to the sample() function on collections, I have added this as I do 
believe this is something users need. The name I gave it was pick() as this 
reads, “From array, pick 2”.

The name "sample" has been used to good effect in other languages, has a well 
understood meaning in statistics, and is consistent with Swift language 
guidelines. The operation here is a sampling, and per Swift guidelines the name 
must be a noun: therefore, 'sample' is fitting. "Pick" does not intrinsically 
suggest randomness, whereas sample does, and your proposed reading uses it as a 
verb, whereas Swift guidelines tell us it must be a noun. I would advocate 
strongly for using well-established terminology and sticking with "sample."


On Nov 17, 2017, 8:32 PM -0600, Xiaodi Wu via swift-evolution 
>, wrote:
On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon 
> wrote:
On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution 
> wrote:

But actually, Int.random followed by % is the much bigger issue and a very good 
cautionary tale for why T.random is not a good idea. Swift should help users do 
the correct thing, and getting a random value across the full domain and 
computing an integer modulus is never the correct thing to do because of modulo 
bias, yet it's a very common error to make. We are much better off eliminating 
this API and encouraging use of the correct API, thereby reducing the 
likelihood of users making this category of error.

Amen.

If (and I agree with this) the range-based notation is less intuitive 
(0..<10.random is certainly less discoverable than Int.random), then we ought 
to offer an API in the form of `Int.random(in:)` but not `Int.random`. This 
does not preclude a `Collection.random` API as Alejandro proposes, of course, 
and that has independent value as Gwendal says.

If we're not happy with the range syntax, maybe we should put 
`random(in:)`-style methods on the RNG protocol as extension methods instead. 
Then there's a nice, uniform style:

let diceRoll = rng.random(in: 1...6)
let card = rng.random(in: deck)
let isHeads = rng.random(in: [true, false])
let probability = rng.random(in: 0.0...1.0) // Special FloatingPoint overload

The only issue is that this makes the default RNG's name really important. 
Something like:

DefaultRandom.shared.random(in: 1...6)

Will be a bit of a pain for users.

I did in fact implement this style of RNG in NumericAnnex, but I'm not 
satisfied with the design myself. Not only is it a bit of an ergonomic thorn, 
there's also another drawback that actually has weighty implications:

Users aren't conditioned to reuse RNG instances. Perhaps, it is because it can 
"feel" wrong that multiple random instances should come from the *same* RNG. 
Instead, it "feels" more right to initialize a new 

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

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Thu, Nov 23, 2017 at 5:33 PM, Chris Lattner  wrote:

> On Nov 23, 2017, at 10:35 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> This proposed addition addresses a known pain point, to be sure, but I
> think it has many implications for the future direction of the language and
> I'd like to explore them here.
>
>
> Thanks for writing this up Xiaodi,
>
> We should certainly move any discussion about regex literals into its own
> thread, but to make it clear that I'm not simply suggesting that we
> implement something in Swift 10 instead of addressing a known pain point
> now, here's a sketch of how Swift 5 could make meaningful progress:
>
> - Teach the lexer about basic /pattern/flag syntax.
> - Add an `ExpressibleByRegularExpressionLiteral`, where the initializer
> would be something like `init(regularExpressionLiteralPattern: String,
> flags: RegularExpressionFlags)` where RegularExpressionFlags would be an
> OptionSet type.
> - Add conformance to `ExpressibleByRegularExpressionLiteral` to
> `NSRegularExpression`.
> - Have no default `RegularExpressionLiteralType` for now so that, in the
> future, we can discuss and design a Swift standard library regular
> expression type, which is justifiable because we've baked in language
> support for the literal. This can be postponed.
>
>
> This approach could make sense, but it makes a couple of assumptions that
> I’m not certain are the right way to go (to be clear, I’m not certain that
> they’re wrong either!).
>
> Things I’d like to carefully consider:
>
> 1) We could make the compiler parse and validate regex literals at compile
> time:
>
> a) this allows the compiler to emit diagnostics (with fixits!) on
> malformed literals.
>
> b) When the compiler knows the grammar of the regex, it can precompile the
> regex into a DFA table or static executable code, rather than runtime
> compiling into a bytecode.
>
> c) however, the compiler can’t parse the literal unless it knows the
> dialect it corresponds to.  While we could parameterize this somehow (e.g.
> as a requirement in ExpressibleByRegularExpressionLiteral), if we weren’t
> bound by backwards compatibility, we would just keep things simple and say
> “there is one and only one grammar”.  I’d argue that having exactly one
> grammar supported by the // syntax is also *better* for users, rather than
> saying “it depends on what library you’re passing the regex into”.
>

I think we've circled back to a topic that we've discussed here before. I
do agree that having more of this validation at compile time would improve
the experience. However, I can see a few drawbacks to the _compiler_ doing
the validation:

- In the absence of a `constexpr`-like facility, supporting runtime
expressions would mean we'd be writing the same code twice, once in C++ for
compile-time validation of literal expressions and another time in Swift
for runtime expressions.

- As seen in these discussions about string literals where users want to
copy and paste text and have it "just work," supporting only one dialect in
regex literals will inevitably lead users to ask for other types of regex
literals for each individual flavor of regex they encounter.

Just like ExpressibleByDictionaryLiteral doesn't deduplicate keys, leaving
that to Dictionary, I think regex literals are better off not validating
literal expressions (or, maybe, doing only the barest sanity check),
leaving the rest to concrete regex types. As you point out with validation
of integer overflows during constant folding, we could get enough
compile-time validation even without teaching the compiler itself how to
validate the literal.

2) I’d like to explore the idea of making // syntax be *patterns* instead
> of simply literals.  As a pattern, it should be possible to bind submatches
> directly into variable declarations, eliminating the need to count parens
> in matches or other gross things.  Here is strawman syntax with a dumb
> example:
>
> if case /([a-zA-Z]+: let firstName) ([a-zA-Z]+: let lastName)/ =
> getSomeString() {
>print(firstName, lastName)
> }
>
>
This is an interesting idea. But is it significantly more usable than the
same type having a collection of named matches using the usual Perl syntax?

  if case /(?[a-zA-Z]+) (?[a-zA-Z]+)/ =
getSomeString() {
print(Regex.captured["firstName"], Regex.captured["lastName"])
  }

3) I see regex string matching as the dual to string interpolation.  We
> already provide the ability for types to specify a default way to print
> themselves, and it would be great to have default regex’s associated with
> many types, so you can just say “match an Int here” instead of having to
> match [0-9]+ and then do a failable conversion to Int outside the regex.
>
>
> 4) I’d like to consider some of the advances that Perl 6 added to its
> regex grammar.  Everyone knows that modern regex’s aren’t actually regular
> anyway, so it begs the question of how far to take it.  If 

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

2017-11-24 Thread Xiaodi Wu via swift-evolution
On Thu, Nov 23, 2017 at 6:27 PM, Kelvin Ma  wrote:

>
>
> On Thu, Nov 23, 2017 at 7:08 PM, Xiaodi Wu  wrote:
>
>>
>> On Thu, Nov 23, 2017 at 16:45 Kelvin Ma via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>>
>>>
>>> On Thu, Nov 23, 2017 at 12:32 PM, Tino Heth <2...@gmx.de> wrote:
>>>

 a good idea on paper, a disastrous one in practice. What happens if
 every geometry library declares their own Point type?

 That would be ugly („disastrous“ imho is a little bit to strong — C++
 had/has similar issues, and other languages as well)
 But if there would be a simple Point struct in a library that is
 popular (could be achieved by shipping it alongside the stdlib), this
 problem would be solved (there has been a pitch lately, but I guess it
 faded away silently).

>>>
>>> it’s ugly in C++ and disastrous in Swift because C++ has fixed layout
>>> guarantees and everyone agrees that z comes after y comes after x, so you
>>> can unsafe-bitcast the foreign C++ points into your own points “for free”.
>>> you can’t do the same thing in Swift
>>>
>>
>> Why do you need to have this ability to unsafe bitcast? Is
>> interconversion between point types such a common operation that it's a
>> performance bottleneck?
>>
>
> idk if it’s a performance bottleneck because i use tuples in my geometry
> stack and i keep the bottom 2 levels in the same module but it cannot be
> good. a lot of the geometry code I write sits atop 2 or 3 other layers of
> geometry code beneath it, and it interops with geometry APIs in other
> libraries. for example it might be organized like
>
> [ Client geometry code ] ←→ [ Library geometry code ] (example:
> Voronoi.voronoi(_:), Noise.perlin(_:_:))
>[ Procedurally generated geometry ] (example:
> makeSphere(resolution:))
>[Matrices and projections ] (example:
> Geometry.clockwise(_:_:center:normal:))
>[   Math  ] (example: Math.cross(_:_:))
>
> converting at every boundary seems like something to avoid. not to mention
> the sheer amount of boilerplate all those conversions produce.
>

FWIW, tuples are only guaranteed to have a C-compatible layout when exposed
to C; that is, Swift doesn't guarantee that there will not be optimizations
in the future that change tuple layout such that a call into C will cause
your tuples to do interop gymnastics.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution