<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div style="font-family:Arial;">I completely agree with Austin here. Automatic derivation (perhaps through the same mechanisms Joe is talking about) would be a nice enhancement, but I find it refreshing and advantageous for simple value types to have very little automatic behavior.</div>
<div style="font-family:Arial;">&nbsp;</div>
<div id="sig40804545"><div class="signature">Cheers!<br></div>
<div class="signature">&nbsp; Zachary Waldowski<br></div>
<div class="signature">&nbsp;&nbsp;<a href="mailto:zach@waldowski.me">zach@waldowski.me</a><br></div>
<div style="font-family:Arial;">&nbsp;</div>
</div>
<div>On Tue, Mar 8, 2016, at 05:15 PM, Austin Zheng via swift-evolution wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div style="font-family:Arial;">I would prefer Equatable and Hashable to remain opt-in, and for us to add better support for automatic deriving of implementation.<br></div>
<div>&nbsp;</div>
<div>For something like printing the representation of an object to a string, there exists a "not wrong" mapping of every possible value to a string. That is, if my FooStruct doesn't provide a custom description, having the runtime convert it to something like "(FooStruct instance)" is still a valid mapping. It might not be useful, but it's not wrong.<br></div>
<div>&nbsp;</div>
<div>I don't think the same applies for equatability. The universal default behavior for equating two objects is either correct or incorrect, and it's not possible to know beforehand which is which. One of the wonderful things about the current Swift system is that (modulo some exceptional cases) only things explicitly meant to be equatable with each other are comparable. We avoid the object-oriented pitfall in which 'equality' means two different things - equality of value if you implemented an override properly; a default 'equality of instance' otherwise (which might be right or wrong). Of course, the same pitfall wouldn't necessarily apply in our case, but the problem of having a 'default' == impl that allows a developer to falsely assume their type is being properly compared (or not think about it at all) would still be present.<br></div>
<div>&nbsp;</div>
<div>Best,<br></div>
<div>Austin<br></div>
<div><div>&nbsp;</div>
<div>&nbsp;</div>
</div>
</div>
<div><div style="font-family:Arial;">&nbsp;</div>
<div><div style="font-family:Arial;">On Tue, Mar 8, 2016 at 2:02 PM, Brian Pratt via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex;"><div dir="ltr"><div style="font-family:Arial;"><span class="size" style="font-size:12.8px">Definitely a +1 on the basics. W</span><span class="size" style="font-size:12.8px">hen you get inheritance involved, does that complicates things a little bit?</span><br></div>
<div>&nbsp;</div>
<div><span class="size" style="font-size:12.8px">Let's say I have a subclass instance that has corresponding fields with a superclass instance. Is it equal to said super-class instance using just member-wise comparisons? Would that be problematic? In Scala you'd often use a reference to an "equality contract" object type in order to get "transitive" equality between subclasses and superclasses, which definitely feels like a step backwards from the current protocol-driven approach.</span><br></div>
<div><div>&nbsp;</div>
<div>&nbsp;</div>
</div>
</div>
<div><div><div><div style="font-family:Arial;">&nbsp;</div>
<div><div style="font-family:Arial;">On Tue, Mar 8, 2016 at 2:54 PM, Joe Groff via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex;"><div style="font-family:Arial;">(starting a new thread by DaveA's request)<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
There's a definition of equality that makes sense as a default for nearly every type in our system:<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
- Basic types like IntNN, FloatNN, String, etc. have domain-defined equality,<br></div>
<div style="font-family:Arial;">
- Structs and tuples can be considered equal if their corresponding fields are equal,<br></div>
<div style="font-family:Arial;">
- Enums can be considered equal if they carry the same, equal payload,<br></div>
<div style="font-family:Arial;">
- Class references can be considered equal if they refer to the same instance,<br></div>
<div style="font-family:Arial;">
- Metatypes can be considered equal if they represent the same type, and<br></div>
<div style="font-family:Arial;">
- Existentials can be considered equal if they carry equal values of the same dynamic type.<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
and similarly, reasonable hash code implementations could be synthesized by applying a standard hash combine operation over the components, and a default ordering&nbsp; could be assigned to values of every type. I think it's worth considering whether Equatable, Hashable, and/or Comparable, instead of being explicit protocols, should become universal behavior like 'print', with customization points to override the default behavior. If Equatable and Hashable behavior were universal, that would solve many of the common problems people currently have trying to work with heterogeneous containers. In object-oriented frameworks, including Cocoa, Java, and .NET, it is common for the root (NS)Object class to provide default equality and hashing operations. There are of course some tradeoffs:<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
- Universal behavior would require us to either generate code for '==', 'hashValue', and/or '&lt;' for every type, or provide sufficient reflection info for a common runtime implementation to do it. The reflection-based approach may be reasonable for print(), since dumping reflection info only reduces the quality of the default logging behavior, but '==' and 'hashValue' are more essential to proper behavior, so relying on reflection might be too slow, and would be brittle when we introduce the ability to drop reflection info.<br></div>
<div style="font-family:Arial;">
- Type safety with '==' is important to prevent accidental '1 == "1"' type comparsions, and a fully generic 'func ==&lt;T&gt;(x: T, y: T) -&gt; Bool' could potentially allow those sorts of mixed-type comparisons by accident. Language rules that constrained when generic parameters can be resolved to supertypes might help here.<br></div>
<div style="font-family:Arial;">
- Function types in Swift do not provide a ready equality operation. We could provide a default implementation that always returns 'false', perhaps.<br></div>
<div style="font-family:Arial;">
- A Comparable ordering can be dreamt up for many types, but it's not always a stable ordering, or a desired one. Many people have complained that 'nil &lt; .Some(1)' works for optionals, for instance, ordering 'nil' below Some values. We could use pointer identity to order class instances and types, but this wouldn't be a stable ordering across process runs. That might be good enough for ordered collections like search trees, but is weaker than what many people expect '&lt;' to do.<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
It's my feeling that Equatable and Hashable would make a lot of sense as universal operations; I'm not so sure about Comparable.<br></div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">
-Joe<br></div>
<div style="font-family:Arial;">
_______________________________________________<br></div>
<div style="font-family:Arial;">
swift-evolution mailing list<br></div>
<div style="font-family:Arial;">
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div style="font-family:Arial;">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote></div>
<div style="font-family:Arial;">&nbsp;</div>
</div>
</div>
</div>
<div style="font-family:Arial;">&nbsp;</div>
<div style="font-family:Arial;">_______________________________________________<br></div>
<div style="font-family:Arial;">
swift-evolution mailing list<br></div>
<div style="font-family:Arial;">
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div style="font-family:Arial;">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
<div style="font-family:Arial;">&nbsp;</div>
</blockquote></div>
</div>
<div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div style="font-family:Arial;">&nbsp;</div>
</body>
</html>