> Am 19.07.2016 um 06:29 schrieb Félix Cloutier <[email protected]>:
> 
>>> 
>>>> 1. You cannot say something is unequal although the system says it is equal
>>> 
>>> That doesn't make me feel much safer. Comparison returned false when it 
>>> should have returned true?
>> 
>> Yes you just may have a condition inverted e.g.. You could even have a 
>> compiler flag, where you remove the short-circuit and throw an error, if you 
>> have a false-negative. This would ease finding such issues (easier than just 
>> not having this feature)
> 
> This minor enhancement could most likely be obtained by just having a default 
> ==, which is a project that I can get behind.

Structs do not have a common ancestor, this is why swift uses existential 
containers, in order to create polymorphic behavior for protocol types with 
value type implementations. So implementing such a default == would bring 
changes to swift either. But I didn’t bring this idea in the first place to 
have some more convenience. I am sure (and literature as well as my experience 
as a developer and project lead in many industrial projects proves me right), 
that implementing equality is a major source of errors in software development 
and I think that you underestimate this issue. This issues are really hard to 
track down. It is always better to implement a custom protocol for custom 
equality semantics, so that it doesn’t interfere with the expectations of the 
standard library and the many libraries to come, that will depend on the 
equals-contract.

Swift has the chance, not to make the same mistakes that other languages did 
before. But perhaps I just have to wait until Swift 3 has finished and repost 
the proposal, so that the core team has time to revisit it and we can start a 
fruitful discussion. Because right now I have the feeling that we are just 
spinning although I am 100% confident that this proposal (or at least a 
modified variant) is beneficial for swift.

> Also, what about C structures with character arrays? They get translated as 
> tuples of CChar (if that's what they're still called now, didn't really keep 
> track). The two are equal as soon as you hit a null terminator, but 
> memberwise comparison doesn't know that.

They can have its own standard implementation. There is a lot of translation 
going on between Objective C <-> Swift as well as C <-> Swift (e.g., some 
constants are automatically coerced into enums).

>> Invisible behavior is everywhere: Automatic Reference Counting, Existential 
>> Containers, Virtual Functions, …
>> 
>> Swift is a high-level language, so it’s main appeal is invisible behavior, 
>> but I would call it *rich semantics* or something like that.
> 
> There is an actual demand for these. With ARC, I don't need to think about 
> memory management (too much).

You have to, as soon as you have cyclic structures (weak, unowned). It is a 
tradeoff between performance (ARC) and convenience (garbage collection).

Analogously, Having a better corset for equality helps me not to think so much 
about doing this implementation right.

> Virtual functions let me implement OO design, which allows a ton of 
> developers to leverage experience. With forced memberwise comparisons, I can 
> trade easily debuggable problems for surprising behavior.

With my proposal you wouldn’t make it harder to find these issues it makes it 
easier. As I told before, you could have an instrumentation/error handling, 
that (in debug mode) does both checks default and custom implementation (so no 
short-circuit) and inform you about false-negatives automatically.

> Also keep in mind that most of these things are criticized to some degree. 
> ARC is a common enough source of bugs that Apple has a relatively large 
> investment into tools specially made to debug them.

This is due to the tension between the goal „safety“ and „performance“. Perhaps 
swift switches to garbage collection in the future. Or they decide to use 
garbage collection on fast devices as well as ARC on slow devices. Who knows.

> OO also has a ton of detractors.

Yes, because it is not restrictive enough in it’s current implementation. This 
is why I add these proposals. But there is not just black and white. Languages 
like Haskell are not that widely adopted, because a pure functional approach 
has its own downsides. Try to implement something like SpriteKit with Haskell.

>> It is like a virtual method, but for arbitrary parameters, so you need some 
>> kind of V-table for that and a lookup, that can be done in constant time. It 
>> is something, that I wouldn’t add by default. It is something that you may 
>> add to a method explicitly via a keyword (instead of implementing the 
>> dynamic dispatch by hand, by calling an `equals:other` method on the 
>> left-hand-side and then doing an if-cascade for rhs for example; which is 
>> error-prone). So you may use it wisely only, where necessary (and the 
>> internal implementation of swift will be much faster, than the manual 
>> variant). The XTend language has such a feature.
> 
> I didn't understand what you meant with dispatch. Now, my understanding is 
> that it would be used to implement virtual dispatch over multiple parameters 
> (instead of just `self`).

Yes and no. Operators (like ==) do not have `self`, this is a major issue IMO, 
since even the left-hand-side is not dispatched. Operators (and global 
functions) are non-virtual.

> What? You want to force every equality check to start with a memberwise 
> comparison of *everything*.

I just proposed these two standard implementations executed before any custom 
implementation (no recursion or anything alike):

1. a `memcmp` for value types (not recursing through referenced types or 
anything) and
2. a === check for reference types (just comparing one address)

>>> Please realize that this is an absolutely radical change. Swift currently 
>>> has little to no invisible behavior, and currently lets you implement 
>>> equality any way that you like. In my book, radical changes should be 
>>> considered with extreme skepticism, and should have an extremely compelling 
>>> case behind them.
>> 
>> First off, I don’t think, that the changes are that radical and second this 
>> example gives a small insight how bad you can implement equality in swift:
> 
> None of it is hard enough to debug to justify a performance hit. Just because 
> you're able to misuse a feature is not an argument that this feature 
> shouldn't be available, especially if you can only half-solve the problem.

You cannot solve the `null` problem or the fragile base class problem 
completely either, but still swift has:

1. no abstract classes and no abstract methods
2. optionals
3. 2-phase initialization

to narrow the problem space.

> Why can't you be content with a default implementation? People all over are 
> saying "don't touch my code", there's a very easy way to not touch anyone's 
> code, but it's like you really want to.

As mentioned above AFAIK this would introduce a change to swift either, since 
structs don’t have a common ancestor (in terms of „inheritance“) **and** this 
would just be a convenience feature and not help to reduce really hard to trace 
bugs.

These features aren’t only for the master-of-the-blaster programmer. In a 
normal project you have differently skilled programmers and a type system 
should help even the average skilled one.

All the best
Johannes

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to