Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 11:59 PM, Thorsten Seitz 
wrote:

>
>
> Am 16.10.2017 um 00:46 schrieb Xiaodi Wu :
>
> On Sun, Oct 15, 2017 at 2:39 PM, Kevin Nattinger 
> wrote:
>
>> […]
>> Swift's Sequence protocol does not require the order of iteration to
>> "convey any meaning"; it doesn't even require it to be deterministic.
>>
>>
>> And that’s EXACTLY why none of the functions on Sequence should rely on
>> the order conveying meaning.  `ElementsEqual` (for example) DOES rely on
>> the order of iteration conveying a meaning not required by the protocol,
>> and renaming it `lexicographicallyEquals` does not change that fact. Either
>> Sequence needs to require a meaningful order or `elementsEqual` should be
>> moved to a protocol that does.
>>
>
> What's your basis for saying that `elementsEqual` requires orders of
> iteration that "convey a meaning"? It merely answers the question of
> whether iterating over `a` is substitutable for iterating over `b`, a
> question applicable to instances of any type which offers iterated access.
>
>
> As Set has no intrinsic order of elements just imagine it was implemented
> to have each iterator created on it to iterate in a random order. This
> would satisfy the Sequence protocol (or rather its Iterable part hich
> should be split off) and clearly show that the order is meaningless for
> Sets.
>

As I wrote above, Set cannot use a different iteration order for each
iterator because it conforms to `Collection`, thereby guaranteeing a
multi-pass sequence.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 11:57 PM, Thorsten Seitz 
wrote:

>
>
> Am 16.10.2017 um 00:41 schrieb Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org>:
>
> On Sun, Oct 15, 2017 at 2:32 PM, Kevin Nattinger 
> wrote:
>
>> […]
>> Sets, as a mathematical concept, have no intrinsic order. However,
>> instances of `Set`, which can be iterated over, *do* have at least one
>> order which can be said to be intrinsic in the following sense: as long as
>> iteration is possible, no API design can prevent that order from being
>> observed and associated with the instance. Put another way, if you can use
>> an instance of a type in a for...in loop, intrinsic to that functionality
>> is a publicly visible order.
>>
>>
>> You keep saying this, I keep saying it’s only a technical “order” that is
>> an implementation detail
>>
>
> You keep saying it's an implementation detail, which it emphatically is
> *not*. It's a *public guarantee* by the protocol that you can use an
> instance of `Set` in a `for...in` loop, thereby exposing a publicly visible
> order. An implementation detail is something
>
>
> Being able to use a Set in a for...in loop does *not* make it ordered! The
> purpose is is just being able to do something with each element. That a
> for...loop works sequentially is just a side effect. Just imagine we had
> parallelized for...in loops.
>

No, it is not at all a "side effect." A for...in loop is a way of
controlling the flow of code which accesses elements in a sequence one
after another, and the correct behavior of code inside the loop depends on
these semantics. A "parallel for" loop would be a totally different thing;
arbitrary for...in loops can't be automatically "upgraded" to a "parallel
for" loop because they have different semantics, and types that support
"parallel for" would likely have to conform to a protocol other than
`Sequence`.

> that could go away with an alternative implementation. By contrast, no
> implementation that permits an instance of `Set` being iterated over in a
> `for...in` loop can avoid exposing at least one publicly visible order,
> because it's not a matter of implementation. Put another way, by allowing
> iteration, a type necessarily exposes at least one publicly visible order
> and thereby models a sequence in at least one way.
>
>
> Wrong. I could easily implement Set or another type to iterate in a random
> order over its elements, so each iteration would expose a different
> (meaningless) order.
>

No, you cannot implement `Set` in this way because it conforms to
`Collection`, which guarantees a multi-pass sequence. Set *must expose the
same order on every iteration*.


> This demonstrates that being able to be used in a for...in loop is about
> doing somthing with each element and not about element order.
>

Again, Sequence *already doesn't* require the order to be meaningful or
even repeatable. Notice that, above, I said at least one order. A
conforming type could expose as many different orders as iterations, but
that changes nothing. I can still map an instance of that type to get an
array of elements, and that array will reveal some order which is the
result of the inner workings of the type.

The latter is an additional property which should be expressed in an
> additional protocol like Kevin suggested.
>

What useful generic algorithms would this protocol support that are not
already possible?

-Thorsten
>
>
>
>
>
>> and can’t be relied upon for anything and so we shouldn’t provide methods
>> that rely on it. I think this part of the discussion has reached the “agree
>> to disagree” stage.
>>
>> […]
>>>
>> You’re a fan of the principal of least surprise. Tell me, which would be
>>> less surprising: Set.dropFirst() actually drops a random element, or Set
>>> doesn’t have a dropFirst()? And if you think dropFirst() removing an
>>> element at random is not surprising, please explain why.
>>>
>>
>> I think Set.dropFirst removing the first element that I observe on
>> iteration is the least surprising answer, because Swift tells me that the
>> stdlib Set models a set but that it is also a sequence.
>>
>>
>> Your logic is backwards. You’re saying it’s “least surprising” because
>> that’s how it’s currently implemented, not that it should be implemented
>> that way because it’s least surprising.
>>
>
> No, I'm saying it's least surprising because any type that supports
> iterated access thereby exposes an order--not as an implementation detail
> but as a matter of public API--and in the absence of any other order,
> "first" must refer to that order so exposed.
>
>> […]
>
>
>>> And that’s PRECISELY why lexicographicallyEqual does not make sense to
>>> apply to unordered sets. There is no lexicographical comparison possible,
>>> so why do you keep insisting they should have a method that falsely claims
>>> to lexicographically compare them?
>>>
>>
>> I agree! It doesn't make sense if no comparison is possible! But 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Thorsten Seitz via swift-evolution


> Am 16.10.2017 um 04:36 schrieb Jonathan Hull via swift-evolution 
> :
> 
> Ok, just to summarize our options so far (in order of effort & theoretical 
> effectiveness):
> 
> 1) Do nothing - This is the easiest thing to do, but it won’t fix any problems
> 
> 2) Rename the elementsEqual method: (Again, fairly easy to do, and will 
> hopefully reduce confusion, but doesn’t fix the underlying issue)
>   • lexicographicallyEquals
>   • elementOrderingEqual (this is my favorite of the names)
>   • sequentiallyEquals
>   • orderedEqual
>   • pairwiseEqual
>   • iterativelyEquals
>   I might be missing some...

This is just wasting time IMO. Lets tackle the real problem.

> 
> 3) Change the implementation of Set so that it will return the same order 
> whenever it has the same elements. This solves the issue with set, but not 
> with unordered sequences in general (e.g. comparing a set with the keys of a 
> dictionary). Still on balance, this is my current favorite.
> 
> 4) Add an UnorderedX (name to be bikeshed) protocol that defines a 
> sequence/collection as unordered, which provides a method which will return a 
> sequence/collection of defined order. Generic algorithms can check for 
> conformance to the UnorderedX protocol, and provide different implementations 
> as needed (mostly by operating on the provided sequence/collection).  The 
> advantage is that generic algorithms can be made which take whether the 
> sequence is ordered/unordered into account, and we don’t lose any speed. The 
> downside is that you have to remember to check if it is ordered or not, and 
> failing to do so may result in generic algorithms which have the current 
> issues.  We could guarantee that the standard library would be correct though.
> 
> 5) Add an UnorderedX protocol that defines a sequence/collection as 
> unordered, takes the unordered elements and uses them to provide a partial 
> implementation to Sequence/Collection where the elements have a defined 
> order.  The advantage to this is that you can now build correct generic 
> algorithms that depend on a stable/defined ordering that will “just work" 
> (e.g. elementsEqual will work when comparing a set to the keys of a 
> dictionary).  

Maybe instead of `elementsEqual` we need a `unorderedEquals` method to solve 
the problems `elementsEqual` was written for?


> The disadvantage is that it will be a bit slower for things that don’t care 
> about ordering (e.g. many things involving for-in) unless you specifically 
> call a method that says you don’t care about the order.
> 
> 6) Rework the Sequence protocols to account for Ordered and Unordered (e.g. 
> replacing ‘first’ with ‘any’ and then adding ‘first’ back in only for ordered 
> sequences).  Reworking the protocol hierarchy would be the most permanent and 
> theoretically “correct” fix, but has the potential to be massively 
> source-breaking.

This is what should be fixed IMO.

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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 9:36 PM, Jonathan Hull  wrote:

> Ok, just to summarize our options so far (in order of effort & theoretical
> effectiveness):
>
> 1) *Do nothing* - This is the easiest thing to do, but it won’t fix any
> problems
>
> 2) *Rename the elementsEqual method*: (Again, fairly easy to do, and will
> hopefully reduce confusion, but doesn’t fix the underlying issue)
> • lexicographicallyEquals
> • elementOrderingEqual (this is my favorite of the names)
> • sequentiallyEquals
> • orderedEqual
> • pairwiseEqual
> • iterativelyEquals
> I might be missing some...
>

I'll be revising the proposal to incorporate these suggests, settling on
`elementsEqualInIterationOrder`.


> 3) *Change the implementation of Set* so that it will return the same
> order whenever it has the same elements. This solves the issue with set,
> but not with unordered sequences in general (e.g. comparing a set with the
> keys of a dictionary). Still on balance, this is my current favorite.
>

As I mentioned earlier, I think 4-6 are wildly out of the scope of this
discussion. The starting premise is that Set : Collection and Sequence :
Collection, and that this will not change for Swift 5.

4) *Add an UnorderedX* (name to be bikeshed) *protocol* *that defines a
> sequence/collection as unordered*, which provides a method which will *return
> a sequence/collection of defined order*. Generic algorithms can check for
> conformance to the UnorderedX protocol, and provide different
> implementations as needed (mostly by operating on the provided
> sequence/collection).  The advantage is that generic algorithms can be made
> which take whether the sequence is ordered/unordered into account, and we
> don’t lose any speed. The downside is that you have to remember to check if
> it is ordered or not, and failing to do so may result in generic algorithms
> which have the current issues.  We could guarantee that the standard
> library would be correct though.
>
> 5) *Add an UnorderedX* *protocol* *that defines a sequence/collection as
> unordered*, takes the unordered elements and uses them to *provide a
> partial implementation to Sequence/Collection* where the elements have a
> defined order.  The advantage to this is that you can now build correct
> generic algorithms that depend on a stable/defined ordering that will “just
> work" (e.g. elementsEqual will work when comparing a set to the keys of a
> dictionary).  The disadvantage is that it will be a bit slower for things
> that don’t care about ordering (e.g. many things involving for-in) unless
> you specifically call a method that says you don’t care about the order.
>
> 6) *Rework the Sequence protocols to account for Ordered and Unordered* (e.g.
> replacing ‘first’ with ‘any’ and then adding ‘first’ back in only for
> ordered sequences).  Reworking the protocol hierarchy would be the most
> permanent and theoretically “correct” fix, but has the potential to be
> massively source-breaking.
>
>
> Thanks,
> Jon
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Thorsten Seitz via swift-evolution


> Am 16.10.2017 um 00:46 schrieb Xiaodi Wu :
> 
> On Sun, Oct 15, 2017 at 2:39 PM, Kevin Nattinger  wrote:
>>> […]
>>> Swift's Sequence protocol does not require the order of iteration to 
>>> "convey any meaning"; it doesn't even require it to be deterministic.
>>> 
>> 
>> And that’s EXACTLY why none of the functions on Sequence should rely on the 
>> order conveying meaning.  `ElementsEqual` (for example) DOES rely on the 
>> order of iteration conveying a meaning not required by the protocol, and 
>> renaming it `lexicographicallyEquals` does not change that fact. Either 
>> Sequence needs to require a meaningful order or `elementsEqual` should be 
>> moved to a protocol that does.
> 
> What's your basis for saying that `elementsEqual` requires orders of 
> iteration that "convey a meaning"? It merely answers the question of whether 
> iterating over `a` is substitutable for iterating over `b`, a question 
> applicable to instances of any type which offers iterated access.
> 

As Set has no intrinsic order of elements just imagine it was implemented to 
have each iterator created on it to iterate in a random order. This would 
satisfy the Sequence protocol (or rather its Iterable part hich should be split 
off) and clearly show that the order is meaningless for Sets.

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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 8:51 PM, Jonathan Hull  wrote:

>
> On Oct 14, 2017, at 10:48 PM, Xiaodi Wu  wrote:
>
>>  That ordering can be arbitrary, but it shouldn’t leak internal
>>> representation such that the method used to create identical things affects
>>> the outcome of generic methods because of differences in internal
>>> representation.
>>>


  It would be better to say that the iteration order is well-defined.
 That will almost always mean documented, and usually predictable though
 obviously e.g. RNGs and iterating in random order will not be predictable
 by design.

>
> That's actually more semantically constrained than what Swift calls a
> `Collection` (which requires conforming types to be multi-pass and(?)
> finite). By contrast, Swift's `SpongeBob` protocol explicitly permits
> conforming single-pass, infinite, and/or unordered types.
>
>
> I think you’re talking about Sequence here, I’ve lost track of your
> nonsense by now. Yes, the current Swift protocol named Sequence allows
> unordered types. You seem to keep asserting that but not actually
> addressing my argument, which is *that allowing Sequences to be
> unordered with the current API is undesired and actively harmful, and
> should* *therefore** be changed*.
>

 What is harmful about it?


 After thinking about it, I think the harmful bit is that unordered
 sequences are leaking internal representation (In your example, this is
 causing people to be surprised when two sets with identical elements are
 generating different sequences/orderings based on how they were created).
 You are correct when you say that this problem is even true for for-in.

>>>
>>> I would not say it is a problem. Rather, by definition, iteration
>>> involves retrieving one element after another; if you're allowed to do that
>>> with Set, then the elements of a Set are observably ordered in some way.
>>> Since it's not an OrderedSet--i.e., order doesn't matter--then the only
>>> sensible conclusion is that the order of elements obtained in a for...in
>>> loop must be arbitrary. If you think this is harmful, then you must believe
>>> that one should be prohibited from iterating over an instance of Set.
>>> Otherwise, Set is inescapably a Sequence by the Swift definition of
>>> Sequence. All extension methods on Sequence like drop(while:) are really
>>> just conveniences for common things that you can do with iterated access;
>>> to my mind, they're essentially just alternative ways of spelling various
>>> for...in loops.
>>>
>>>
>>> I think an argument could be made that you shouldn’t be able to iterate
>>> over a set without first defining an ordering on it (even if that ordering
>>> is somewhat arbitrary).  Maybe we have something like a “Sequenc(e)able”
>>> protocol which defines things which can be turned into a sequence when
>>> combined with some sort of ordering.  One possible ordering could be the
>>> internal representation (At least in that case we are calling it out
>>> specifically).  If I had to say 
>>> “setA.arbitraryOrder.elementsEqual(setB.arbitraryOrder)”
>>> I would definitely be less surprised when it returns false even though setA
>>> == setB.
>>>
>>
>> Well, that's a totally different direction, then; you're arguing that
>> `Set` and `Dictionary` should not conform to `Sequence` altogether. That's
>> fine (it's also a direction that some of us explored off-list a while ago),
>> but at this point in Swift's evolution, realistically, it's not within the
>> realm of possible changes.
>>
>>
>> I am actually suggesting something slightly different.  Basically, Set
>> and Dictionary’s conformance to Collection would have a different
>> implementation.  They would conform to another protocol declaring that they
>> are unordered. That protocol would fill in part of the conformance to
>> sequence/collection using a default ordering, which is mostly arbitrary,
>> but guaranteed to produce the same ordering for the same list of elements
>> (even across collection types).  This would be safer, but a tiny bit slower
>> than what we have now (We could also potentially develop a way for
>> collections like set to amortize the cost). For those who need to recover
>> speed, the new protocol would also define a property which quickly returns
>> a sequence/iterator using the internal ordering (I arbitrarily called it
>> .arbitraryOrder).
>>
>> I believe it would not be source breaking.
>>
>
> That is indeed something slightly different.
>
> In an ideal world--and my initial understanding of what you were
> suggesting--Set and Dictionary would each have a member like `collection`,
> which would expose the underlying data as a `SetCollection` or
> `DictionaryCollection` that in turn would conform to `Collection`;
> meanwhile, Set and Dictionary themselves would not offer methods such as
> `prefix`, or 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 8:35 PM, Jonathan Hull  wrote:

>
> On Oct 15, 2017, at 3:41 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I’ll have to mull this over to see if I can come up with a coherent and
>> (more) specific requirement for what makes an Iterable a Sequence, since
>> clearly “documented” isn’t enough.  Perhaps something along the lines that
>> any two Sequences that compare equal must iterate the same.
>>
>> […]
>> Apple documentation calls this one of the "order-dependent" methods. It
>> is surely acceptable for a type that conforms to an order-dependent
>> protocol to have methods that are order-dependent; they do, however, have
>> to be clearly order-dependent to avoid confusion on unordered types.
>>
>>
>> I’m not clear on what you’re trying to get across here. It seems you’re
>> saying unordered types shouldn’t have order-dependent methods, which is
>> exactly what I’ve been arguing.
>>
>
> No, I'm saying, essentially, that there are no truly unordered types in
> Swift; `Set` and `Dictionary` lead double lives modeling unordered
> collections on the one hand and ordered collections on the other. The
> order-dependent methods can continue to exist; they just need to be clearly
> named so that users know when they're using an instance of `Set` in the
> manner of an unordered collection and when they're using an instance of
> `Set` in the manner of an ordered collection.
>
>
> Is the order of elements returned from Set/Dictionary guaranteed not to
> change based on implementation?  For instance, the elements of a dictionary
> may shift around as I add items, and they may be different in different
> runs of a program.
>
> If we document/say that Set will always return elements in the order they
> were added, then it may prevent us from using a more efficient
> implementation of Sets in a future version of Swift.
>
> Just to check what we are saying.  I am saying that we can’t really build
> generic algorithms on something which is undefined (because we are leaking
> implementation details, and depending on private implementation details
> leads to problems).  You are saying that the leaking of implementation
> details is a feature, not a bug… and that we should just document them and
> consider them fixed ABI?
>

We can also document the iteration order as arbitrary (i.e., the status
quo).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Thorsten Seitz via swift-evolution


> Am 16.10.2017 um 00:41 schrieb Xiaodi Wu via swift-evolution 
> :
> 
> On Sun, Oct 15, 2017 at 2:32 PM, Kevin Nattinger  wrote:
>>> […]
>>> Sets, as a mathematical concept, have no intrinsic order. However, 
>>> instances of `Set`, which can be iterated over, *do* have at least one 
>>> order which can be said to be intrinsic in the following sense: as long as 
>>> iteration is possible, no API design can prevent that order from being 
>>> observed and associated with the instance. Put another way, if you can use 
>>> an instance of a type in a for...in loop, intrinsic to that functionality 
>>> is a publicly visible order.
>> 
>> You keep saying this, I keep saying it’s only a technical “order” that is an 
>> implementation detail
> 
> You keep saying it's an implementation detail, which it emphatically is 
> *not*. It's a *public guarantee* by the protocol that you can use an instance 
> of `Set` in a `for...in` loop, thereby exposing a publicly visible order. An 
> implementation detail is something

Being able to use a Set in a for...in loop does *not* make it ordered! The 
purpose is is just being able to do something with each element. That a 
for...loop works sequentially is just a side effect. Just imagine we had 
parallelized for...in loops.


> that could go away with an alternative implementation. By contrast, no 
> implementation that permits an instance of `Set` being iterated over in a 
> `for...in` loop can avoid exposing at least one publicly visible order, 
> because it's not a matter of implementation. Put another way, by allowing 
> iteration, a type necessarily exposes at least one publicly visible order and 
> thereby models a sequence in at least one way.

Wrong. I could easily implement Set or another type to iterate in a random 
order over its elements, so each iteration would expose a different 
(meaningless) order.
This demonstrates that being able to be used in a for...in loop is about doing 
somthing with each element and not about element order. The latter is an 
additional property which should be expressed in an additional protocol like 
Kevin suggested.

-Thorsten



>  
>> and can’t be relied upon for anything and so we shouldn’t provide methods 
>> that rely on it. I think this part of the discussion has reached the “agree 
>> to disagree” stage.
>> 
 […]
 You’re a fan of the principal of least surprise. Tell me, which would be 
 less surprising: Set.dropFirst() actually drops a random element, or Set 
 doesn’t have a dropFirst()? And if you think dropFirst() removing an 
 element at random is not surprising, please explain why.
>>> 
>>> I think Set.dropFirst removing the first element that I observe on 
>>> iteration is the least surprising answer, because Swift tells me that the 
>>> stdlib Set models a set but that it is also a sequence.
>> 
>> Your logic is backwards. You’re saying it’s “least surprising” because 
>> that’s how it’s currently implemented, not that it should be implemented 
>> that way because it’s least surprising.
> 
> No, I'm saying it's least surprising because any type that supports iterated 
> access thereby exposes an order--not as an implementation detail but as a 
> matter of public API--and in the absence of any other order, "first" must 
> refer to that order so exposed.
> […]
 
 And that’s PRECISELY why lexicographicallyEqual does not make sense to 
 apply to unordered sets. There is no lexicographical comparison possible, 
 so why do you keep insisting they should have a method that falsely claims 
 to lexicographically compare them?
>>> 
>>> I agree! It doesn't make sense if no comparison is possible! But Swift 
>>> tells me that a `Set` is a `Sequence`!
>> 
>> You keep making the circular argument that a Set should do things because it 
>> currently does them. If you want to argue against changing things, argue 
>> that things shouldn’t be changed, not that the current implementation is 
>> correct because it is the current implementation.
> 
> No, I'm arguing that `Set`, by supporting iterated access, is not wrong to 
> conform to a protocol called `Sequence` because it does have an intrinsic and 
> publicly observable order, which is not an accident of a particular 
> implementation but is inherent to any type that supports iterated access. 
> Now, whether it's the *best choice* to conform `Set` to `Sequence` and offer 
> order-dependent functions is a matter of taste, but it isn't *wrong*.
>>> […]
>>> You will always have to account for this possibility, because Swift's 
>>> `Equatable` explicitly allows "special values" to be not equal to 
>>> themselves. This is, at least in part, in order to accommodate the IEEE 
>>> decree that NaN != NaN:
>> 
>>> 
>>> ```
>>> let x = [Double.nan]
>>> x.elementsEqual(x) // false
>>> ```
>> 
>> NaN is special, one-shot and unordered sequences are not. Unless you think 
>> that all unordered and 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Thorsten Seitz via swift-evolution


> Am 15.10.2017 um 21:22 schrieb Xiaodi Wu :
> 
> 
> On Sun, Oct 15, 2017 at 14:14 Thorsten Seitz  wrote:
>>> Am 15.10.2017 um 10:38 schrieb Xiaodi Wu via swift-evolution 
>>> :
>>> 
 On Sun, Oct 15, 2017 at 2:29 AM, Kevin Nattinger  
 wrote:
 
> On Oct 14, 2017, at 7:54 PM, Xiaodi Wu  wrote:
> 
> On Sat, Oct 14, 2017 at 6:17 PM, Kevin Nattinger  
> wrote:
> […]
> * A Swift `Sequence` is, to put it simplistically, a thing that can 
> be iterated over in a `for...in` loop. If it would make you happy, 
> for the rest of the discussion, let's suppose we called the protocol 
> `ForLoopable` instead of `Sequence`.
 
 ForLoopable is so ugly. Since we’re just iterating over the elements, 
 how about, oh, say, `Iterable`? Hey, that looks familiar.
>>> 
>>> I'm not trying to bikeshed the name of `Sequence`. I'm picking an 
>>> intentionally unwieldy name for the purposes of discussing the 
>>> semantics of this particular protocol. The point is that the underlying 
>>> issue has nothing to do with the name; it can be `Iterable` or it can 
>>> be `SpongeBob` for all I care.
>> 
>> I’m not trying to bikeshed the name either, The underlying issue is that 
>> (what is currently) Sequence actually encompasses two separate 
>> functionalities, and those functionalities need to be separated with 
>> their separate semantic requirements documented. “Sequence: Iterable,” 
>> “OrderedSequence: Sequence,” “SpongeBob: ForLoopable,” the names are 
>> 100% irrelevant at this point; what’s important is that one is not 
>> necessarily ordered and the other guarantees an order.
> 
> What are the "two separate functionalities”?
 
 Iteration, with convenience methods that don’t imply or rely on an order 
 that may not be there; and convenience methods applicable to sequences 
 that do have an intrinsic order.
>>> 
>>> Sets, as a mathematical concept, have no intrinsic order. However, 
>>> instances of `Set`, which can be iterated over, *do* have at least one 
>>> order which can be said to be intrinsic in the following sense: as long as 
>>> iteration is possible, no API design can prevent that order from being 
>>> observed and associated with the instance. Put another way, if you can use 
>>> an instance of a type in a for...in loop, intrinsic to that functionality 
>>> is a publicly visible order.
>> 
>> I disagree. Sets are value types, therefore two instances of `Set` are equal 
>> if they contain the same elements. An intrinsic order should therefore only 
>> depend on the elements contained and should be the same for two instances of 
>> `Set` which are equal.
>> This is not the case, though, as you can easily check in a playground by 
>> looking at Set([1,2,3,4,5,6]) and Set([6,5,4,3,2,1]) which represent the 
>> same value and are equal but do *not* have the same order.
>> 
>> 
>>> 
 
> All the extension methods on Sequence are ways of spelling things that 
> you can write in a few lines of code using a `for...in` loop; they're in 
> the stdlib to allow a more functional style which some prefer. If you 
> accept that a type should support iteration with a `for...in` loop, then 
> what is your basis for claiming that these extension methods are 
> "separate functionalities”?
 
 Just because you *can* express something in code doesn’t mean you should, 
 or that it’s correct. It is objectively false to say a Set has a first or 
 last object, because the objects therein have no order. You can take a 
 random object from the set and call it “first”, but that doesn’t make that 
 a correct definition of Set.first. A Set has no order, a specific 
 iteration has an “order” only in the sense that all and only the objects 
 in the set have to come out one at a time, but that doesn’t mean the Set 
 itself has an order, specifically a first or last object.
>>> 
>>> Since Set conforms to Collection, it is guaranteed that if one element of 
>>> an instance of Set comes out first one time, it'll come out first every 
>>> time from that instance. If it helps, think of Swift's Set as modeling 
>>> (imperfectly, as all models must) both a mathematical set and a multi-pass 
>>> sequence, just as Swift's Int models both an integer and a sequence of bits.
>>> 
 You’re a fan of the principal of least surprise. Tell me, which would be 
 less surprising: Set.dropFirst() actually drops a random element, or Set 
 doesn’t have a dropFirst()? And if you think dropFirst() removing an 
 element at random is not surprising, please explain why.
>>> 
>>> I think Set.dropFirst removing the first element that I observe on 
>>> iteration is the least surprising answer, because 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Jonathan Hull via swift-evolution
Ok, just to summarize our options so far (in order of effort & theoretical 
effectiveness):

1) Do nothing - This is the easiest thing to do, but it won’t fix any problems

2) Rename the elementsEqual method: (Again, fairly easy to do, and will 
hopefully reduce confusion, but doesn’t fix the underlying issue)
• lexicographicallyEquals
• elementOrderingEqual (this is my favorite of the names)
• sequentiallyEquals
• orderedEqual
• pairwiseEqual
• iterativelyEquals
I might be missing some...

3) Change the implementation of Set so that it will return the same order 
whenever it has the same elements. This solves the issue with set, but not with 
unordered sequences in general (e.g. comparing a set with the keys of a 
dictionary). Still on balance, this is my current favorite.

4) Add an UnorderedX (name to be bikeshed) protocol that defines a 
sequence/collection as unordered, which provides a method which will return a 
sequence/collection of defined order. Generic algorithms can check for 
conformance to the UnorderedX protocol, and provide different implementations 
as needed (mostly by operating on the provided sequence/collection).  The 
advantage is that generic algorithms can be made which take whether the 
sequence is ordered/unordered into account, and we don’t lose any speed. The 
downside is that you have to remember to check if it is ordered or not, and 
failing to do so may result in generic algorithms which have the current 
issues.  We could guarantee that the standard library would be correct though.

5) Add an UnorderedX protocol that defines a sequence/collection as unordered, 
takes the unordered elements and uses them to provide a partial implementation 
to Sequence/Collection where the elements have a defined order.  The advantage 
to this is that you can now build correct generic algorithms that depend on a 
stable/defined ordering that will “just work" (e.g. elementsEqual will work 
when comparing a set to the keys of a dictionary).  The disadvantage is that it 
will be a bit slower for things that don’t care about ordering (e.g. many 
things involving for-in) unless you specifically call a method that says you 
don’t care about the order.

6) Rework the Sequence protocols to account for Ordered and Unordered (e.g. 
replacing ‘first’ with ‘any’ and then adding ‘first’ back in only for ordered 
sequences).  Reworking the protocol hierarchy would be the most permanent and 
theoretically “correct” fix, but has the potential to be massively 
source-breaking.


Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Jonathan Hull via swift-evolution

> On Oct 14, 2017, at 10:48 PM, Xiaodi Wu  wrote:
>>>  That ordering can be arbitrary, but it shouldn’t leak internal 
>>> representation such that the method used to create identical things affects 
>>> the outcome of generic methods because of differences in internal 
>>> representation.
>>> 
>>> 
  It would be better to say that the iteration order is well-defined. That 
 will almost always mean documented, and usually predictable though 
 obviously e.g. RNGs and iterating in random order will not be predictable 
 by design.
 
> That's actually more semantically constrained than what Swift calls a 
> `Collection` (which requires conforming types to be multi-pass and(?) 
> finite). By contrast, Swift's `SpongeBob` protocol explicitly permits 
> conforming single-pass, infinite, and/or unordered types. 
 
 I think you’re talking about Sequence here, I’ve lost track of your 
 nonsense by now. Yes, the current Swift protocol named Sequence allows 
 unordered types. You seem to keep asserting that but not actually 
 addressing my argument, which is that allowing Sequences to be unordered 
 with the current API is undesired and actively harmful, and should 
 therefore be changed.
 
 What is harmful about it?
>>> 
>>> After thinking about it, I think the harmful bit is that unordered 
>>> sequences are leaking internal representation (In your example, this is 
>>> causing people to be surprised when two sets with identical elements are 
>>> generating different sequences/orderings based on how they were created).  
>>> You are correct when you say that this problem is even true for for-in.
>>> 
>>> I would not say it is a problem. Rather, by definition, iteration involves 
>>> retrieving one element after another; if you're allowed to do that with 
>>> Set, then the elements of a Set are observably ordered in some way. Since 
>>> it's not an OrderedSet--i.e., order doesn't matter--then the only sensible 
>>> conclusion is that the order of elements obtained in a for...in loop must 
>>> be arbitrary. If you think this is harmful, then you must believe that one 
>>> should be prohibited from iterating over an instance of Set. Otherwise, Set 
>>> is inescapably a Sequence by the Swift definition of Sequence. All 
>>> extension methods on Sequence like drop(while:) are really just 
>>> conveniences for common things that you can do with iterated access; to my 
>>> mind, they're essentially just alternative ways of spelling various 
>>> for...in loops.
>> 
>> I think an argument could be made that you shouldn’t be able to iterate over 
>> a set without first defining an ordering on it (even if that ordering is 
>> somewhat arbitrary).  Maybe we have something like a “Sequenc(e)able” 
>> protocol which defines things which can be turned into a sequence when 
>> combined with some sort of ordering.  One possible ordering could be the 
>> internal representation (At least in that case we are calling it out 
>> specifically).  If I had to say 
>> “setA.arbitraryOrder.elementsEqual(setB.arbitraryOrder)” I would definitely 
>> be less surprised when it returns false even though setA == setB.
>> 
>> Well, that's a totally different direction, then; you're arguing that `Set` 
>> and `Dictionary` should not conform to `Sequence` altogether. That's fine 
>> (it's also a direction that some of us explored off-list a while ago), but 
>> at this point in Swift's evolution, realistically, it's not within the realm 
>> of possible changes.
> 
> I am actually suggesting something slightly different.  Basically, Set and 
> Dictionary’s conformance to Collection would have a different implementation. 
>  They would conform to another protocol declaring that they are unordered. 
> That protocol would fill in part of the conformance to sequence/collection 
> using a default ordering, which is mostly arbitrary, but guaranteed to 
> produce the same ordering for the same list of elements (even across 
> collection types).  This would be safer, but a tiny bit slower than what we 
> have now (We could also potentially develop a way for collections like set to 
> amortize the cost). For those who need to recover speed, the new protocol 
> would also define a property which quickly returns a sequence/iterator using 
> the internal ordering (I arbitrarily called it .arbitraryOrder).
> 
> I believe it would not be source breaking.
> 
> That is indeed something slightly different.
> 
> In an ideal world--and my initial understanding of what you were 
> suggesting--Set and Dictionary would each have a member like `collection`, 
> which would expose the underlying data as a `SetCollection` or 
> `DictionaryCollection` that in turn would conform to `Collection`; meanwhile, 
> Set and Dictionary themselves would not offer methods such as `prefix`, or 
> indexing by subscript, which are not compatible with being unordered. For 
> those who want a 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Jonathan Hull via swift-evolution

> On Oct 15, 2017, at 3:41 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I’ll have to mull this over to see if I can come up with a coherent and 
> (more) specific requirement for what makes an Iterable a Sequence, since 
> clearly “documented” isn’t enough.  Perhaps something along the lines that 
> any two Sequences that compare equal must iterate the same.
> 
>> […]
>> Apple documentation calls this one of the "order-dependent" methods. It is 
>> surely acceptable for a type that conforms to an order-dependent protocol to 
>> have methods that are order-dependent; they do, however, have to be clearly 
>> order-dependent to avoid confusion on unordered types.
> 
> I’m not clear on what you’re trying to get across here. It seems you’re 
> saying unordered types shouldn’t have order-dependent methods, which is 
> exactly what I’ve been arguing.
> 
> No, I'm saying, essentially, that there are no truly unordered types in 
> Swift; `Set` and `Dictionary` lead double lives modeling unordered 
> collections on the one hand and ordered collections on the other. The 
> order-dependent methods can continue to exist; they just need to be clearly 
> named so that users know when they're using an instance of `Set` in the 
> manner of an unordered collection and when they're using an instance of `Set` 
> in the manner of an ordered collection.

Is the order of elements returned from Set/Dictionary guaranteed not to change 
based on implementation?  For instance, the elements of a dictionary may shift 
around as I add items, and they may be different in different runs of a program.

If we document/say that Set will always return elements in the order they were 
added, then it may prevent us from using a more efficient implementation of 
Sets in a future version of Swift.

Just to check what we are saying.  I am saying that we can’t really build 
generic algorithms on something which is undefined (because we are leaking 
implementation details, and depending on private implementation details leads 
to problems).  You are saying that the leaking of implementation details is a 
feature, not a bug… and that we should just document them and consider them 
fixed ABI?

Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 14, 2017, at 6:11 PM, Michael Ilseman via swift-evolution 
>  wrote:
> 
> I think that “match” is a word to avoid for this, as this doesn’t have 
> anything to do with pattern matching, fuzzy matching, etc., while  “equals” 
> is precisely the concept we’re using.
> 
> What about the name “sequentiallyEquals”? Highlight the fact that we’re 
> talking about sequential ordering, i.e. whatever order the sequence provides, 
> as opposed to first doing some lexicographical ordering of elements 
> themselves.
> 
> var a: Set =  [3, 1, 2]
> a.sequentiallyEquals([1,2,3]) // result depends on application of equality in 
> a (potentially-arbitrary) sequential ordering

I really like this name. 

It does make me think about .first which I now feel it should be 
.sequentiallyFirst :)

I ultimately think that these methods/properties do not make sense for 
unordered types so probably they should just be unavailable. 

> 
> Whereas I could see the following being more confusing:
> 
> var a: Set =  [3, 1, 2]
> a.lexicographicallyEquals([1,2,3]) // result depends on application of 
> equality, but what meaning does “lexicographically” convey?
> 
> It’s not immediately clear to someone new to the API that “lexicographically” 
> speaks to the nature of the sequence’s (potentially-arbitrary) order, 
> irrespective of element. It could give the false impression that it speaks to 
> some nature of the elements themselves, in this case Ints, which have an 
> obvious lexicographical ordering. I don’t know how frequent that 
> misconception would be in practice, but it does cause me to do a double-take 
> in this contrived example.
> 
> 
>> On Oct 14, 2017, at 1:04 PM, Benjamin G via swift-evolution 
>> > wrote:
>> 
>> To answer more precisely this request (which remains valid no matter the 
>> protocol hierarchy). I propose
>> 
>> "matchesSequence" ( or simply "matches" or "match", whatever is more 
>> coherent with the naming guidelines).
>> 
>> So
>> var a: [Int] = [1,2,3]
>> a.matchesSequence([1,2,3]) returns true.
>> 
>> I first thought that the verb "matching" was too heavily associated to 
>> regular expressions, but i think that it's the correct equivalent for 
>> something as general as a sequence.
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> On Fri, Oct 13, 2017 at 1:24 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> Rename Sequence.elementsEqual
>> 
>> Proposal: SE- 
>> Authors: Xiaodi Wu 
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> Introduction
>> 
>> The current behavior of Sequence.elementsEqual is potentially confusing to 
>> users given its name. Having surveyed the alternative solutions to this 
>> problem, it is proposed that the method be renamed to 
>> Sequence.lexicographicallyEquals.
>> 
>>  
>> Motivation
>> 
>> As outlined by Ole Begemann 
>> , use of 
>> Sequence.elementsEqual(_:) can lead to surprising results if the sequences 
>> compared are unordered:
>> 
>> var set1: Set = Set(1...5)
>> var set2: Set = Set((1...5).reversed())
>> 
>> set1 == set2 // true
>> set1.elementsEqual(set2) // false
>> This result does reflect the intended and documented behavior of the 
>> elementsEqual(_:) method, which performs a lexicographical elementwise 
>> comparison. That is, the method first compares set1.first to set2.first, 
>> then (if the two elements compare equal) compares the next element stored 
>> internally in set1 to the next element stored internally in set2, and so on.
>> 
>> In almost all circumstances where a set is compared to another set, or a 
>> dictionary is compared to another dictionary, users should use == instead of 
>> elementsEqual(_:).
>> 
>>  
>> Proposed
>>  solution
>> 
>> The proposed solution is the result of an iterative process of reasoning, 
>> presented here:
>> 
>> The first and most obvious solution is to remove the elementsEqual(_:) 
>> method altogether in favor of ==. This prevents its misuse. However, because 
>> elementsEqual(_:) is a generic method on Sequence, we can use it to compare 
>> an instance of UnsafeBufferPointer to an instance of [Int]. This is a 
>> useful and non-redundant feature which would be eliminated if the method is 
>> removed altogether.
>> 
>> A second solution  is to create 
>> overloads that forbid the use of the elementsEqual(_:) method specifically 
>> in non-generic code. This would prevent misuse in non-generic code; however, 
>> it would also forbid legitimate mixed-type 

Re: [swift-evolution] commas optional

2017-10-15 Thread Mike Kluev via swift-evolution
On 16 October 2017 at 01:20, Dave Yost  wrote:

> Nuance:
>
> Compiler says:
> Expression following ‘return’ is treated as an argument of the 'return
> '.
> unless foo() is indented by at least one space. Then there is no
> complaint.
>

to have more fun try this:

 return
 foo()  // visually no indent, warning

 return
 foo()  // no warning. but visually it is the same as above.

where n is the same number of spaces as in your tab-character

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


Re: [swift-evolution] commas optional

2017-10-15 Thread Dave Yost via swift-evolution
Nuance:

Compiler says:
Expression following ‘return’ is treated as an argument of the 'return'.
unless foo() is indented by at least one space. Then there is no complaint.

> On 2017-10-15, at 4:32 PM, Dave Yost  wrote:
> 
> Very cool!
> 
> func foo() -> Int { return 17 }
> 
> func bug1() -> Int {
> return
> foo()  // Compiler says: Expression following ‘return'
>//is treated as an argument of the 'return'.
> }
> 
> var x = 0
> 
> func bug2() {
> return x = 4 // not even a warning – should be an error
> }
> 
> print(bug1()) // prints 17
> bug2()
> 
> Dave
> 
> bug1() suggests that return be one of perhaps a set of special cases where 
> line wrap is illegal.
> 
> bug2() is a compiler bug IMO.
> 
>> On 2017-10-15, at 8:32 AM, Mike Kluev via swift-evolution 
>> > wrote:
>> 
>> on Date: Fri, 13 Oct 2017 20:21:22 -0700 Chris Lattner > > wrote:
>> 
>> We already have whitespace sensitive rules to handle this.  There is no 
>> fundamental implementation difference that I see between separating the 
>> elements of lists (which are expressions) and the elements of statements 
>> (which can be expressions):
>> 
>> func foo() -> Int { … }
>> 
>> func statements() {
>>   foo()
>>   foo()
>> }
>> 
>> let list = [
>>   foo()
>>   foo()
>> ]
>> 
>> i was beaten by these optional semicolons...
>> 
>> override func viewDidLoad() {
>>  super.viewDidLoad()
>>  return  // put it ad-hoc to temporarily circumvent the rest of the code
>>  
>>  someView = SomeView(frame: view.bounds) // *
>>  view.addSubview(someView)   // **
>>  ...
>> }
>>  
>> so i put that ad-hoc return statement to circumvent the rest of the code 
>> temporarily. of course i didn't put a semicolon after "return" as that skill 
>> was long lost. to my surprise the app crashed, and nowhere else but in the 
>> code that i thought was disabled...
>> 
>> further investigation showed that in this case compiler was treating the 
>> statement after return which happened to have the matching type “Void” as 
>> part of return statement.
>> 
>> should the function return type was, say, Int - that wouldn’t happen. or 
>> should the next statement was of a different type - that wouldn’t happen. in 
>> this case i was just “lucky”. here semantic information (matching vs non 
>> matching types) is clearly "aiding" syntax parsing and sometimes it leads to 
>> a surprising results.
>> 
>> there was a warning on the * line:
>> “warning: expression following 'return' is treated as an argument of the 
>> 'return’”
>> 
>> and another warning on the ** line:
>> “warning: code after 'return' will never be executed”
>> 
>> as i was prepared to get the warning about the code being unused in the 
>> first place, i didn’t pay too much attention to the exact wording of that 
>> warning... and was beaten by it.
>> 
>> Mike
>> 
>> ___
>> 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] commas optional

2017-10-15 Thread Dave Yost via swift-evolution
Very cool!

func foo() -> Int { return 17 }

func bug1() -> Int {
return
foo()  // Compiler says: Expression following ‘return'
   //is treated as an argument of the 'return'.
}

var x = 0

func bug2() {
return x = 4 // not even a warning – should be an error
}

print(bug1()) // prints 17
bug2()

Dave

bug1() suggests that return be one of perhaps a set of special cases where line 
wrap is illegal.

bug2() is a compiler bug IMO.

> On 2017-10-15, at 8:32 AM, Mike Kluev via swift-evolution 
>  wrote:
> 
> on Date: Fri, 13 Oct 2017 20:21:22 -0700 Chris Lattner  > wrote:
> 
> We already have whitespace sensitive rules to handle this.  There is no 
> fundamental implementation difference that I see between separating the 
> elements of lists (which are expressions) and the elements of statements 
> (which can be expressions):
> 
> func foo() -> Int { … }
> 
> func statements() {
>   foo()
>   foo()
> }
> 
> let list = [
>   foo()
>   foo()
> ]
> 
> i was beaten by these optional semicolons...
> 
> override func viewDidLoad() {
>   super.viewDidLoad()
>   return  // put it ad-hoc to temporarily circumvent the rest of the code
>   
>   someView = SomeView(frame: view.bounds) // *
>   view.addSubview(someView)   // **
>   ...
> }
>   
> so i put that ad-hoc return statement to circumvent the rest of the code 
> temporarily. of course i didn't put a semicolon after "return" as that skill 
> was long lost. to my surprise the app crashed, and nowhere else but in the 
> code that i thought was disabled...
> 
> further investigation showed that in this case compiler was treating the 
> statement after return which happened to have the matching type “Void” as 
> part of return statement.
> 
> should the function return type was, say, Int - that wouldn’t happen. or 
> should the next statement was of a different type - that wouldn’t happen. in 
> this case i was just “lucky”. here semantic information (matching vs non 
> matching types) is clearly "aiding" syntax parsing and sometimes it leads to 
> a surprising results.
> 
> there was a warning on the * line:
> “warning: expression following 'return' is treated as an argument of the 
> 'return’”
> 
> and another warning on the ** line:
> “warning: code after 'return' will never be executed”
> 
> as i was prepared to get the warning about the code being unused in the first 
> place, i didn’t pay too much attention to the exact wording of that 
> warning... and was beaten by it.
> 
> Mike
> 
> ___
> 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] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 2:39 PM, Kevin Nattinger 
wrote:

> […]
> Swift's Sequence protocol does not require the order of iteration to
> "convey any meaning"; it doesn't even require it to be deterministic.
>
>
> And that’s EXACTLY why none of the functions on Sequence should rely on
> the order conveying meaning.  `ElementsEqual` (for example) DOES rely on
> the order of iteration conveying a meaning not required by the protocol,
> and renaming it `lexicographicallyEquals` does not change that fact. Either
> Sequence needs to require a meaningful order or `elementsEqual` should be
> moved to a protocol that does.
>

What's your basis for saying that `elementsEqual` requires orders of
iteration that "convey a meaning"? It merely answers the question of
whether iterating over `a` is substitutable for iterating over `b`, a
question applicable to instances of any type which offers iterated access.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 2:32 PM, Kevin Nattinger 
wrote:

> […]
> Sets, as a mathematical concept, have no intrinsic order. However,
> instances of `Set`, which can be iterated over, *do* have at least one
> order which can be said to be intrinsic in the following sense: as long as
> iteration is possible, no API design can prevent that order from being
> observed and associated with the instance. Put another way, if you can use
> an instance of a type in a for...in loop, intrinsic to that functionality
> is a publicly visible order.
>
>
> You keep saying this, I keep saying it’s only a technical “order” that is
> an implementation detail
>

You keep saying it's an implementation detail, which it emphatically is
*not*. It's a *public guarantee* by the protocol that you can use an
instance of `Set` in a `for...in` loop, thereby exposing a publicly visible
order. An implementation detail is something that could go away with an
alternative implementation. By contrast, no implementation that permits an
instance of `Set` being iterated over in a `for...in` loop can avoid
exposing at least one publicly visible order, because it's not a matter of
implementation. Put another way, by allowing iteration, a type necessarily
exposes at least one publicly visible order and thereby models a sequence
in at least one way.


> and can’t be relied upon for anything and so we shouldn’t provide methods
> that rely on it. I think this part of the discussion has reached the “agree
> to disagree” stage.
>
> […]
>>
> You’re a fan of the principal of least surprise. Tell me, which would be
>> less surprising: Set.dropFirst() actually drops a random element, or Set
>> doesn’t have a dropFirst()? And if you think dropFirst() removing an
>> element at random is not surprising, please explain why.
>>
>
> I think Set.dropFirst removing the first element that I observe on
> iteration is the least surprising answer, because Swift tells me that the
> stdlib Set models a set but that it is also a sequence.
>
>
> Your logic is backwards. You’re saying it’s “least surprising” because
> that’s how it’s currently implemented, not that it should be implemented
> that way because it’s least surprising.
>

No, I'm saying it's least surprising because any type that supports
iterated access thereby exposes an order--not as an implementation detail
but as a matter of public API--and in the absence of any other order,
"first" must refer to that order so exposed.

> […]


>> And that’s PRECISELY why lexicographicallyEqual does not make sense to
>> apply to unordered sets. There is no lexicographical comparison possible,
>> so why do you keep insisting they should have a method that falsely claims
>> to lexicographically compare them?
>>
>
> I agree! It doesn't make sense if no comparison is possible! But Swift
> tells me that a `Set` is a `Sequence`!
>
>
> You keep making the circular argument that a Set should do things because
> it currently does them. If you want to argue against changing things, argue
> that things shouldn’t be changed, not that the current implementation is
> correct because it is the current implementation.
>

No, I'm arguing that `Set`, by supporting iterated access, is not wrong to
conform to a protocol called `Sequence` because it does have an intrinsic
and publicly observable order, which is not an accident of a particular
implementation but is inherent to any type that supports iterated access.
Now, whether it's the *best choice* to conform `Set` to `Sequence` and
offer order-dependent functions is a matter of taste, but it isn't *wrong*.

> […]
> You will always have to account for this possibility, because Swift's
> `Equatable` explicitly allows "special values" to be not equal to
> themselves. This is, at least in part, in order to accommodate the IEEE
> decree that NaN != NaN:
>
>
> ```
> let x = [Double.nan]
> x.elementsEqual(x) // false
> ```
>
>
> NaN is special, one-shot and unordered sequences are not. Unless you think
> that all unordered and single-pass sequences should compare false for
> `elementsEqual`, this is irrelevant for any sequence that doesn’t contain
> NaN and well-defined (false) for any that does.
>

Certainly, not all single-pass sequences should compare false to
themselves, but some should: for instance, an infinite single-pass stream
of all 1's should compare true to itself, but an infinite single-pass
stream of alternating 1's and 0's should compare false to itself. If you
write generic code that calls `elementsEqual`, it is pervasively incorrect
to test for identity by assuming that elementsEqual will return true on
reflexive comparison. NaN is only one of many reasons why such code would
blow up.


>
> Changing this behavior is way beyond the scope of this thread (and has
> been the topic of hours (actually, weeks and weeks) of fun on this list
> previously).
>
>
> Yes, I’ve seen the discussion on NaN and Comparable. It’s not the same
> discussion.
>
> […]
>
>> It 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Michael Ilseman via swift-evolution
That is what == does: 
https://github.com/apple/swift/blob/master/stdlib/public/core/HashedCollections.swift.gyb#L1267

> On Oct 15, 2017, at 1:25 PM, C. Keith Ray via swift-evolution 
>  wrote:
> 
> Why not use an equals Implementation that doesn't rely on order?
> 
> Something like this (which doesn't compile in my iPad playground). If two 
> sets have the same number of elements, and every element in one can be found 
> in the other, they are equal, otherwise they are not equal.
> 
> protocol Set  {
> static func == (lhs: Self, rhs: Self) {
> guard lhs.count == rhs.count else { return false }
> for x in lhs {
> if !rhs.contains(x) { return false }
> }
> return true
> }
> }
> 
> --
> C. Keith Ray
> 
> * https://leanpub.com/wepntk  <- buy my book?
> * http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf 
> 
> * http://agilesolutionspace.blogspot.com/ 
> 
> 
> On Oct 15, 2017, at 12:40 PM, Kevin Nattinger via swift-evolution 
> > wrote:
> 
>>> […]
>>> Swift's Sequence protocol does not require the order of iteration to 
>>> "convey any meaning"; it doesn't even require it to be deterministic.
>>> 
>> 
>> And that’s EXACTLY why none of the functions on Sequence should rely on the 
>> order conveying meaning.  `ElementsEqual` (for example) DOES rely on the 
>> order of iteration conveying a meaning not required by the protocol, and 
>> renaming it `lexicographicallyEquals` does not change that fact. Either 
>> Sequence needs to require a meaningful order or `elementsEqual` should be 
>> moved to a protocol that does.
>> 
>> ___
>> 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] Rename Sequence.elementsEqual

2017-10-15 Thread C. Keith Ray via swift-evolution
Why not use an equals Implementation that doesn't rely on order?

Something like this (which doesn't compile in my iPad playground). If two sets 
have the same number of elements, and every element in one can be found in the 
other, they are equal, otherwise they are not equal.

protocol Set  {
static func == (lhs: Self, rhs: Self) {
guard lhs.count == rhs.count else { return false }
for x in lhs {
if !rhs.contains(x) { return false }
}
return true
}
}

--
C. Keith Ray

* https://leanpub.com/wepntk <- buy my book?
* http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf
* http://agilesolutionspace.blogspot.com/

> On Oct 15, 2017, at 12:40 PM, Kevin Nattinger via swift-evolution 
>  wrote:
> 
>> […]
>> Swift's Sequence protocol does not require the order of iteration to "convey 
>> any meaning"; it doesn't even require it to be deterministic.
>> 
> 
> And that’s EXACTLY why none of the functions on Sequence should rely on the 
> order conveying meaning.  `ElementsEqual` (for example) DOES rely on the 
> order of iteration conveying a meaning not required by the protocol, and 
> renaming it `lexicographicallyEquals` does not change that fact. Either 
> Sequence needs to require a meaningful order or `elementsEqual` should be 
> moved to a protocol that does.
> 
> ___
> 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] /*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

2017-10-15 Thread C. Keith Ray via swift-evolution
+1 to "discardable" or "@discardable" next to the result type.

] A simple “discardable” would be great. If the result is Bool and 
] “discardable” is placed right in front of it, it’s not only more readable 
] but also eliminates the redundant word “Result”. Also no at sign is great.

--
C. Keith Ray

* https://leanpub.com/wepntk <- buy my book?
* http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf
* http://agilesolutionspace.blogspot.com/

> On Oct 15, 2017, at 1:04 PM, Rudolf Adamkovič via swift-evolution 
>  wrote:
> 
> A simple “discardable” would be great. If the result is Bool and 
> “discardable” is placed right in front of it, it’s not only more readable but 
> also eliminates the redundant word “Result”. Also no at sign is great.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] /*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

2017-10-15 Thread Rudolf Adamkovič via swift-evolution
+1

A simple “discardable” would be great. If the result is Bool and “discardable” 
is placed right in front of it, it’s not only more readable but also eliminates 
the redundant word “Result”. Also no at sign is great.

Plus, this is super-straightforward to convert for the compiler when upgrading.

R+

Sent from my iPhone

> On 15 Oct 2017, at 15:52, Mike Kluev via swift-evolution 
>  wrote:
> 
>> On 15 October 2017 at 14:23, Geordie Jay  wrote:
>> Hi Mike,
>> 
>> 2017-10-15 14:55 GMT+02:00 Mike Kluev :
 On 15 October 2017 at 13:35, Geordie Jay  wrote:
 Also we're not talking about whether the Bool itself is discardable. For 
 example, it makes no sense to write:
 
 let something: discardable Bool = true
>>> 
>>> you can't write this either:
>>> 
>>> let something: inout Bool = true
>>> 
>>> that doesn't mean "inout" should be "@inputOutput" before the parameter 
>>> name in function signature.
>> 
>> This is a different case: inout is an annotation on argument types (of which 
>> there can be many).
> 
> i mean:
> 
> @discardableResult func foo(@inputOutput x: Int, @inputOutput y: Float) -> 
> Bool 
> 
> vs:
> 
> func goo(x: inout Int, y: inout y) -> discardable Bool
> 
> i deliberately mixed the current @discardableResult syntax with a 
> hypothetical "consistent" @inputOutput syntax to make my point more clear. to 
> me these use cases are virtually the same, and syntax shall be consistent 
> among them.
>  
>> I don't understand what you're saying here. "Now in swift 0.0"? The first 
>> public version of Swift had this same functionality in its same form, with 
>> the name @warn_unused_result. The current version is just reversed, which to 
>> me is a logical change.
> 
> in other words: "if we didn't have swift already what would I do" kind of 
> test. similar to the one that we already officially use: "if it wasn't done 
> already, would we do it now" to prune rarely used language constructs.
> 
> remember the evolution of the "inout" keyword:
> 
> (inout x: Int)  --->  "var parameters dropped" + (x: inout Int)
> 
> similarly, it's not unimaginable to consider this evolution as well:
> 
> "@warn_unused_result func" --> "@discardableResult func" --> "func foo() -> 
> discardable Bool"
>  
>>> throwing func foo() -> Bool
>> 
>> I personally like that syntax, because that's exactly how I talk about such 
>> a function. "oh that's a throwing function so you need to call it with try".
> 
> you are the first who +1-ed it so far, so we now have +2 in total for 
> "throwing".
>  
>> As an extension to that, I'd also say "you can call that function without a 
>> preceding variable assignment because it has a discardable result". I would 
>> never say "this function returns a discardable boolean" because that just 
>> doesn't match my mental model of what's going on. To me, it's the function 
>> whose return value can be discarded — in theory it has nothing to do with 
>> the result itself. But it's quite possible I'm in the minority here.
> 
> to me it's trivial:
> 
> func foo() -> Bool- means "function foo returning result of type Bool"
> 
> ditto:
> 
> func foo() -> discardable Bool- means "function foo returning result of 
> type Bool that can be unused by the caller"
> 
> very compatible with:
> 
> foo(x: inout Bool)- means input / output parameter x that is of type Bool
> 
> if you don't complain about the latter (like: "how come Bool is input 
> output?! it is the parameter that is input / output, not the Bool itself !!!" 
> or, similarly: "how come the function returns type Never? the function just 
> never returns but the type shall be Void !!!") then I don't see why you don't 
> accept the former.
> 
>> But it's quite possible I'm in the minority here.
> 
> as a matter of fact, so far it looks I am :)
> 
> Mike
> 
> ___
> 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] /*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

2017-10-15 Thread Jean-Daniel via swift-evolution


> Le 15 oct. 2017 à 15:52, Mike Kluev via swift-evolution 
>  a écrit :
> 
> On 15 October 2017 at 14:23, Geordie Jay  > wrote:
> Hi Mike,
> 
> 2017-10-15 14:55 GMT+02:00 Mike Kluev  >:
> On 15 October 2017 at 13:35, Geordie Jay  > wrote:
> Also we're not talking about whether the Bool itself is discardable. For 
> example, it makes no sense to write:
> 
> let something: discardable Bool = true
> 
> you can't write this either:
> 
> let something: inout Bool = true
> 
> that doesn't mean "inout" should be "@inputOutput" before the parameter name 
> in function signature.
> 
> This is a different case: inout is an annotation on argument types (of which 
> there can be many).
> 
> i mean:
> 
> @discardableResult func foo(@inputOutput x: Int, @inputOutput y: Float) -> 
> Bool 
> 
> vs:
> 
> func goo(x: inout Int, y: inout y) -> discardable Bool
> 

inout and discardableResult are fundamentally different. Inout change the 
calling convention and the way the parameter is passed. discardableResult is 
just an annotation to help catching bad function usage by warning the developer 
about it.


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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Kevin Nattinger via swift-evolution
> […]
> Swift's Sequence protocol does not require the order of iteration to "convey 
> any meaning"; it doesn't even require it to be deterministic.
> 

And that’s EXACTLY why none of the functions on Sequence should rely on the 
order conveying meaning.  `ElementsEqual` (for example) DOES rely on the order 
of iteration conveying a meaning not required by the protocol, and renaming it 
`lexicographicallyEquals` does not change that fact. Either Sequence needs to 
require a meaningful order or `elementsEqual` should be moved to a protocol 
that does.

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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Kevin Nattinger via swift-evolution
> […]
> Sets, as a mathematical concept, have no intrinsic order. However, instances 
> of `Set`, which can be iterated over, *do* have at least one order which can 
> be said to be intrinsic in the following sense: as long as iteration is 
> possible, no API design can prevent that order from being observed and 
> associated with the instance. Put another way, if you can use an instance of 
> a type in a for...in loop, intrinsic to that functionality is a publicly 
> visible order.

You keep saying this, I keep saying it’s only a technical “order” that is an 
implementation detail and can’t be relied upon for anything and so we shouldn’t 
provide methods that rely on it. I think this part of the discussion has 
reached the “agree to disagree” stage.

> […]
> You’re a fan of the principal of least surprise. Tell me, which would be less 
> surprising: Set.dropFirst() actually drops a random element, or Set doesn’t 
> have a dropFirst()? And if you think dropFirst() removing an element at 
> random is not surprising, please explain why.
> 
> I think Set.dropFirst removing the first element that I observe on iteration 
> is the least surprising answer, because Swift tells me that the stdlib Set 
> models a set but that it is also a sequence.

Your logic is backwards. You’re saying it’s “least surprising” because that’s 
how it’s currently implemented, not that it should be implemented that way 
because it’s least surprising.

 […]
> 
> And that’s PRECISELY why lexicographicallyEqual does not make sense to apply 
> to unordered sets. There is no lexicographical comparison possible, so why do 
> you keep insisting they should have a method that falsely claims to 
> lexicographically compare them?
> 
> I agree! It doesn't make sense if no comparison is possible! But Swift tells 
> me that a `Set` is a `Sequence`!

You keep making the circular argument that a Set should do things because it 
currently does them. If you want to argue against changing things, argue that 
things shouldn’t be changed, not that the current implementation is correct 
because it is the current implementation.

> […]
> You will always have to account for this possibility, because Swift's 
> `Equatable` explicitly allows "special values" to be not equal to themselves. 
> This is, at least in part, in order to accommodate the IEEE decree that NaN 
> != NaN:

> 
> ```
> let x = [Double.nan]
> x.elementsEqual(x) // false
> ```

NaN is special, one-shot and unordered sequences are not. Unless you think that 
all unordered and single-pass sequences should compare false for 
`elementsEqual`, this is irrelevant for any sequence that doesn’t contain NaN 
and well-defined (false) for any that does.

> Changing this behavior is way beyond the scope of this thread (and has been 
> the topic of hours (actually, weeks and weeks) of fun on this list 
> previously).

Yes, I’ve seen the discussion on NaN and Comparable. It’s not the same 
discussion.

> […]
>> It would be better to say that the iteration order is well-defined. That 
>> will almost always mean documented, and usually predictable though obviously 
>> e.g. RNGs and iterating in random order will not be predictable by design.
> 
> Wouldn't it then suffice to document, say, that a set's iteration order is 
> the insertion order?

Now this actually gave me pause. I guess it does match what I said, but I still 
take issue with the fact that two Sets could compare `==` but not 
`elementsEqual`. I think that defining iteration order as insertion order adds 
a piece of publicly documented state that goes beyond what a Set really is. 
What you describe is really an OrderedSet, just without the random-access 
manipulation. I’ll have to mull this over to see if I can come up with a 
coherent and (more) specific requirement for what makes an Iterable a Sequence, 
since clearly “documented” isn’t enough.  Perhaps something along the lines 
that any two Sequences that compare equal must iterate the same.

> […]
> Apple documentation calls this one of the "order-dependent" methods. It is 
> surely acceptable for a type that conforms to an order-dependent protocol to 
> have methods that are order-dependent; they do, however, have to be clearly 
> order-dependent to avoid confusion on unordered types.

I’m not clear on what you’re trying to get across here. It seems you’re saying 
unordered types shouldn’t have order-dependent methods, which is exactly what 
I’ve been arguing.

>  [...]
> Then there are all the methods that imply a specific order of iteration. If 
> the “sequence” is unordered, who knows what you’ll get? It is incredibly easy 
> for an engineer to write a method that implicitly relies on a passed sequence 
> being intrinsically ordered and another engineer to pass it an unordered 
> “sequence.”  The first engineer could neglect to document the dependency, or 
> even not notice it; or the second engineer could just fail to read the 
> documentation thoroughly enough.  There is 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 14:14 Thorsten Seitz  wrote:

> Am 15.10.2017 um 10:38 schrieb Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org>:
>
> On Sun, Oct 15, 2017 at 2:29 AM, Kevin Nattinger 
> wrote:
>
>>
>> On Oct 14, 2017, at 7:54 PM, Xiaodi Wu  wrote:
>>
>> On Sat, Oct 14, 2017 at 6:17 PM, Kevin Nattinger 
>> wrote:
>>
>>> […]
 * A Swift `Sequence` is, to put it simplistically, a thing that can be
 iterated over in a `for...in` loop. If it would make you happy, for the
 rest of the discussion, let's suppose we called the protocol `ForLoopable`
 instead of `Sequence`.


 ForLoopable is so ugly. Since we’re just iterating over the elements,
 how about, oh, say, `Iterable`? Hey, that looks familiar.

>>>
>>> I'm not trying to bikeshed the name of `Sequence`. I'm picking an
>>> intentionally unwieldy name for the purposes of discussing the semantics of
>>> this particular protocol. The point is that the underlying issue has
>>> nothing to do with the name; it can be `Iterable` or it can be `SpongeBob`
>>> for all I care.
>>>
>>>
>>> I’m not trying to bikeshed the name either, The underlying issue is that
>>> (what is currently) Sequence actually encompasses two separate
>>> functionalities, and those functionalities need to be separated with their
>>> separate semantic requirements documented. “Sequence: Iterable,”
>>> “OrderedSequence: Sequence,” “SpongeBob: ForLoopable,” the names are 100%
>>> irrelevant at this point; what’s important is that one is not necessarily
>>> ordered and the other guarantees an order.
>>>
>>>
>>
>> What are the "two separate functionalities”?
>>
>>
>> Iteration, with convenience methods that don’t imply or rely on an order
>> that may not be there; and convenience methods applicable to sequences that
>> do have an intrinsic order.
>>
>
> Sets, as a mathematical concept, have no intrinsic order. However,
> instances of `Set`, which can be iterated over, *do* have at least one
> order which can be said to be intrinsic in the following sense: as long as
> iteration is possible, no API design can prevent that order from being
> observed and associated with the instance. Put another way, if you can use
> an instance of a type in a for...in loop, intrinsic to that functionality
> is a publicly visible order.
>
>
> I disagree. Sets are value types, therefore two instances of `Set` are
> equal if they contain the same elements. An intrinsic order should
> therefore only depend on the elements contained and should be the same for
> two instances of `Set` which are equal.
> This is not the case, though, as you can easily check in a playground by
> looking at Set([1,2,3,4,5,6]) and Set([6,5,4,3,2,1]) which represent the
> same value and are equal but do *not* have the same order.
>
>
>
>
>> All the extension methods on Sequence are ways of spelling things that
>> you can write in a few lines of code using a `for...in` loop; they're in
>> the stdlib to allow a more functional style which some prefer. If you
>> accept that a type should support iteration with a `for...in` loop, then
>> what is your basis for claiming that these extension methods are "separate
>> functionalities”?
>>
>>
>> Just because you *can* express something in code doesn’t mean you should,
>> or that it’s correct. It is objectively false to say a Set has a first or
>> last object, because the objects therein have no order. You can take a
>> random object from the set and call it “first”, but that doesn’t make that
>> a correct definition of Set.first. A Set has no order, a specific iteration
>> has an “order” only in the sense that all and only the objects in the set
>> have to come out one at a time, but that doesn’t mean the Set itself has an
>> order, specifically a first or last object.
>>
>
> Since Set conforms to Collection, it is guaranteed that if one element of
> an instance of Set comes out first one time, it'll come out first every
> time from that instance. If it helps, think of Swift's Set as modeling
> (imperfectly, as all models must) both a mathematical set and a multi-pass
> sequence, just as Swift's Int models both an integer and a sequence of bits.
>
> You’re a fan of the principal of least surprise. Tell me, which would be
>> less surprising: Set.dropFirst() actually drops a random element, or Set
>> doesn’t have a dropFirst()? And if you think dropFirst() removing an
>> element at random is not surprising, please explain why.
>>
>
> I think Set.dropFirst removing the first element that I observe on
> iteration is the least surprising answer, because Swift tells me that the
> stdlib Set models a set but that it is also a sequence.
>
>
> The latter is exactly the problem Kevin did point out. A Set is an
> Iterable (in the sense that I can iterate over its elements with the order
> being a meaningless random side effect) but it is *not* a Sequence (in the
> sense that 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Thorsten Seitz via swift-evolution

> Am 15.10.2017 um 10:38 schrieb Xiaodi Wu via swift-evolution 
> :
> 
> On Sun, Oct 15, 2017 at 2:29 AM, Kevin Nattinger  > wrote:
> 
>> On Oct 14, 2017, at 7:54 PM, Xiaodi Wu > > wrote:
>> 
>> On Sat, Oct 14, 2017 at 6:17 PM, Kevin Nattinger > > wrote:
 […]
 * A Swift `Sequence` is, to put it simplistically, a thing that can be 
 iterated over in a `for...in` loop. If it would make you happy, for the 
 rest of the discussion, let's suppose we called the protocol `ForLoopable` 
 instead of `Sequence`.
>>> 
>>> ForLoopable is so ugly. Since we’re just iterating over the elements, how 
>>> about, oh, say, `Iterable`? Hey, that looks familiar.
>>> 
>>> I'm not trying to bikeshed the name of `Sequence`. I'm picking an 
>>> intentionally unwieldy name for the purposes of discussing the semantics of 
>>> this particular protocol. The point is that the underlying issue has 
>>> nothing to do with the name; it can be `Iterable` or it can be `SpongeBob` 
>>> for all I care.
>> 
>> I’m not trying to bikeshed the name either, The underlying issue is that 
>> (what is currently) Sequence actually encompasses two separate 
>> functionalities, and those functionalities need to be separated with their 
>> separate semantic requirements documented. “Sequence: Iterable,” 
>> “OrderedSequence: Sequence,” “SpongeBob: ForLoopable,” the names are 100% 
>> irrelevant at this point; what’s important is that one is not necessarily 
>> ordered and the other guarantees an order.
>>  
>> 
>> What are the "two separate functionalities”?
> 
> Iteration, with convenience methods that don’t imply or rely on an order that 
> may not be there; and convenience methods applicable to sequences that do 
> have an intrinsic order.
> 
> Sets, as a mathematical concept, have no intrinsic order. However, instances 
> of `Set`, which can be iterated over, *do* have at least one order which can 
> be said to be intrinsic in the following sense: as long as iteration is 
> possible, no API design can prevent that order from being observed and 
> associated with the instance. Put another way, if you can use an instance of 
> a type in a for...in loop, intrinsic to that functionality is a publicly 
> visible order.

I disagree. Sets are value types, therefore two instances of `Set` are equal if 
they contain the same elements. An intrinsic order should therefore only depend 
on the elements contained and should be the same for two instances of `Set` 
which are equal.
This is not the case, though, as you can easily check in a playground by 
looking at Set([1,2,3,4,5,6]) and Set([6,5,4,3,2,1]) which represent the same 
value and are equal but do *not* have the same order.


> 
> 
>> All the extension methods on Sequence are ways of spelling things that you 
>> can write in a few lines of code using a `for...in` loop; they're in the 
>> stdlib to allow a more functional style which some prefer. If you accept 
>> that a type should support iteration with a `for...in` loop, then what is 
>> your basis for claiming that these extension methods are "separate 
>> functionalities”?
> 
> Just because you *can* express something in code doesn’t mean you should, or 
> that it’s correct. It is objectively false to say a Set has a first or last 
> object, because the objects therein have no order. You can take a random 
> object from the set and call it “first”, but that doesn’t make that a correct 
> definition of Set.first. A Set has no order, a specific iteration has an 
> “order” only in the sense that all and only the objects in the set have to 
> come out one at a time, but that doesn’t mean the Set itself has an order, 
> specifically a first or last object.
> 
> Since Set conforms to Collection, it is guaranteed that if one element of an 
> instance of Set comes out first one time, it'll come out first every time 
> from that instance. If it helps, think of Swift's Set as modeling 
> (imperfectly, as all models must) both a mathematical set and a multi-pass 
> sequence, just as Swift's Int models both an integer and a sequence of bits.
> 
> You’re a fan of the principal of least surprise. Tell me, which would be less 
> surprising: Set.dropFirst() actually drops a random element, or Set doesn’t 
> have a dropFirst()? And if you think dropFirst() removing an element at 
> random is not surprising, please explain why.
> 
> I think Set.dropFirst removing the first element that I observe on iteration 
> is the least surprising answer, because Swift tells me that the stdlib Set 
> models a set but that it is also a sequence.

The latter is exactly the problem Kevin did point out. A Set is an Iterable (in 
the sense that I can iterate over its elements with the order being a 
meaningless random side effect) but it is *not* a Sequence (in the sense that 
the order 

Re: [swift-evolution] commas optional

2017-10-15 Thread Mike Kluev via swift-evolution
on Date: Fri, 13 Oct 2017 20:21:22 -0700 Chris Lattner 
wrote:

We already have whitespace sensitive rules to handle this.  There is no
> fundamental implementation difference that I see between separating the
> elements of lists (which are expressions) and the elements of statements
> (which can be expressions):
>
> func foo() -> Int { … }
>
> func statements() {
>   foo()
>   foo()
> }
>
> let list = [
>   foo()
>   foo()
> ]
>

i was beaten by these optional semicolons...

override func viewDidLoad() {
super.viewDidLoad()
return // put it ad-hoc to temporarily circumvent the rest of the code
someView = SomeView(frame: view.bounds) // *
view.addSubview(someView) // **
...
}
so i put that ad-hoc return statement to circumvent the rest of the code
temporarily. of course i didn't put a semicolon after "return" as that
skill was long lost. to my surprise the app crashed, and nowhere else but
in the code that i thought was disabled...

further investigation showed that in this case compiler was treating the
statement after return which happened to have the matching type “Void” as
part of return statement.

should the function return type was, say, Int - that wouldn’t happen. or
should the next statement was of a different type - that wouldn’t happen.
in this case i was just “lucky”. here semantic information (matching vs non
matching types) is clearly "aiding" syntax parsing and sometimes it leads
to a surprising results.

there was a warning on the * line:
“warning: expression following 'return' is treated as an argument of the
'return’”

and another warning on the ** line:
“warning: code after 'return' will never be executed”

as i was prepared to get the warning about the code being unused in the
first place, i didn’t pay too much attention to the exact wording of that
warning... and was beaten by it.

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


Re: [swift-evolution] /*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

2017-10-15 Thread Mike Kluev via swift-evolution
On 15 October 2017 at 14:23, Geordie Jay  wrote:

> Hi Mike,
>
> 2017-10-15 14:55 GMT+02:00 Mike Kluev :
>
>> On 15 October 2017 at 13:35, Geordie Jay  wrote:
>>
>>> Also we're not talking about whether the Bool itself is discardable. For
>>> example, it makes no sense to write:
>>>
>>> *let something: discardable Bool = true*
>>>
>>
>> you can't write this either:
>>
>> let something: inout Bool = true
>>
>> that doesn't mean "inout" should be "@inputOutput" before the parameter
>> name in function signature.
>>
>
> This is a different case: inout is an annotation on argument types (of
> which there can be many).
>

i mean:

@discardableResult func foo(@inputOutput x: Int, @inputOutput y: Float) ->
Bool

vs:

func goo(x: inout Int, y: inout y) -> discardable Bool

i deliberately mixed the current @discardableResult syntax with a
hypothetical "consistent" @inputOutput syntax to make my point more clear.
to me these use cases are virtually the same, and syntax shall be
consistent among them.


> I don't understand what you're saying here. "Now in swift 0.0"? The first
> public version of Swift had this same functionality in its same form, with
> the name @warn_unused_result. The current version is just reversed, which
> to me is a logical change.
>

in other words: "if we didn't have swift already what would I do" kind of
test. similar to the one that we already officially use: "if it wasn't done
already, would we do it now" to prune rarely used language constructs.

remember the evolution of the "inout" keyword:

(inout x: Int)  --->  "var parameters dropped" + (x: inout Int)

similarly, it's not unimaginable to consider this evolution as well:

"@warn_unused_result func" --> "@discardableResult func" --> "func foo() ->
discardable Bool"


> throwing func foo() -> Bool
>>
>
> I personally like that syntax, because that's exactly how I *talk* about
> such a function. "oh that's a throwing function so you need to call it with
> *try*".
>

you are the first who +1-ed it so far, so we now have +2 in total for
"throwing".


> As an extension to that, I'd also say "you can call that function without
> a preceding variable assignment because it has a discardable result". I
> would never say "this function returns a discardable boolean" because that
> just doesn't match my mental model of what's going on. To me, it's the
> *function* whose return value can be discarded — in theory it has nothing
> to do with the result itself. But it's quite possible I'm in the minority
> here.
>

to me it's trivial:

func foo() -> Bool- means "function foo returning result of type Bool"

ditto:

func foo() -> discardable Bool- means "function foo returning result of
type Bool that can be unused by the caller"

very compatible with:

foo(x: inout Bool)- means input / output parameter x that is of type
Bool

if you don't complain about the latter (like: "how come Bool is input
output?! it is the parameter that is input / output, not the Bool itself
!!!" or, similarly: "how come the function returns type Never? the function
just never returns but the type shall be Void !!!") then I don't see why
you don't accept the former.

But it's quite possible I'm in the minority here.
>

as a matter of fact, so far it looks I am :)

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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Benjamin G via swift-evolution
On Sat, Oct 14, 2017 at 3:45 AM, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > That is reflected in the fact that over half the methods in the main
> Sequence definition* make no sense and are not well-defined unless there is
> a well-defined order to the sequence itself. What does it even mean to
> `dropFirst()` in a Set?
>
> It means to skip the first element the set would normally have given you.
> Which element this will be may be arbitrary, but this is still not useless:
>
> set.dropFirst().reduce(set.first!, …)
>

Do we have the guarantee that set.dropFirst() is going to return the same
element as set.first! ?

I don't understand how you can build generic algorithms over Sequence using
first() and last() that work if the protocol itself doesn't give any
guarantee about ordering.. Unless "first" and "last" both mean "any"...



>
> Even elementsEqual(_:) does tell you something potentially valuable:
> Whether two instances will end up giving the same result when processed by
> an ordering-sensitive algorithm.
>
> We should change the name to something like orderEquals(_:), and maybe
> change the lexicographicallyPrecedes(_:) method to something analogous like
> orderPrecedes(_:), and then be done with it.
>
> --
> Brent Royal-Gordon
> Sent from my iPhone
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] /*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

2017-10-15 Thread Geordie Jay via swift-evolution
Hi Mike,

2017-10-15 14:55 GMT+02:00 Mike Kluev :

> On 15 October 2017 at 13:35, Geordie Jay  wrote:
>
>> Also we're not talking about whether the Bool itself is discardable. For
>> example, it makes no sense to write:
>>
>> *let something: discardable Bool = true*
>>
>
> you can't write this either:
>
> let something: inout Bool = true
>
> that doesn't mean "inout" should be "@inputOutput" before the parameter
> name in function signature.
>

This is a different case: inout is an annotation on argument types (of
which there can be many).


>
> my litmus test is: "if we did it now in swift 0.0 what would we do".
> discardable before type passes this test, @discardableResult before
> function doesn't.
>

I don't understand what you're saying here. "Now in swift 0.0"? The first
public version of Swift had this same functionality in its same form, with
the name @warn_unused_result. The current version is just reversed, which
to me is a logical change.


>
>
>> There has been some discussion of "throws" as a keyword. If anything I
>> think that is something that is in more need of change. I've always read it
>> (frustratingly) as e.g. "func throws Bool", which it doesn't, it throws an
>> Error.
>>
>
> indeed. that's why "throws Bool" is wrong and if anything, i am advocating
> for:
>
> throwing func foo() -> Bool
>

I personally like that syntax, because that's exactly how I *talk* about
such a function. "oh that's a throwing function so you need to call it with
*try*".

As an extension to that, I'd also say "you can call that function without a
preceding variable assignment because it has a discardable result". I would
never say "this function returns a discardable boolean" because that just
doesn't match my mental model of what's going on. To me, it's the
*function* whose
return value can be discarded — in theory it has nothing to do with the
result itself. But it's quite possible I'm in the minority here.

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


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 2:29 AM, Kevin Nattinger 
wrote:

>
> On Oct 14, 2017, at 7:54 PM, Xiaodi Wu  wrote:
>
> On Sat, Oct 14, 2017 at 6:17 PM, Kevin Nattinger 
> wrote:
>
>> […]
>>> * A Swift `Sequence` is, to put it simplistically, a thing that can be
>>> iterated over in a `for...in` loop. If it would make you happy, for the
>>> rest of the discussion, let's suppose we called the protocol `ForLoopable`
>>> instead of `Sequence`.
>>>
>>>
>>> ForLoopable is so ugly. Since we’re just iterating over the elements,
>>> how about, oh, say, `Iterable`? Hey, that looks familiar.
>>>
>>
>> I'm not trying to bikeshed the name of `Sequence`. I'm picking an
>> intentionally unwieldy name for the purposes of discussing the semantics of
>> this particular protocol. The point is that the underlying issue has
>> nothing to do with the name; it can be `Iterable` or it can be `SpongeBob`
>> for all I care.
>>
>>
>> I’m not trying to bikeshed the name either, The underlying issue is that
>> (what is currently) Sequence actually encompasses two separate
>> functionalities, and those functionalities need to be separated with their
>> separate semantic requirements documented. “Sequence: Iterable,”
>> “OrderedSequence: Sequence,” “SpongeBob: ForLoopable,” the names are 100%
>> irrelevant at this point; what’s important is that one is not necessarily
>> ordered and the other guarantees an order.
>>
>>
>
> What are the "two separate functionalities”?
>
>
> Iteration, with convenience methods that don’t imply or rely on an order
> that may not be there; and convenience methods applicable to sequences that
> do have an intrinsic order.
>

Sets, as a mathematical concept, have no intrinsic order. However,
instances of `Set`, which can be iterated over, *do* have at least one
order which can be said to be intrinsic in the following sense: as long as
iteration is possible, no API design can prevent that order from being
observed and associated with the instance. Put another way, if you can use
an instance of a type in a for...in loop, intrinsic to that functionality
is a publicly visible order.


> All the extension methods on Sequence are ways of spelling things that you
> can write in a few lines of code using a `for...in` loop; they're in the
> stdlib to allow a more functional style which some prefer. If you accept
> that a type should support iteration with a `for...in` loop, then what is
> your basis for claiming that these extension methods are "separate
> functionalities”?
>
>
> Just because you *can* express something in code doesn’t mean you should,
> or that it’s correct. It is objectively false to say a Set has a first or
> last object, because the objects therein have no order. You can take a
> random object from the set and call it “first”, but that doesn’t make that
> a correct definition of Set.first. A Set has no order, a specific iteration
> has an “order” only in the sense that all and only the objects in the set
> have to come out one at a time, but that doesn’t mean the Set itself has an
> order, specifically a first or last object.
>

Since Set conforms to Collection, it is guaranteed that if one element of
an instance of Set comes out first one time, it'll come out first every
time from that instance. If it helps, think of Swift's Set as modeling
(imperfectly, as all models must) both a mathematical set and a multi-pass
sequence, just as Swift's Int models both an integer and a sequence of bits.

You’re a fan of the principal of least surprise. Tell me, which would be
> less surprising: Set.dropFirst() actually drops a random element, or Set
> doesn’t have a dropFirst()? And if you think dropFirst() removing an
> element at random is not surprising, please explain why.
>

I think Set.dropFirst removing the first element that I observe on
iteration is the least surprising answer, because Swift tells me that the
stdlib Set models a set but that it is also a sequence.

[…]
>>>
>>> * If a type `T` conforms to `ForLoopable` and an instance `t` of that
>>> type has at least one element, then *something* has to be the first element
>>> in a `for element in t { ... }` loop. Put another way, every instance of a
>>> type that conforms to `ForLoopable` must have at least one publicly
>>> observable order (although, intriguingly, I'm not sure it has to be a
>>> repeatable one). It is possible, therefore, to have a semantic answer to
>>> the question of which element is `first` or (if finite) `last`; one can
>>> also `drop(while:)`, etc., and perform lexicographical comparisons.
>>>
>>>
>>> As a side effect of Swift being a procedural language each iteration
>>> happens to occur in some order, yes, but that order is meaningless and
>>> reflects nothing about the Set itself.  In fact, I’d say that *`first`,
>>> `last`, etc. are not even defined on the original Set per se, only on the
>>> specific order that a particular iteration resulted in*. And that order

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Adam Kemp via swift-evolution


> On Oct 15, 2017, at 12:26 AM, Xiaodi Wu  wrote:
> 
> Hmm, I do think I can squash some of these suggestions into an explicit and 
> very clear option:
> 
> equalsInIterationOrder(_:)

I could live with that name. 

> 
> We would then clarify the corresponding precedence function in the same way:
> 
> lexicographicallyPrecedesInIterationOrder(_:)

but that one seems a bit unwieldy...
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Kevin Nattinger via swift-evolution

> On Oct 14, 2017, at 7:54 PM, Xiaodi Wu  wrote:
> 
> On Sat, Oct 14, 2017 at 6:17 PM, Kevin Nattinger  > wrote:
>>> […]
>>> * A Swift `Sequence` is, to put it simplistically, a thing that can be 
>>> iterated over in a `for...in` loop. If it would make you happy, for the 
>>> rest of the discussion, let's suppose we called the protocol `ForLoopable` 
>>> instead of `Sequence`.
>> 
>> ForLoopable is so ugly. Since we’re just iterating over the elements, how 
>> about, oh, say, `Iterable`? Hey, that looks familiar.
>> 
>> I'm not trying to bikeshed the name of `Sequence`. I'm picking an 
>> intentionally unwieldy name for the purposes of discussing the semantics of 
>> this particular protocol. The point is that the underlying issue has nothing 
>> to do with the name; it can be `Iterable` or it can be `SpongeBob` for all I 
>> care.
> 
> I’m not trying to bikeshed the name either, The underlying issue is that 
> (what is currently) Sequence actually encompasses two separate 
> functionalities, and those functionalities need to be separated with their 
> separate semantic requirements documented. “Sequence: Iterable,” 
> “OrderedSequence: Sequence,” “SpongeBob: ForLoopable,” the names are 100% 
> irrelevant at this point; what’s important is that one is not necessarily 
> ordered and the other guarantees an order.
>  
> 
> What are the "two separate functionalities”?

Iteration, with convenience methods that don’t imply or rely on an order that 
may not be there; and convenience methods applicable to sequences that do have 
an intrinsic order.

> All the extension methods on Sequence are ways of spelling things that you 
> can write in a few lines of code using a `for...in` loop; they're in the 
> stdlib to allow a more functional style which some prefer. If you accept that 
> a type should support iteration with a `for...in` loop, then what is your 
> basis for claiming that these extension methods are "separate 
> functionalities”?

Just because you *can* express something in code doesn’t mean you should, or 
that it’s correct. It is objectively false to say a Set has a first or last 
object, because the objects therein have no order. You can take a random object 
from the set and call it “first”, but that doesn’t make that a correct 
definition of Set.first. A Set has no order, a specific iteration has an 
“order” only in the sense that all and only the objects in the set have to come 
out one at a time, but that doesn’t mean the Set itself has an order, 
specifically a first or last object.

You’re a fan of the principal of least surprise. Tell me, which would be less 
surprising: Set.dropFirst() actually drops a random element, or Set doesn’t 
have a dropFirst()? And if you think dropFirst() removing an element at random 
is not surprising, please explain why.

>>> […]
>> 
>>> * If a type `T` conforms to `ForLoopable` and an instance `t` of that type 
>>> has at least one element, then *something* has to be the first element in a 
>>> `for element in t { ... }` loop. Put another way, every instance of a type 
>>> that conforms to `ForLoopable` must have at least one publicly observable 
>>> order (although, intriguingly, I'm not sure it has to be a repeatable one). 
>>> It is possible, therefore, to have a semantic answer to the question of 
>>> which element is `first` or (if finite) `last`; one can also 
>>> `drop(while:)`, etc., and perform lexicographical comparisons.
>> 
>> As a side effect of Swift being a procedural language each iteration happens 
>> to occur in some order, yes, but that order is meaningless and reflects 
>> nothing about the Set itself.  In fact, I’d say that `first`, `last`, etc. 
>> are not even defined on the original Set per se, only on the specific order 
>> that a particular iteration resulted in. And that order is not necessarily 
>> predictable, nor necessarily stable, as you yourself said.
>> 
>> Consider an Iterable that gives a different order every time it’s iterated. 
>> Should calling `.first` or `last` give a different object every time?  
>> That’s absurd.
>> Should an object lexicographically compare not equal to itself? Even more 
>> absurd. 
>> 
>> What's your basis for saying that such behavior is absurd? It is explicitly 
>> permitted for instances of types conforming to `SpongeBob` to be single-pass 
>> and/or infinite. For a single-pass `SpongeBob`, `first` will certainly 
>> return a different value every time it is invoked.
> 
> Is `first` mutating? No. Should it be? No! `first` and `last` are a peek at 
> the state of the object.
> 
> You're right, `first` should not be mutating; that's actually an important 
> design consideration, as Ole pointed out, and it's not actually available on 
> `Sequence` for that reason. However, `first { _ in true }` is available and 
> is potentially mutating, as are all methods on Sequence by design.
> 
> Is `elementsEqual` (or *shudder* 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Adam Kemp via swift-evolution
I don’t think it’s impossible. I still think pairwiseEqual is clear and 
intuitive, and if sequenceEqual doesn’t work because of other conventions then 
maybe sequentiallyEqual could work. There have been several other proposed 
names as well. We should be spending more time discussing these alternatives.

What other names can we come up with? Let’s discuss them. 

> On Oct 14, 2017, at 11:18 PM, Xiaodi Wu  wrote:
> 
>> On Sun, Oct 15, 2017 at 12:56 AM, Adam Kemp  wrote:
>> 
>> 
>> > On Oct 14, 2017, at 10:32 PM, Xiaodi Wu  wrote:
>> >
>> > Therefore, it is entirely OK (to me) if the result is something that is so 
>> > obtuse as to be at first meaningless to most people.
>> 
>> I can’t speak for others, but it’s not ok with me. API is UX. It should be 
>> understandable and approachable. If this were a function that was considered 
>> dangerous and we wanted to discourage its use then maybe I could buy this 
>> argument, but I don’t think that’s quite the case here. Even if you don’t 
>> think it’s the best API to use or the most common it should still be named 
>> clearly.
> 
> I don't disagree with you that it should be _clear_. I'm simply wondering out 
> loud whether it is possible to name this method _intuitively_ (i.e., clear 
> without resorting to documentation) given that it lives in the nexus of an 
> inherent contradiction between protocol and implementing type which is 
> anything but intuitive (or even clear after you read the documentation).
> 
> If it is not possible to name this method _intuitively_, then it is not 
> possible to name it _well_. Then, given the option between obtuse-but-correct 
> and approachable-but-misleading, I would opt for the former as the _least 
> bad_ option.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 1:18 AM, Xiaodi Wu  wrote:

> On Sun, Oct 15, 2017 at 12:56 AM, Adam Kemp  wrote:
>
>>
>>
>> > On Oct 14, 2017, at 10:32 PM, Xiaodi Wu  wrote:
>> >
>> > Therefore, it is entirely OK (to me) if the result is something that is
>> so obtuse as to be at first meaningless to most people.
>>
>> I can’t speak for others, but it’s not ok with me. API is UX. It should
>> be understandable and approachable. If this were a function that was
>> considered dangerous and we wanted to discourage its use then maybe I could
>> buy this argument, but I don’t think that’s quite the case here. Even if
>> you don’t think it’s the best API to use or the most common it should still
>> be named clearly.
>
>
> I don't disagree with you that it should be _clear_. I'm simply wondering
> out loud whether it is possible to name this method _intuitively_ (i.e.,
> clear without resorting to documentation) given that it lives in the nexus
> of an inherent contradiction between protocol and implementing type which
> is anything but intuitive (or even clear after you read the documentation).
>
> If it is not possible to name this method _intuitively_, then it is not
> possible to name it _well_. Then, given the option between
> obtuse-but-correct and approachable-but-misleading, I would opt for the
> former as the _least bad_ option.
>

Hmm, I do think I can squash some of these suggestions into an explicit and
very clear option:

equalsInIterationOrder(_:)

We would then clarify the corresponding precedence function in the same way:

lexicographicallyPrecedesInIterationOrder(_:)

(Lexicographic precedence in contradistinction to length-lexicographic or
Kleene-Brouwer precedence.)

All other "order-dependent" functions, as Apple documentation calls them,
on Set and Dictionary are pretty explicit about being intrinsically
order-dependent (in that they talk about firsts, lasts, starts, ends,
prefixes, suffixes, indices, ranges, dropping, popping, reversing, joining,
or splitting).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-15 Thread Xiaodi Wu via swift-evolution
On Sun, Oct 15, 2017 at 12:56 AM, Adam Kemp  wrote:

>
>
> > On Oct 14, 2017, at 10:32 PM, Xiaodi Wu  wrote:
> >
> > Therefore, it is entirely OK (to me) if the result is something that is
> so obtuse as to be at first meaningless to most people.
>
> I can’t speak for others, but it’s not ok with me. API is UX. It should be
> understandable and approachable. If this were a function that was
> considered dangerous and we wanted to discourage its use then maybe I could
> buy this argument, but I don’t think that’s quite the case here. Even if
> you don’t think it’s the best API to use or the most common it should still
> be named clearly.


I don't disagree with you that it should be _clear_. I'm simply wondering
out loud whether it is possible to name this method _intuitively_ (i.e.,
clear without resorting to documentation) given that it lives in the nexus
of an inherent contradiction between protocol and implementing type which
is anything but intuitive (or even clear after you read the documentation).

If it is not possible to name this method _intuitively_, then it is not
possible to name it _well_. Then, given the option between
obtuse-but-correct and approachable-but-misleading, I would opt for the
former as the _least bad_ option.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution