Yes, these are some really useful insights, thanks. On Mon, 28 Nov 2016 at 01:58 John McCall <[email protected]> wrote:
> > On Nov 25, 2016, at 7:59 AM, Jay Abbott <[email protected]> wrote: > > Why not just say that this doesn't affect the removal of types (i.e. > they can still be discarded) and add something to prevent specific types > being discarded even if they're not statically used? > > > > ```swift > > @nodiscard SomeType > > ``` > > > > This way, rather than a protocol opting in that anything implementing it > is automatically `@nodiscard` a program or library would declare some types > as non-discardable and could safely say "there will be at least 1 > SomeProtocol" available" without saying what specific type it is in the > public interface/docs? > > In language design, we usually find that semantic annotations (which tell > us what the programmer is trying to do) are superior to imperative > annotations (which order the compiler to do something without much > explanation why). They allow the implementation to provide a better > programming experience (e.g. giving useful diagnostics about likely errors > and selecting more thoughtful default behaviors), they're easier to apply > sensibly to new language constructs, and they allow better optimization > with fewer unintended side-effects. All of that applies here as well. > > In this case, because it's really *the conformance of a type to a specific > protocol* that should not be stripped, tying the annotation to the protocol > is the more semantic approach, and as expected, it has a number of > benefits. Let's dig in to why. > > First, if the annotation has to be on every conforming type, there's an > easy error of omission that could lead to bugs. The really unfortunate > thing here is that it often *won't* lead to bugs, because you'll only miss > it if the type is actually stripped, and there might be all sorts of > reasons why a type that's "really" unused is not stripped — maybe the > implementation isn't running the analysis at all (which it probably won't > in unoptimized builds), or maybe the implementation of the analysis just > isn't very good, or maybe you have test code that still uses the type, or > maybe there's some old code still linked into the project. We really don't > want to encourage a situation where e.g. you have an old implementation of > a library sitting around, and you really want to delete it but you can't > because when you do it breaks the build (but only in release mode), and two > years later someone actually has the time to look into it and figures out > that it's because you were missing this annotation on a bunch of types. > > In contrast, if the annotation is on the protocol, it's really easy to > check at the point of iterating over a protocol's conformances that the > protocol has the right attribute. And in fact, we can use this iteration > as the "root" use of all the conformances, so that e.g. if we can prove > that nothing in the program actually iterates the conformances of that > specific protocol, we can go back to dropping them. > > Second, if the annotation is on types, it's unclear what exactly about the > type can't be stripped. Do we have to keep all of its code around just in > case something unexpectedly links to it? Do we have to keep around every > protocol conformance it has? What does that mean if we add the ability to > synthesize protocol conformances, or imply conformances post-hoc from other > conformances? > > So that's why this belongs on the protocol, and I hope the discussion > gives you an idea of how to approach similar problems in the future. > > John.
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
