Sent from my iPad
> On Sep 7, 2017, at 7:45 AM, Tony Allevato <tony.allev...@gmail.com> wrote: > > Right, let's make sure we're talking about the right thing here. Gwendal, > your issue isn't with synthesis in the form of Codable or the new additions > to Equatable/Hashable which are opt-in-by-conformance, it's with the specific > case of raw value enums or enums without associated values where the > synthesis is implicit with no way to opt-out. That's a big difference. > > I can definitely see the latter being an issue if it were more widespread, > and I'd be supportive of those enums being required to declare their > conformance for consistency (though it would be source breaking). Ahh, thanks for clearing that up Tony. I missed this. I agree that this could be problematic in some cases (as Gwendal found) and should be fixed. Now that we have a well established model for synthesis we should follow it consistently. > > However, I still haven't seen a real issue that has come up because of the > distinction being drawn here between default implementations vs. > implementations that can access other parts of the concrete type. It sounds > like this discussion is trying to protect against a hypothetical problem that > hasn't happened yet and may not happen; it would be helpful to show some > motivating real-world cases where this is indeed a severe problem. >> On Thu, Sep 7, 2017 at 5:37 AM Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote: >> >> >> Sent from my iPad >> >>> On Sep 7, 2017, at 7:07 AM, Gwendal Roué via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> >>> Hello, >>> >>> I'm interested in this debate because I've been bitten by automatic >>> synthesis recently. >>> >>> I'm reading your discussion, but I don't have a strong opinion. I only have >>> an anecdote: implicit, automatic, and unavoidable code synthesis code can >>> make it difficult to write some DSLs (aka Domain-Specific Languages). >>> >>> I did stumble against undesired Equatable synthesis while developping a >>> library[1] that generates SQL snippets. In this library, the `==` operator >>> does not return a Bool: it returns an SQL expression: >>> >>> // SELECT * FROM players WHERE bestScore = 1000 >>> Player.filter(bestScore == 1000) >>> >>> Since the library is free to define == as an operator that returns an SQL >>> expression, this works quite well. Even when both operands have the same >>> type: >>> >>> // SELECT * FROM players WHERE lastScore = bestScore >>> Player.filter(lastScore == bestScore) >>> >>> However, as soon as the type is (also) Equatable, an ambiguity occurs, and >>> the DSL is basically broken: >>> >>> Player.filter(lastScore == bestScore) // which == please? >>> >>> In this case, the == from synthesized Equatable conformance is not welcome >>> at all. It prevents the library from controlling the return type of the == >>> operator. Equatable conformance is unavoidable for enums based on String or >>> generally any raw value type that adopts Equatable. The consequence is that >>> my library can't allow its users to define an enum of table columns. >>> >>> This is not a deal breaker. Everybody can live with this little caveat, and >>> I guess I'm the only one who wishes things had been more *consistent*. But >>> still: this story helps realizing that code synthesis can bite in plenty of >>> unexpected ways. >> >> I don't understand what this has to do with synthesized Equatable. Wouldn't >> manually implemented Equatable have the same impact? The design of a DSL >> should be able to accommodate conformance to basic protocols without >> ambiguity. >> >> We generally want as many types to be Equatable and Hashable as possible. >> Synthesized conformance means more types will have these conformance and >> that's a good thing in all cases (so long as the implementation is correct). >> >> >>> >>> Thanks for reading, >>> Gwendal Roué >>> [1] http://github.com/groue/GRDB.swift >>> >>>>> Le 7 sept. 2017 à 12:20, Haravikk via swift-evolution >>>>> <swift-evolution@swift.org> a écrit : >>>>> >>>>> >>>>>> On 7 Sep 2017, at 00:11, Brent Royal-Gordon <br...@architechies.com> >>>>>> wrote: >>>>>> >>>>>> On Sep 5, 2017, at 1:02 PM, Haravikk via swift-evolution >>>>>> <swift-evolution@swift.org> wrote: >>>>>> >>>>>> This proposal idea is essentially for a new attribute @synthetic (name >>>>>> is up for debate). This attribute is required for any default >>>>>> implementation that includes reflective type compiler magic, use of the >>>>>> reflection API against `self` or, in future, any native Swift macros >>>>>> within the method (possibly limited to specific features, will depend on >>>>>> the macro language and its capabilities). >>>>> >>>>> >>>>> "Use of the reflection API against `self`"? `String(describing:)` and >>>>> `String(reflecting:)` sometimes do that. >>>>> >>>>> I see zero justification for having @synthetic cover all of these random >>>>> things, but not ordinary default implementations—they have the same >>>>> amount of dangerous implicitness. >>>> >>>> Actually they don't; the problem here is that through reflection you are >>>> accessing and manipulating concrete types. A non-reflective default >>>> implementation only has access to what the protocol itself has defined. >>>> The synthetic alternatives are instead diving into parts of a concrete >>>> type that may have nothing to do with the protocol at all, and must >>>> therefore make assumptions that cannot be guaranteed to be correct, this >>>> is what makes them dangerous. >>>> >>>>>> On 6 Sep 2017, at 23:43, Nevin Brackett-Rozinsky >>>>>> <nevin.brackettrozin...@gmail.com> wrote: >>>>>>> On Wed, Sep 6, 2017 at 5:42 PM, Haravikk via swift-evolution >>>>>>> <swift-evolution@swift.org> wrote: >>>>>>> the issue I'm trying to raise is that when those, and similar features, >>>>>>> are used in synthesised behaviour (default implementations based upon >>>>>>> the concrete type), that these behaviours should be opted into >>>>>>> explicitly, otherwise they open up potential for all kinds of bugs, >>>>>>> even when the assumptions being made about the concrete type are simple >>>>>>> such as in the case for Equatable/Hashable. There's just too much >>>>>>> potential for this kind of reflective protocol implementation to >>>>>>> overreach; to me it feels very much like going into a restaurant and >>>>>>> the waiter coming across and force-feeding me something I don't want >>>>>>> instead of taking my order. >>>>> >>>>> I might suggest that instead it is like you have gone into a pizza shop >>>>> and said, “I’d like a large veggie pizza please.” And they made you a >>>>> pizza with their standard dough and their standard sauce and their >>>>> standard cheese and their standard selection of vegetables. >>>> >>>> Actually I don't think that's quite it either; to strain the analogy even >>>> further, I'd say it's more like going into a pizza shop and saying "I'd >>>> like a pizza" and the staff looking at you and deciding you look like a >>>> vegetarian and giving you a vegetarian pizza. >>>> >>>> The crux of the issue here are the assumptions that are being made; for a >>>> standard default implementation there are no assumptions, because you're >>>> operating on the basis of methods and properties that you yourself have >>>> defined as the protocol creator that, where properly implemented, have >>>> precisely defined requirements, behaviours etc. When you're doing it with >>>> some form of compile-time or run-time reflection however you're messing >>>> around with parts of a concrete type that the protocol itself doesn't >>>> actually know anything about with any certainty. >>>> >>>> It's the same reason that run-time reflection isn't something you should >>>> ever want to do, because while it might work with all of the types you >>>> test directly, if it supports arbitrary types (which it'd need to, or >>>> there'd be no point to reflecting) then there's always the risk of >>>> encountering a type where some part of it doesn't match the assumptions >>>> that you've made. Of course there are use-cases where this may not matter, >>>> e.g- if you're just dumping data from a type and don't really care if >>>> you're storing stuff that isn't important, but in other cases such as >>>> Equatable and Hashable it can make a difference, as it can drastically >>>> affect behaviour when those assumptions fail. >>>> >>>>> On 7 Sep 2017, at 05:00, Andrew Thompson <mrwerdo...@me.com> wrote: >>>>> Perhaps we could find a solution by meeting in the middle. Introduce a >>>>> compiler flag that will disable the automatic synthesis and revert to the >>>>> old behaviour (i.e. swiftc main.swift —disable-automatic-synthesis ) >>>> >>>> Thanks for the suggestion, but that's a bit too all-or-nothing; I realise >>>> I might seem very negative but to be clear, I do want these synthesised >>>> features, I just don't want them in their current form. What I want is for >>>> them to be explicitly opted into where I, as the developer, need them to >>>> be, so that I'm in absolute, unambiguous control of when and where they >>>> are used. >>>> >>>> I do absolutely support features that eliminate tedious boiler-plate, I >>>> just think that doing so implicitly in invasive ways is not the right way >>>> to do it. >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> swift-evolution@swift.org >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org >> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution