> On Nov 19, 2016, at 8:57 PM, John McCall <[email protected]> wrote:
> 
>> On Nov 19, 2016, at 6:03 PM, Alan Cabrera <[email protected] 
>> <mailto:[email protected]>> wrote:
>>> On Nov 19, 2016, at 4:02 PM, John McCall <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>> On Nov 19, 2016, at 3:31 PM, Alan Cabrera <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>>> On Nov 19, 2016, at 1:21 PM, John McCall <[email protected] 
>>>>> <mailto:[email protected]>> wrote:
>>>>> 
>>>>>> On Nov 19, 2016, at 10:07 AM, Alan Cabrera via swift-evolution 
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>> On Nov 19, 2016, at 9:27 AM, Jean-Daniel <[email protected] 
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>>> Le 19 nov. 2016 à 15:58, Alan Cabrera via swift-evolution 
>>>>>>>> <[email protected] <mailto:[email protected]>> a écrit 
>>>>>>>> :
>>>>>>>> 
>>>>>>>> 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.
>>>>>>>> 
>>>>>>>> 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.
>>>>>>>> 
>>>>>>> 
>>>>>>> I’d rather like a swift attribute equivalent to : 
>>>>>>> __attribute__((constructor))
>>>>>>> 
>>>>>>> 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.
>>>>>>> 
>>>>>> 
>>>>>> I’m not quite following what “__attribute__((constructor))” means; it 
>>>>>> looks like an LLVM implementation bit.  Do you mean defining a new Swift 
>>>>>> declaration attribute named “constructor”?  If so, I really 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?
>>>>>> 
>>>>>> @startup
>>>>>> func registerHandlers() {
>>>>>> }
>>>>>> 
>>>>>> 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.
>>>>>> 
>>>>>> I’m going to try goofing around with the idea on my fork.
>>>>> 
>>>>> 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.
>>>> 
>>>> Very good points.  I recognize the dangers.  However.
>>>> 
>>>> 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.
>>>> 
>>>> 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.
>>>> 
>>>> 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.  
>>>> 
>>>> Global init() functions are a clean solution to what engineers are already 
>>>> boiler plating with static singleton code.
>>> 
>>> 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.
>>> 
>>> 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.
>> 
>> 
>> 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 inevitability solely afflicting 
>> global init functions.  My and others’ experience with them has been very 
>> different from yours.
>> 
>> 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?
> 
> 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.  

Great, are there any keywords I can use to search for this thread?

> 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.

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.  Is it because the protocol information is erased after 
compilation?

> In general, this kind of straightforward compilation task — "compilation" in 
> the general sense of gathering like information from different sources — is 
> pretty easy to support and much less problematic than features that rely on 
> arbitrary code execution.

Agreed, it solves the bulk of the problems I would have solved with global init 
functions without the temptations to indulge in dangerous proclivities.


Regards,
Alan


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to