<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 29, 2016, at 1:56 PM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><div class=""><blockquote type="cite" 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-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">On Nov 29, 2016, at 1:54 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Nov 28, 2016, at 11:53 AM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Nov 19, 2016, at 8:57 PM, John McCall via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" 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:<br class=""><blockquote type="cite" 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:<br class=""><br class=""><blockquote type="cite" 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:<br class=""><blockquote type="cite" 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:<br class=""><br class=""><blockquote type="cite" 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:<br class=""><blockquote type="cite" 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:<br class=""><br class=""><br class=""><blockquote type="cite" 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 :<br class=""><br 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=""></blockquote><br class="">I’d rather like a swift attribute equivalent to : __attribute__((constructor))<br class=""><br class="">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.<br class=""><br class=""></blockquote><br class="">I’m not quite following what “__attribute__((constructor))” means; it looks like an LLVM implementation bit. &nbsp;Do you mean defining a new Swift declaration attribute named “constructor”? &nbsp;If so, I really 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?<br class=""><br class="">@startup<br class="">func registerHandlers() {<br class="">}<br class=""><br class="">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.<br class=""><br class="">I’m going to try goofing around with the idea on my fork.<br class=""></blockquote><br class="">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? 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.<br class=""></blockquote><br class="">Very good points. &nbsp;I recognize the dangers. &nbsp;However.<br class=""><br 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.<br class=""><br 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.<br class=""><br 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;<br class=""><br class="">Global init() functions are a clean solution to what engineers are already boiler plating with static singleton code.<br class=""></blockquote><br 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.<br class=""><br 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.<br class=""></blockquote><br 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 inevitability solely afflicting global init functions. &nbsp;My and others’ experience with them has been very different from yours.<br class=""><br 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?<br class=""></blockquote><br 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;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.<br class=""></blockquote><br class="">I worry that there are registration use cases for which "get all protocol conformers" is a bit boilerplatey. For example, collecting test case functions is a classic use case, and requiring a separate type declaration for every case would be a bit heavyweight compared to just having each test be a free function.<br class=""></blockquote><br class="">I agree with you, but I'm not sure that global initializers fit this use-case well either.<br class=""></blockquote><br 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=""><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="">That wasn't what I was going for, sorry for not being clear. I more meant that having another mechanism for discovering a set of declarations with a common attribute across a program might be called for besides just types with protocol conformances. Someone earlier in the thread suggested a @tag attribute; something like that could be allowed to apply not only to types but to functions as well.</span><br 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=""></div></blockquote><div><br class=""></div></div>Sure, that's a good point.<div class=""><br class=""></div><div class="">John.</div></body></html>