<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Nov 20, 2016, at 6:40 AM, Alan Cabrera &lt;<a href="mailto:adc@toolazydogs.com" class="">adc@toolazydogs.com</a>&gt; wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 8:57 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 6:03 PM, Alan Cabrera &lt;<a href="mailto:adc@toolazydogs.com" class="">adc@toolazydogs.com</a>&gt; wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 4:02 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 3:31 PM, Alan Cabrera &lt;<a href="mailto:adc@toolazydogs.com" class="">adc@toolazydogs.com</a>&gt; wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 1:21 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 10:07 AM, Alan Cabrera via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 9:27 AM, Jean-Daniel &lt;<a href="mailto:dev@xenonium.com" class="">dev@xenonium.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 19 nov. 2016 à 15:58, Alan Cabrera via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><div class="">I’m not sure if this was proposed or not; or even if this is a Swift-ly way of doing things. &nbsp;It would be pretty handy to be able to declare init() functions in my module to register handlers. &nbsp;It’s a common pattern in enterprise software.<br class=""><br class="">Currently, I have to generate a lot of boilerplate code to emulate the behavior. &nbsp;I think it would be cleaner to have these global init() functions.<br class=""><br class=""></div></div></blockquote><br class=""></div><div class="">I’d rather like a swift attribute equivalent to :&nbsp;<span class="pln" 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="pun" 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="kwd" 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="pun" 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=""><span class="pun" 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=""></span></div><div class=""><span class="pun" 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=""><br class=""></div></div></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">I’m not quite following what “<span class="pln" 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="pun" 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="kwd" 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="pun" 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. &nbsp;Do you mean defining a new Swift declaration attribute named “constructor”? &nbsp;If so, I<span class="Apple-converted-space">&nbsp;</span><i class=""><b class="">really</b></i><span class="Apple-converted-space">&nbsp;</span>like that idea. &nbsp;I think that the specific attribute name “constructor” may be a bit confusing though, since it’s not really constructing anything specific. &nbsp;Maybe “startup” would be a more descriptive attribute name?</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">@startup</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">func registerHandlers() {</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">}</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">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. &nbsp;Maybe global teardown functions would be helpful as well.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">I’m going to try goofing around with the idea on my fork.</div></div></blockquote><div class=""><br class=""></div>Some sort of reflective discovery would be better, I think. &nbsp;Eager global initialization is superficially attractive — what could be simpler than just running some code at program launch? — &nbsp;but as a program scales up and gains library dependencies, it very quickly runs into problems. &nbsp;What if an initializer depends on another already having been run? &nbsp;What if an initializer needs to be sensitive to the arguments or environment? &nbsp;What if an initializer need to spawn a thread? &nbsp;What if an initializer needs to do I/O? &nbsp;What if an initializer fails? &nbsp;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. &nbsp;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=""></div><div class="">Very good points. &nbsp;I recognize the dangers. &nbsp;However.</div><div class=""><br class=""></div><div class="">Don’t these problems already exist given that user code can still execute at program startup? &nbsp;It cannot be denied that the pattern is used and is extremely useful though, as you point out above, it should be used carefully. &nbsp;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. &nbsp;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=""><br class=""></div><div class="">And the pattern is not just useful in enterprise software. &nbsp;Complex applications’ app-delegate did-finish-launching methods are chucked full of hand stitched roll calls to framework initialization code. &nbsp;This needlessly places a brittle dependency/burden on the application developer in what should be a simple behind the scenes collaboration.</div><div class=""><br class=""></div><div class="">One could argue that such a thing was never needed before. &nbsp;I would point to CocoaPods, Carthage, and the other influx of enterprise influenced tooling and frameworks. &nbsp;Today’s mobile applications are no longer simply todo apps. &nbsp;</div><div class=""><br class=""></div><div class="">Global init() functions are a clean solution to what engineers are<span class="Apple-converted-space">&nbsp;</span><b class=""><i class="">already</i></b><span class="Apple-converted-space">&nbsp;</span>boiler plating with static singleton code.</div></div></div></blockquote><div class=""><br class=""></div><div class="">No, they aren't a clean solution for the reasons I listed. &nbsp;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=""><br class=""></div><div class="">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. &nbsp;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=""><br class=""></div><div class="">It’s difficult to subscribe to the slippery slope arguments that contain specters that can still afflict applications without global init functions. &nbsp;Any feature can be abused and it seems hyperbolic to provide arguments that seems to ascribe the above problems as an<span class="Apple-converted-space">&nbsp;</span><i class="">inevitability</i><span class="Apple-converted-space">&nbsp;</span>solely afflicting global init functions. &nbsp;My and others’ experience with them has been very different from yours.</div><div class=""><br class=""></div><div class="">With that said, I took some time to re-read your reply, after my afternoon nap. &nbsp;I really like the idea of some kind of reflective discovery. &nbsp;How would that work? &nbsp;Maybe having a special @tag attribute that can be searched at runtime?</div></div></div></blockquote><div class=""><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">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. &nbsp;</span></div></blockquote><div class=""><br class=""></div><div class=""><div class="">Great, are there any keywords I can use to search for this thread?</div></div><br class=""><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">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. &nbsp;There are some other complexities here, but that's the basic idea, and it's totally reasonable to support.</span></div></blockquote><div class=""><br class=""></div>Does the other thread go into detail about this? &nbsp;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><br class=""></div><div>We would want this to be opt-in on the protocol because it would inhibit removing a conforming type from the program. &nbsp;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. &nbsp;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. &nbsp;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><br class=""></div><div>John.</div></div></body></html>