> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[email protected]>:
> 
> 
> As you may know, smalltalk global dictionary contain all symbols defined 
> globally,
> so you can access them directly in any piece of code i.e. when you write:
> 
> Object new
> 
> it actually means 'send message #new to object, associated with #Object name 
> in globals dictionary.
> 
> Most of globals are classes, but some of them , like Transcript, World, 
> Display etc are not.
> And i was always thinking there's something wrong with these globals 
> (actually there's multiple 'wrongs'), but finally, i think i can answer 
> myself, what is most basic wrong with them: they miss any form of declaration.
> 
> Most of variables in smalltalk require declaration, such as temps, method 
> arguments, instance variables , class variables, pool variables,
> but not globals.
> Even classes, from formal point of view do not require declaration,
> because actually the usual:
> 
> Object subclass: #Collection
>     instanceVariableNames: ''
>     classVariableNames: 'MutexForPicking RandomForPicking'
>     poolDictionaries: ''
>     category: 'Collections-Abstract'
> 
> is _definition_ but not declaration:
> 
> Collection definition =>
> 
> 'Object subclass: #Collection
>     instanceVariableNames: ''''
>     classVariableNames: ''MutexForPicking RandomForPicking''
>     poolDictionaries: ''''
>     category: ''Collections-Abstract''' 
> 
> in fact, it is just a message sent to 'Object' variable (at some moment in 
> the past) , and there's nothing 
> in language which enforces the rule that evaluating such expression must 
> declare new global, named Collection, except from environment we're working 
> in.
> 
> The absence of declaration for globals leads to following problems:
> since declaration point is not defined, all tools (including compiler) assume 
> that given name always been there, and always accessible. Which leads to 
> bootstrap problems.
> There's no way to determine if given piece of code (which uses some global) 
> will keep functioning properly, once you unload certain package. No way to 
> determine dependencies (and as consequence the order of code loading during 
> bootstrapping).
> Also, it is hard to determine, to which package certain global belongs. While 
> it is easy to tell for classes since they having category, for globals like 
> Transcript, Display etc, there's no way to tell anything. 
> Piece of cake, you can say:  since Display is instance of DisplayScreen 
> class, then such variable must belong to same package as DisplayScreen, right?
> Wrong! 
> Just for example, imagine i create variable named MyWindowMousePosition, 
> which will contain an instance of Point. Does it means that such variable 
> should belong to same package as Point class? I guess not.
> 
> So, to sum up, i think we should really think how to introduce a way to 
> declare globals in package-based ecosystem, where each global belongs to 
> certain package, and then since packages form dependency hierarchy, you can 
> easily detect whether you allowed to use certain global in given context or 
> not,
> to prevent forming dependency loops.
> But even if we will weaken contract and allow having dependency loops, even 
> in such case declarations can help us to clearly tell which pieces of code 
> will stop functioning properly, if package which declares given variable are 
> not present in system.
> 
> The last aspect of bootstrapping problem is order of initialization,
> because declaring variable doesn't means you can use it right away,
> since it may be not properly initialized yet (otherwise we will be forced to 
> always use lazy initialization pattern).
> 
> From this perspective, IMO package should not only have unordered list of 
> classes/symbols it declares/defines, but also contain information in which 
> order they must be initialized while loaded.
> From other side, i don't really like introducing too much formalism and 
> rules, and keep them as minimal as possible, following smalltalk spirit.
> 
> What  you think?

I think packages should be first class citizens. A package once loaded provides 
an environment/namespace/... that declares all the (exported) symbols that 
should be accesible global. The smalltalk dictionary should rather be a list of 
those namespaces/environments/... A package should also have an initialize 
method where you could specify order of class initialization if necessary ( and 
other things). Furthermore I would like to see class initializers idempotent. 
So when loading a package the package initialize is invoked first and then the 
class initializers, As they are idempotent a possible double invocation is not 
a problem. 
Dependencies are always hard. I would start thinking about metacello defining 
all the possible dependencies regarding platforms, platform versions etc. At 
load time there is only one dependency graph and that could be reflected by the 
system. And this graph is not dependent on the tool that loaded the code.
With this in place unloading should be rather easy. Dependencies can warn the 
user about an harmful action and when the namespace is removed all global 
definitions are automaticall removed. 

That is what I think. But I also think that there should be a possibility to 
load something that doesn't end being global. A way to load a package that 
isn't added to the global namespace (smalltalk dictionary) but to a package 
namespace would also be very good. Not everything needs to global but we can 
only load global things. That is a flaw in my opinion. And it prevents cool 
things like loading multiple versions of a code in separate packages.

Norbert

Reply via email to