[swift-evolution] Proposals: (1) Forbidding custom `==` for value types, (2) `dispatch` keyword, (3) `default`-result for methods with `Self`, and (4) Poor-Mans-Existentials
felixcca at yahoo.ca
Tue Jul 19 11:00:21 CDT 2016
>> 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.
Please do point me to that literature that shows that developers frequently misimplement their own comparators.
>> 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).
No, they can't. There is no way to differentiate a char array that should be a null-terminated string from a char array that is actually a byte array at the C level.
>>> 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). 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.
This sounds like piling on more work for the sake of it. If we end up forcing a default equality check on everything, I hope that we can at least rely on it being there all the time, because otherwise that will also be a bug vector.
>> 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.
Swift won't switch to a GC in the foreseeable future. That discussion has already happened. The points brought forward are that you couldn't implement COW semantics because a GC doesn't keep a reference count around at all times; that ARC means that resources are deallocated deterministically; that a fast GC requires you to use up to 2-3x as much memory as you actually need.
>> 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)
>> 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.
Here's one way this could be implemented: if you write `struct Foo: Equatable` without implementing a `func ==`, the compiler makes one for you. Done.
More information about the swift-evolution