> Am 18.10.2017 um 22:36 schrieb Michael Ilseman <milse...@apple.com>:
> 
> 
> 
>> On Oct 18, 2017, at 12:24 PM, Thorsten Seitz <tseit...@icloud.com 
>> <mailto:tseit...@icloud.com>> wrote:
>> 
>>> 
>>> Am 17.10.2017 um 20:47 schrieb Michael Ilseman via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
>>> 
>>> 
>>> 
>>>> On Oct 17, 2017, at 10:15 AM, Kevin Nattinger via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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?

>From Wikipedia: "In computer software 
><https://en.wikipedia.org/wiki/Software>, business logic or domain logic is 
>the part of the program that encodes the real-world business rules 
><https://en.wikipedia.org/wiki/Business_rule> that determine how data can be 
>created, stored, and changed 
><https://en.wikipedia.org/wiki/Create,_read,_update_and_delete>. It is 
>contrasted with the remainder of the software that might be concerned with 
>lower-level details of managing a database 
><https://en.wikipedia.org/wiki/Database> or displaying the user interface 
><https://en.wikipedia.org/wiki/User_interface>, system infrastructure, or 
>generally connecting various parts of the program.“
(https://en.wikipedia.org/wiki/Business_logic)

I explained why there is no possibility to use `elementsEqual` with unordered 
collections like Set except for the single use case of comparing the elements 
of a set with themselves, i.e. `set.elementsEqual(set)`.

> 
>> 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)

Exactly. I am well aware that Sets are unordered. This whole discussion 
revolves around `elementsEqual` being not appropriate for unordered collections 
like Set. 

-Thorsten


>> 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
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to