> On 10 Aug 2017, at 23:29, Brent Royal-Gordon <br...@architechies.com> wrote:
> If the only difference were whether the default implementation was generated
> by a macro or not, would you still think auto-derivation should be marked
> with a keyword?
With or without a macro the issue here is still that the synthesised behaviour
is generated based upon assumptions about a concrete type, whereas current
default implementations are only based upon the methods/properties that are
defined by the protocol itself, i.e- if the protocol is well-defined, and you
implement it accordingly, then all a default implementation should be doing is
correctly using the protocol. The problem with the synthesised behaviour is
that it must necessarily make assumptions about parts of the concrete type that
are not defined by the protocol and may in fact have nothing to do with it at
all (e.g- could be properties implementing an entirely different protocol).
Whether or not this is generated by a macro is not the issue. If we assume
macros will eventually replace features like this one, then I would still want
a clear standard on how to distinguish between opting in to synthesised
behaviour such as this.
To be clear as well; I didn't specifically request a keyword. In fact I'm
leaning more towards separate protocols personally; i.e- if you just want to
adopt the requirements you would conform to Equatable, but if you want to use
the synthesised behaviour you would instead conform to AutoEquatable (or some
similar naming convention). The important distinction here being that simply
conforming to Equatable will still give you all the usual errors for failed
requirements, at which point you can either fulfil them, or switch to
AutoEquatable instead if you prefer.
This kind of standard would make sense for any protocol that wants to add
default implementations that are "invasive", i.e- delve deeper into the
concrete type than simply what the protocol itself defines as possible, i.e-
behaviours that by their very nature must make assumptions about the concrete
type. This might be fine for a protocol that is clearly defined as having such
behaviour from the start, but personally I'd rather see a standard set that has
it split off into a more specific protocol, such that we still have "pure"
protocols which remain primarily as a set of requirements.
In other words, Equatable would contain all the basic requirements and the "non
invasive" default implementations, while AutoEquatable would extend it with the
macros/special behaviour that provides the synthesised defaults, allowing a
developer to opt-in to them explicitly.
> On 10 Aug 2017, at 16:19, Tony Allevato <tony.allev...@gmail.com> wrote:
> I disagree that @transient is crucial for this feature to work—that feature
> only applies to the set of types that contain volatile data, that volatile
> data and all the other fields are all Equatable/Hashable, and the user wants
> to synthesize Eq/Hash for a subset of its fields. I certainly agree that such
> a set is non-empty, but I it's also small enough that it can be considered at
> a later date.
I disagree with your reasons for disagreeing 😛
The problem is that synthesising the behaviour for such types right now will
introduce a bug, and one that will not be exposed to developers except at
runtime, which is something that makes me very uncomfortable. To be clear, my
point is that a transient feature is a requirement now specifically because the
proposal seeks to use conforming to Equatable as sufficient as an opt-in; if a
more explicit opt-in were required then this would not be an issue, i.e- if a
developer conforms to AutoEquatable instead of Equatable, then we can assume
that they should know what that means, and should not do it unless they know
their type contains no transient values.
With that kind of absolutely explicit opt-in then, yes, a @transient attribute
or whatever can be deferred to a future feature. But with opt-in via Equatable
conformance the lack of such a feature is much more pronounced. Though like I
say, my preference is very much towards a more explicit opt-in, rather than an
attribute/keyword that developers may not realise they need to use with regular
Equatable (remember, not everyone will know that Equatable is gaining this new
> I sympathize with these concerns, and a great deal of thought and discussion
> was done around the best way to surface this feature in the last couple of
> mailing list threads about this topic. But at the time this proposal and its
> implementation were written, the synthesis for Codable had already been
> implemented and this proposal adopts the same synthesis conditions that were
> used by Codable. Core team members expressed that the implementation for
> Eq/Hash should follow those existing practices as closely as possible; I
> agreed that consistency is important so that we don't have to document
> intricate nuances between the implementations of protocol synthesis.
> Given that constraint, IMO it would be incorrect for this proposal to create
> an inconsistent set of synthesis conditions compared to Codable, and it is
> out of scope for this proposal to suggest changes to Codable. If you feel
> that synthesis should be made more explicit across Equatable, Hashable, and
> Codable, please do propose that!
The problem with using Codable as a precedent (other than the fact auto-correct
keeps trying to change it Coddle) is that it's an entirely new feature; there
is no existing, well understood protocol that developers are already using
day-to-day. Since it's new it can simply describe all of its default behaviour
and expect developers to learn that before using it, but how many developers do
we really expect to re-learn Equatable every time a new version of Swift is
released? It's also arguable that conforming to Codable is already more of an
explicit opt-in to the synthesised behaviour.
Equatable however has existing, well understood behaviour; if you don't
implement == you get an error. This proposal is going to change that without
any interaction with the developers at all; this was not an issue with Codable,
and therefore I don't think it's a sound precedent to follow.
If consistency with Codable is a requirement, then I would argue that changes
to Codable should come before this feature, e.g- split off Codable's
synthesised behaviour into AutoCodable, then implement Equatable/Hashable's as
AutoEquatable/AutoHashable afterwards, but personally I don't think it matters;
Codable was free to define its behaviour as being an intrinsic part of it from
the start, but Equatable/Hashable already exist.
swift-evolution mailing list