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

Reply via email to