[swift-evolution] Proposals: (1) Forbidding custom `==` for value types, (2) `dispatch` keyword, (3) `default`-result for methods with `Self`, and (4) Poor-Mans-Existentials

Johannes Neubauer neubauer at kingsware.de
Sat Jul 16 04:52:50 CDT 2016

> Am 16.07.2016 um 03:53 schrieb Susan Cheng <susan.doggie at gmail.com>:
> How about Polar(r: 0, phi: 0) ?
> It should all equal with any angles if r == 0.

In an earlier post I wrote:

> And I would do the „standard equality“ upfront even if there is a custom implementation
> and if the „standard equality“ says `true`, the custom implementation is not asked.
> This would reduce the possibility of false-negatives.

So, if you’d like to override the "standard equality“ you would be able to do this, but with this chain you cannot create false-negatives as easy:

* for heap allocated values (e.g. values bigger than the value buffer in an existential container for protocol types) do a `===`. If `true` return `true`.
* for stack allocated values use „standard equality“. If `true` return `true`.
* if „standard equality“ return `false`, execute possible custom equality check `==`. Return result.

But If you override `==` in a value type I would warn, because this makes sense in only very rare occasions (perhaps with a @suppress annotation or alike). If you would like to ignore some values (produce „false“-negatives on purpose) add a `transient` keyword or alike. But I wouldn’t allow the latter, but instead offer the developer best practices like value types with indirect storage and copy-on-write for value semantics, in order to omit the values in the `==` implementation of the indirect storage reference type. Last but not least, in a far future, when the indirect storage of value types is done automatically (potentially) and these values are uniquely stored on the heap (in some kind of value pool), you can check for them `===`, too. The latter would **not** be as easy, if we allow custom equality because if we store values uniquely in the value pool and the equality puts values in the same equivalence class that are actually **not** equal from a value types point of view (be it for false-positives and false-negatives), it would put the values into the same slot, since you don’t have an identity check (`===`) on values.

In summary, IMHO using custom equality for value types is dangerous as it puts values that are actually different into the same equivalence class, which make their usage in dictionaries very difficult (especially for false-negatives, which hold some context information not part of the value) and correspondingly the implementation of value pools hard. So, custom equality should be used only in exceptional cases and it should be possible to do at most false-positives (like in the `Polar(r:0, phi: whatever)` example), but for false-negatives (like in the URI example) it should be handled differently, by introducing indirection.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160716/dec44666/attachment.sig>

More information about the swift-evolution mailing list