I really want synthesized equality (etc.), but having seen the previous
discussions on this and related topics I am not sure that directly-deriving the
`==` function is the right approach.
The main reason I say this is that although this works great for the easy case
— all fields equatable, do the obvious thing! — sooner or later people will
want to customize it, which would ideally allow someone to say “do the obvious
thing for a,b,c but let me handle d and e”, e.g. still get synthesis for the
easy parts…but an approach that directly-synthesizes `==` for a type seems like
it’ll be difficult to expand to support such customization.
Suppose instead that we had a “magic function” `T#memberwiseEqual(_:_:)` we
could invoke like so:
// the details are *very* bikesheddable here:
func ==(lhs: Foo, rhs: Foo) -> Bool {
return Foo#memberwiseEqual(lhs,rhs) // `#` b/c of "compiler magic”
// ^ compiler error iff any of `Foo`’s members aren’t Equatable
}
…which’d expand to the expected “lhs.a == rhs.a && lhs.b == rhs.b && …”.
For trivial equatable synthesis this isn’t as nice as a full automatic
derivation, but it seems like an *approach* that’d be much-better positioned
for future expansion and enhancement, e.g.:
extension Foo: Equatable {
// mock syntax; probably too ambiguous for actual use but i think the idea
is clear:
private static func boringComponentsEqual(lhs: Foo, _ rhs: Foo) -> Bool {
return Foo(boring,boring2,boringIII)#memberwiseEqual(lhs,rhs)
}
}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return Foo.boringComponentsEqual(lhs,rhs) && // non-trivial equality logic
here
}
…as opposed to trying to retrofit various “customizations" onto a system that
directly synthesizes `==` (without exposing any “internals", so to speak).
You can easily imagine a similar `#casewiseEqual` for enums (it seems likely to
be trickier, but not impossible), and again a #memberwiseHash for hashing, and
so on.
I think you can summarize the above as “all-in-one derivation is appealing, but
I think pragmatically and looking-ahead it’s a better move to expose the
'synthesis mechanism’ itself (leaving it the user to do the 'final assembly’)”.
> On May 25, 2016, at 1:28 PM, Tony Allevato via swift-evolution
> <[email protected]> wrote:
>
> I was inspired to put together a draft proposal based on an older discussion
> in the Universal Equality, Hashability, and Comparability thread
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/8919/
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/8919/>> that
> recently got necromanced (thanks Mark Sands!).
>
> I'm guessing that this would be a significant enough change that it's not
> possible for the Swift 3 timeline, but it's something that would benefit
> enough people that I want to make sure the discussion stays alive. If there
> are enough good feelings about it, I'll move it from my gist into an actual
> proposal PR.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution