<div dir="ltr"><div>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?<br></div><br>```swift<br><div>@nodiscard SomeType<br>```<br><br></div><div>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?<br><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 21 Nov 2016 at 22:50 John McCall via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 20, 2016, at 6:40 AM, Alan Cabrera <<a href="mailto:adc@toolazydogs.com" class="gmail_msg" target="_blank">adc@toolazydogs.com</a>> wrote:</div><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 8:57 PM, John McCall <<a href="mailto:rjmccall@apple.com" class="gmail_msg" target="_blank">rjmccall@apple.com</a>> wrote:</div><br class="m_9193626307012584802Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 6:03 PM, Alan Cabrera <<a href="mailto:adc@toolazydogs.com" class="gmail_msg" target="_blank">adc@toolazydogs.com</a>> wrote:</div><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 4:02 PM, John McCall <<a href="mailto:rjmccall@apple.com" class="gmail_msg" target="_blank">rjmccall@apple.com</a>> wrote:</div><br class="m_9193626307012584802Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 3:31 PM, Alan Cabrera <<a href="mailto:adc@toolazydogs.com" class="gmail_msg" target="_blank">adc@toolazydogs.com</a>> wrote:</div><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 1:21 PM, John McCall <<a href="mailto:rjmccall@apple.com" class="gmail_msg" target="_blank">rjmccall@apple.com</a>> wrote:</div><br class="m_9193626307012584802Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 10:07 AM, Alan Cabrera via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:</div><div class="gmail_msg"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 19, 2016, at 9:27 AM, Jean-Daniel <<a href="mailto:dev@xenonium.com" class="gmail_msg" target="_blank">dev@xenonium.com</a>> wrote:</div><br class="m_9193626307012584802Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">Le 19 nov. 2016 à 15:58, Alan Cabrera via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> a écrit :</div><br class="m_9193626307012584802Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I’m not sure if this was proposed or not; or even if this is a Swift-ly way of doing things. It would be pretty handy to be able to declare init() functions in my module to register handlers. It’s a common pattern in enterprise software.<br class="gmail_msg"><br class="gmail_msg">Currently, I have to generate a lot of boilerplate code to emulate the behavior. I think it would be cleaner to have these global init() functions.<br class="gmail_msg"><br class="gmail_msg"></div></div></blockquote><br class="gmail_msg"></div><div class="gmail_msg">I’d rather like a swift attribute equivalent to : <span class="m_9193626307012584802pln gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">__attribute__</span><span class="m_9193626307012584802pun gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">((</span><span class="m_9193626307012584802kwd gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(16,16,148)">constructor</span><span class="m_9193626307012584802pun gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">))</span></div><div class="gmail_msg"><span class="m_9193626307012584802pun gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)"><br class="gmail_msg"></span></div><div class="gmail_msg"><span class="m_9193626307012584802pun gmail_msg" style="white-space:inherit;margin:0px;padding:0px;border:0px">It will not force me to call my initializer init, and moreover it will let me declare multiple functions so I would be able to register multiples handlers from a single module without having to group all the register call into a single init() function.</span></div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">I’m not quite following what “<span class="m_9193626307012584802pln gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">__attribute__</span><span class="m_9193626307012584802pun gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">((</span><span class="m_9193626307012584802kwd gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(16,16,148)">constructor</span><span class="m_9193626307012584802pun gmail_msg" style="font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono','Courier New',monospace,sans-serif;white-space:inherit;font-size:13px;margin:0px;padding:0px;border:0px;color:rgb(48,51,54)">))</span>” means; it looks like an LLVM implementation bit. Do you mean defining a new Swift declaration attribute named “constructor”? If so, I<span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span><i class="gmail_msg"><b class="gmail_msg">really</b></i><span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span>like that idea. I think that the specific attribute name “constructor” may be a bit confusing though, since it’s not really constructing anything specific. Maybe “startup” would be a more descriptive attribute name?</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="gmail_msg"></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">@startup</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">func registerHandlers() {</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">}</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="gmail_msg"></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">The attribute would also help the compiler and IDEs prevent direct calling of the startup functions, thus reinforcing/focusing the startup functions’ role as global startup functions. Maybe global teardown functions would be helpful as well.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="gmail_msg"></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">I’m going to try goofing around with the idea on my fork.</div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div>Some sort of reflective discovery would be better, I think. Eager global initialization is superficially attractive — what could be simpler than just running some code at program launch? — but as a program scales up and gains library dependencies, it very quickly runs into problems. What if an initializer depends on another already having been run? What if an initializer needs to be sensitive to the arguments or environment? What if an initializer need to spawn a thread? What if an initializer needs to do I/O? What if an initializer fails? Global initialization also has a lot of the same engineering drawbacks as global state, in that once you've introduced a dependency on it, it's extremely hard to root that out because entire APIs get built around the assumption that there's no need for an explicit initialization/configuration/whatever step. And it's also quite bad for launch performance — perhaps not important for a server, but important for pretty much every other kind of program — since every subsystem eagerly initializes itself whether it's going to be used or not, and that initialization generally has terrible locality.</div></div></div></blockquote><br class="gmail_msg"></div><div class="gmail_msg">Very good points. I recognize the dangers. However.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Don’t these problems already exist given that user code can still execute at program startup? It cannot be denied that the pattern is used and is extremely useful though, as you point out above, it should be used carefully. Thinking on it, there are always pros and cons to most language features and one relies on best practices to avoid shooting oneself in the foot. For each of the specters listed above, there are simple accepted practices that can be adopted to avoid them; most of those practices are already being employed for other situations.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">And the pattern is not just useful in enterprise software. Complex applications’ app-delegate did-finish-launching methods are chucked full of hand stitched roll calls to framework initialization code. This needlessly places a brittle dependency/burden on the application developer in what should be a simple behind the scenes collaboration.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">One could argue that such a thing was never needed before. I would point to CocoaPods, Carthage, and the other influx of enterprise influenced tooling and frameworks. Today’s mobile applications are no longer simply todo apps. </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Global init() functions are a clean solution to what engineers are<span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span><b class="gmail_msg"><i class="gmail_msg">already</i></b><span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span>boiler plating with static singleton code.</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">No, they aren't a clean solution for the reasons I listed. They may be a solution you're used to using, but they're not a *clean* solution, and Swift's line against providing them is for the best.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I'm surprised that you keep talking about enterprise / complex applications as some sort of argument for them, because those are exactly the applications where, in my experience, global initializers completely break down as a reasonable approach. It's the small applications that can get away with poor software engineering practices, because the accumulated maintenance/complexity/performance costs are, well, small.</div></div></div></blockquote></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It’s difficult to subscribe to the slippery slope arguments that contain specters that can still afflict applications without global init functions. Any feature can be abused and it seems hyperbolic to provide arguments that seems to ascribe the above problems as an<span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span><i class="gmail_msg">inevitability</i><span class="m_9193626307012584802Apple-converted-space gmail_msg"> </span>solely afflicting global init functions. My and others’ experience with them has been very different from yours.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">With that said, I took some time to re-read your reply, after my afternoon nap. I really like the idea of some kind of reflective discovery. How would that work? Maybe having a special @tag attribute that can be searched at runtime?</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">There was another thread that mentioned this idea recently, but it would be reasonable to provide some way to get a P.Type for every type in the program that conforms to a protocol P. </span></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div class="gmail_msg">Great, are there any keywords I can use to search for this thread?</div></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">This would be opt-in at the protocol level, because we wouldn't want to be prevented from e.g. stripping an unused type from the program just because it implemented Equatable. There are some other complexities here, but that's the basic idea, and it's totally reasonable to support.</span></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div>Does the other thread go into detail about this? I’m not sure that I follow why it should be opt-in as opposed to simply searching for all implementations of a specific protocol.</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">We would want this to be opt-in on the protocol because it would inhibit removing a conforming type from the program. The compiler can ordinarily remove types that you never directly use, and that's an important optimization when e.g. linking in large libraries that you only use a small part of. We wouldn't want to lose the ability to do that just because a type implemented Equatable or Collection, because a lot of types implement those protocols, and the ability to iterate all those types is probably not very useful — certainly it isn't useful enough to justify losing that optimization. In contrast, when there's a protocol that is useful to iterate over all the conformances of, like a Deserializable protocol that registers types with a deserialization engine, you always certainly know that when you're defining the protocol.</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">John.</div></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>