> On Oct 18, 2017, at 12:24 PM, Thorsten Seitz <[email protected]> wrote:
>
>>
>> Am 17.10.2017 um 20:47 schrieb Michael Ilseman via swift-evolution
>> <[email protected] <mailto:[email protected]>>:
>>
>>
>>
>>> On Oct 17, 2017, at 10:15 AM, Kevin Nattinger via swift-evolution
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>> Because, in my analysis, the problem is that the method is incorrectly
>>>> named. The problem affects all types that conform to Sequence and not just
>>>> Set and Dictionary; elementsEqual is a distinct function from ==, and it
>>>> must either continue to be distinct or cease to exist, but its name does
>>>> nothing to clarify any distinction.
>>>
>>> In my analysis, the problem is the method's implementation. As I see it,
>>> the only use for `elementsEqual` is as a replacement for `==` when two
>>> objects are different types (or not known to be the same)—equal elements,
>>> and IF the sequences have an order, in the same order. Could you provide an
>>> example where `elementsEqual` randomly returning either true or false
>>> depending on internal state alone is a legitimate and desirable result?
>>>
>>
>> It doesn’t randomly return true or false, it consistently returns true or
>> false for the *same* pair of Sequences. What *same* means, of course, is
>> complicated and exists at two levels (as we have two ways of talking about
>> *same*).
>
>
> It is random (for unordered collections) from the standpoint of business
> logic.
Could you define what you mean by “business logic”? Is this is a subset of
programming in Swift, and if so what is in it? Can users define their own types
in this subset? Also, why would arguments made in that subset also apply to all
of Swift?
> The order of the elements of a Set, while publicly observable, cannot be
> influenced by business logic because it is an implementation detail.
Yes, this is what Set means when it says: “You use a set instead of an array
when you need to test efficiently for membership and you aren’t concerned with
the order of the elements in the collection, or when you need to ensure that
each element appears only once in a collection.” (emphasis mine)
> Therefore it is not possible to write business logic that exploits this
> order, i.e. it is not possible to write business logic using `elementsEqual`
> on a Set.
> The only exception is using the receiver as argument, i.e.
> `set.elementsEqual(set)` because in this case, and in this case alone, the
> result is independent of the effectively random order.
> Therefore the single use case for `elementsEqual` for unordered collections
> is calling `set.elementsEqual(set)` to determine whether a Set of Floats
> contains NaN values. I claim that this is better written as `set.contains {
> $0.isNaN }` which works nicely for a Set<Float> and is intention revealing as
> opposed to using `elementsEqual`.
>
> As I have shown this really is the *single* use case for `elementsEqual` for
> unordered collections. There can be no other use case.
> All other uses of `elementsEqual` involving two different collections where
> one is an unordered collection have random results that have absolutely no
> business meaning and therefore are bugs.
>
> Therefore having `elementsEqual` as API for unordered collections is a source
> of bugs except for a single use case which has a better solution using
> `contains`. That is why I would like to split the API.
>
> Adam expressed the concern that this required `map` to implemented separately
> for the split APIs: `Iterable.map` would have to return an `Iterable` whereas
> `Sequence.map` would have to return a `Sequence`.
> This is an independent issue IMO, because currently we have a similar
> situation: `Collection.map` does not return a `Collection` either. It returns
> an Array. This is a compromise partly due to missing language features which
> can simply remain when `Sequence` is split.
>
> Actually the question for the correct return type for `map` is not a simple
> one. For a `Dictionary` we would probably want to get a `Dicitonary` where
> the values have been replaced by the mapped ones (this is how Smalltalk does
> it). But for `Set` we typically do *not* want a `Set` because in general we
> will be interested in duplicate mapped values. There are times where a `Set`
> would be the correct return type but this applies to ordered collections or
> dictionaries as well, so there should be a variant (or an argument with a
> default) allowing to provide the desired result type or target collection.
> But this is a completely separate issue which can be easily deferred until
> the planned language features have arrived which might help finding a good
> solution for this question. Until then we will just use the current
> implementation which returns an array.
>
> To get back to the topic at hand: I propose to differentiate between
> unordered and ordered collections because I think that this is an important
> distinction with tractable impact on algorithms (as shown above). The method
> `elementsEqual` would be part of the ordered sequence protocol and I would
> suggest the name `elementsPairwiseEqual`.
>
You are free to propose that and justify its cost. You'll probably want to plan
on how you’ll present the cost/benefit analysis for the feedback of “why not
just slap a warning on Set/Dictionary?”
> -Thorsten
>
>
>
>>
>> I apologize for not reading every email in depth in this thread (they are
>> coming in faster than I can parse them), but let me try to present
>> motivation for this and hopefully provide more shared understanding.
>>
>> We have two forms of equality we’re talking about: equality of Sequence and
>> equality of the elements of Sequences in their respective ordering. `==`
>> covers the former, and I’ll use the existing (harmful) name of
>> `elementsEqual` for the latter.
>>
>> `==` conveys substitutability of the two Sequences. This does not
>> necessarily entail anything about their elements, how those elements are
>> ordered, etc., it just means two Sequences are substitutable.
>> `elementsEqual` means that the two Sequences produce substitutable elements.
>> These are different concepts and both are independently useful.
>>
>> Cases:
>>
>> 1. Two Sequences are substitutable and produce substitutable elements when
>> iterated. `==` and `elementsEqual` both return true.
>>
>> Example: Two arrays with the same elements in the same order.
>>
>>
>> 2. Two Sequences are substitutable, but do not produce substitutable
>> elements when iterated. `==` returns true, while `elementsEqual` returns
>> false.
>>
>> Example: Two Sets that contain the same elements but in a different order.
>>
>> Contrived Example: Two Lorem Ipsum generators are the same generator
>> (referentially equal, substitutable for the purposes of my library), but
>> they sample the user’s current battery level (global state) each time they
>> produce text to decide how fancy to make the faux Latin. They’re
>> substitutable, but don’t generate the same sequence.
>>
>>
>> 3. Two Sequences are not substitutable, but produce substitutable elements
>> when iterated. `==` returns false, while `elementsEqual` returns true.
>>
>> Example: Consider two sequences that have differing identity. `==` operates
>> on an identity level, `elementsEqual` operates at an element level.
>>
>> Contrived Example: InfiniteMonkeys and Shakespeare both produce the same
>> sonnet, but they’re not substitutable for my library’s purposes.
>>
>>
>> 4. Two Sequences are not substitutable and don’t produce substitutable
>> elements when iterated. `==` and `elementsEqual` both return false.
>>
>> Example: `[1,2,3]` compared to `[4,5,6]`
>>
>>
>> It is true that situations #2 and #3 are a little harder to grok, but they
>> are what illustrate the subtle difference at hand. I think situation #2 is
>> the most confusing, and has been the primary focus of this thread as Set
>> exists and exhibits it.
>>
>>
>> Now, onto naming. `elementsEqual` is a very poor choice of name for the
>> concept of equality of elements in their respective orderings, as it doesn’t
>> highlight the “in their respective orderings” part. `lexicographicallyEqual`
>> highlights the ordering much better, as “abc” is not lexicographically equal
>> to “cba” despite having equal elements. I think it is clearly an improvement
>> over the status quo. I like something a little more explicit (e.g.
>> `elementsOrderedEqual`), personally, but I don’t care that strongly. I’m
>> just glad to see `elementsEqual` getting some clarification.
>>
>>
>>
>>
>>>>
>>>> Thanks,
>>>> Jon
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution