Another thought about globals

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Another thought about globals

Igor Stasenko

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?

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Goubier Thierry
Hi Igor,

What about scanning for globals in the code? And just a proper way to declare globals somewhere in a package should be about enough (loading scripts can take care of the initialisation, no?).

Or... All globals are classes, or accessed via classes (singleton pattern). Like that you get everything correct (loading order, package ownership, initialization) and you don't have to create new rules, just produce better code. Would you have a counter example to that ? (i.e. a currently existing Global in Pharo which cannot be reimplemented as a class with some state in it?)

Thierry

De : Pharo-dev [[hidden email]] de la part de Igor Stasenko [[hidden email]]
Date d'envoi : samedi 14 décembre 2013 05:41
À : Discusses Development of Pharo
Objet : [Pharo-dev] Another thought about globals


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?

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl
In reply to this post by Igor Stasenko


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

kilon.alios
why we need globals anyway ? why not use classes instead ? 

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Sergi Reyner
kilon alios wrote
I think it would make even the transition from workspace to browser easier,
or even completely replace workspace with the browser.

I always found workspace unnecessary anyway.
It may be that I am still too unfamiliar with Smalltalk, but I cannot see how removing the Workspace would be a good thing.

Cheers,
Sergi
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Sergi Reyner
Sergi Reyner wrote
kilon alios wrote
I think it would make even the transition from workspace to browser easier,
or even completely replace workspace with the browser.

I always found workspace unnecessary anyway.
It may be that I am still too unfamiliar with Smalltalk, but I cannot see how removing the Workspace would be a good thing.

Cheers,
Sergi

PS: my bad, I thought I was already subscribed to the pharo-dev mailing list :S
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl
In reply to this post by kilon.alios

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

kilon.alios
yes sorry i meant global variables , the ones you define in workspace like a := 1. 


On Sat, Dec 14, 2013 at 4:30 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl

Am 14.12.2013 um 15:58 schrieb kilon alios <[hidden email]>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

Norbert


On Sat, Dec 14, 2013 at 4:30 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

kilon.alios
ah ok my bad, I learned something new, thank you. Is it possible to embed this method to a new class ? lets say i like what i did in workspace and send it directly to a new class. 


On Sat, Dec 14, 2013 at 5:15 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 15:58 schrieb kilon alios <[hidden email]>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

Norbert


On Sat, Dec 14, 2013 at 4:30 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl

Am 14.12.2013 um 16:17 schrieb kilon alios <[hidden email]>:

ah ok my bad, I learned something new, thank you. Is it possible to embed this method to a new class ? lets say i like what i did in workspace and send it directly to a new class. 

Sure. You might never heard of it but we call it copy&paste. Works like charm. You just press cmd-a then cmd-c….

Or you decorate the content in the workspace with „MyClass compile: ‚methodName

[workspace content] ‚

Norbert

 
On Sat, Dec 14, 2013 at 5:15 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 15:58 schrieb kilon alios <[hidden email]>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

Norbert


On Sat, Dec 14, 2013 at 4:30 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

kilon.alios
there is a copy paste ? wow pharo really rocks. 

Thanks I will take a look at compile method. 


On Sat, Dec 14, 2013 at 5:47 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 16:17 schrieb kilon alios <[hidden email]>:

ah ok my bad, I learned something new, thank you. Is it possible to embed this method to a new class ? lets say i like what i did in workspace and send it directly to a new class. 

Sure. You might never heard of it but we call it copy&paste. Works like charm. You just press cmd-a then cmd-c….

Or you decorate the content in the workspace with „MyClass compile: ‚methodName

[workspace content] ‚

Norbert

 
On Sat, Dec 14, 2013 at 5:15 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 15:58 schrieb kilon alios <[hidden email]>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

Norbert


On Sat, Dec 14, 2013 at 4:30 PM, Norbert Hartl <[hidden email]> wrote:

Am 14.12.2013 um 12:09 schrieb kilon alios <[hidden email]>:

why we need globals anyway ? why not use classes instead ? 


Class names are globals. A class is registered in a global namespace by its name. Names need to be looked up. How should it work in another way?

Norbert

The only use I see of globals is in workspace and I am sure we could find a way to automate or make the creation of classes faster inside workspace instead of using globals. Since OO is the very foundation of Pharo I don't see why one would need globals anyway. If that forces us to make object more flexible so be it. Way better than creating concepts that works with this tools and not work with the other tool or could work if you do this and that , ending up making things more complex than they need to be. 

I think it would make even the transition from workspace to browser easier, or even completely replace workspace with the browser. 

I always found workspace unnecessary anyway.   


On Sat, Dec 14, 2013 at 12:47 PM, Norbert Hartl <[hidden email]> wrote:


> Am 14.12.2013 um 05:41 schrieb Igor Stasenko <[hidden email]>:
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Marcus Denker-4
In reply to this post by NorbertHartl

On 14 Dec 2013, at 16:15, Norbert Hartl <[hidden email]> wrote:


Am 14.12.2013 um 15:58 schrieb kilon alios <[hidden email]>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

They live in the “bindings” ivar of Workspace.

When you compile code with the “requestor” not nil, it will put a OCRequestorScope into the scope chain.
This means that when Opal Semantic analysis asks the scope for the definition of a name, it will call
#lookupVar: on that scope, which is then doing:

(requestor bindingOf: name asSymbol) ifNotNil: [:assoc | 
^ OCLiteralVariable new assoc: assoc; scope: self; yourself].
^ super lookupVar: name.

Which means that variables in the Workspace are compiled as literal variables (like globals),
but the binding comes from a dictionary that is in the ivar “bindings” of the Workspace.

Marcus
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

philippeback
Would be nice to have a view on them like in VW. 

On Saturday, December 14, 2013, Marcus Denker wrote:

On 14 Dec 2013, at 16:15, Norbert Hartl <<a href="javascript:_e({}, &#39;cvml&#39;, &#39;norbert@hartl.name&#39;);" target="_blank">norbert@...> wrote:


Am 14.12.2013 um 15:58 schrieb kilon alios <<a href="javascript:_e({}, &#39;cvml&#39;, &#39;kilon.alios@gmail.com&#39;);" target="_blank">kilon.alios@...>:

yes sorry i meant global variables , the ones you define in workspace like a := 1. 

Those aren’t globals. Everything you do in the workspace is compiled as method (UndefinedObect>>#DoIt) and executed. There are only a handful of global values and there is the smalltalk dictionary where names can be looked up.

They live in the “bindings” ivar of Workspace.

When you compile code with the “requestor” not nil, it will put a OCRequestorScope into the scope chain.
This means that when Opal Semantic analysis asks the scope for the definition of a name, it will call
#lookupVar: on that scope, which is then doing:

(requestor bindingOf: name asSymbol) ifNotNil: [:assoc | 
^ OCLiteralVariable new assoc: assoc; scope: self; yourself].
^ super lookupVar: name.

Which means that variables in the Workspace are compiled as literal variables (like globals),
but the binding comes from a dictionary that is in the ivar “bindings” of the Workspace.

Marcus


--
---
Philippe Back
Dramatic Performance Improvements
Mob: +32(0) 478 650 140 | Fax: +32 (0) 70 408 027
Blog: http://philippeback.be | Twitter: @philippeback

High Octane SPRL
rue cour Boisacq 101 | 1301 Bierges | Belgium

Pharo Consortium Member - http://consortium.pharo.org/
Featured on the Software Process and Measurement Cast - http://spamcast.libsyn.com
Sparx Systems Enterprise Architect and Ability Engineering EADocX Value Added Reseller
 


Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

ccrraaiigg
In reply to this post by NorbertHartl

Hi Norbert--

> Class names are globals. A class is registered in a global namespace
> by its name. Names need to be looked up. How should it work in
> another way?

     Get rid of globals. Make the root classes elements of the special
objects array (Object already is), and look up classes through that.
Make everything else that used to be a global (like Transcript) the
responsibility of some class, and use them by sending messages. This
also makes the modularization straightforward.

     There's no need for a system dictionary. It was a profound and
long-lived mistake.


-C

--
Craig Latta
www.netjam.org/resume
+1 510 984 8117
(Skype rings this until 31 January 2014)


Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

kilon.alios

Yes thats exactly what I meant with my reply. I was not so sure though about the exact role of globals in pharo and how many problems their removal would cause internally.

Στις 14 Δεκ 2013 9:39 μ.μ., ο χρήστης "Craig Latta" <[hidden email]> έγραψε:

Hi Norbert--

> Class names are globals. A class is registered in a global namespace
> by its name. Names need to be looked up. How should it work in
> another way?

     Get rid of globals. Make the root classes elements of the special
objects array (Object already is), and look up classes through that.
Make everything else that used to be a global (like Transcript) the
responsibility of some class, and use them by sending messages. This
also makes the modularization straightforward.

     There's no need for a system dictionary. It was a profound and
long-lived mistake.


-C

--
Craig Latta
www.netjam.org/resume
<a href="tel:%2B1%20510%20984%208117" value="+15109848117">+1 510 984 8117
(Skype rings this until 31 January 2014)


Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Stéphane Ducasse
In reply to this post by ccrraaiigg
> Hi Norbert--
>
>> Class names are globals. A class is registered in a global namespace
>> by its name. Names need to be looked up. How should it work in
>> another way?
>
>     Get rid of globals. Make the root classes elements of the special
> objects array (Object already is), and look up classes through that.
> Make everything else that used to be a global (like Transcript) the
> responsibility of some class, and use them by sending messages. This
> also makes the modularization straightforward.

This is what we did with
        Smalltalk -> self environment.
        Smalltalk -> SmalltalkImage current

Now I wonder if it really solves the problem that has igor (this is true that I would prefer to avoid to
have specific declaration.
Now what would be good is to have a protocol to systematically initialize such "global" even when they
are attached to classes.

>     There's no need for a system dictionary. It was a profound and
> long-lived mistake.

In the midterm I want to get rid of it (by splitting it and distributing into module) but it will take
time.
Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl
In reply to this post by ccrraaiigg


> Am 14.12.2013 um 20:38 schrieb Craig Latta <[hidden email]>:
>
>
> Hi Norbert--
>
>> Class names are globals. A class is registered in a global namespace
>> by its name. Names need to be looked up. How should it work in
>> another way?
>
>     Get rid of globals. Make the root classes elements of the special
> objects array (Object already is), and look up classes through that.
> Make everything else that used to be a global (like Transcript) the
> responsibility of some class, and use them by sending messages. This
> also makes the modularization straightforward.
>
>     There's no need for a system dictionary. It was a profound and
> long-lived mistake.
>
Sure. What I wrote before was implying exactly that. There are no globals except those few they are always there. The hard thing is always finding/composing stuff so it can be used. Not having a clever way to do this is preventing us from having namespaces.

When this is solved I think it is not too hard to have more than one special objects array. This will bring us to object spaces within the same memory space.

Norbert

>
> -C
>
> --
> Craig Latta
> www.netjam.org/resume
> +1 510 984 8117
> (Skype rings this until 31 January 2014)
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

NorbertHartl
In reply to this post by Stéphane Ducasse


Am 14.12.2013 um 21:08 schrieb Stéphane Ducasse <[hidden email]>:

>> Hi Norbert--
>>
>>> Class names are globals. A class is registered in a global namespace
>>> by its name. Names need to be looked up. How should it work in
>>> another way?
>>
>>    Get rid of globals. Make the root classes elements of the special
>> objects array (Object already is), and look up classes through that.
>> Make everything else that used to be a global (like Transcript) the
>> responsibility of some class, and use them by sending messages. This
>> also makes the modularization straightforward.
>
> This is what we did with
>    Smalltalk -> self environment.
>    Smalltalk -> SmalltalkImage current
>
> Now I wonder if it really solves the problem that has igor (this is true that I would prefer to avoid to
> have specific declaration.
> Now what would be good is to have a protocol to systematically initialize such "global" even when they
> are attached to classes.
>
What speaks against Package>>#initialize ? Or package having a selector returning the list of package wide globals and a selector for each global to create the value for it?
What is the difference between a dependency to a package and the access to its globals? Shouldn't the package not having defined its dependencies and couldn't that mean the same information composes the "global" namespace for this package?

Norbert
>>    There's no need for a system dictionary. It was a profound and
>> long-lived mistake.
>
> In the midterm I want to get rid of it (by splitting it and distributing into module) but it will take
> time.

Reply | Threaded
Open this post in threaded view
|

Re: Another thought about globals

Stéphane Ducasse

On Dec 15, 2013, at 11:22 AM, Norbert Hartl <[hidden email]> wrote:

>
>
> Am 14.12.2013 um 21:08 schrieb Stéphane Ducasse <[hidden email]>:
>
>>> Hi Norbert--
>>>
>>>> Class names are globals. A class is registered in a global namespace
>>>> by its name. Names need to be looked up. How should it work in
>>>> another way?
>>>
>>>   Get rid of globals. Make the root classes elements of the special
>>> objects array (Object already is), and look up classes through that.
>>> Make everything else that used to be a global (like Transcript) the
>>> responsibility of some class, and use them by sending messages. This
>>> also makes the modularization straightforward.
>>
>> This is what we did with
>>   Smalltalk -> self environment.
>>   Smalltalk -> SmalltalkImage current
>>
>> Now I wonder if it really solves the problem that has igor (this is true that I would prefer to avoid to
>> have specific declaration.
>> Now what would be good is to have a protocol to systematically initialize such "global" even when they
>> are attached to classes.
>>
> What speaks against Package>>#initialize ?
You cannot easily build tools with this approach


> Or package having a selector returning the list of package wide globals and a selector for each global to create the value for it?

would be much better

> What is the difference between a dependency to a package and the access to its globals? Shouldn't the package not having defined its dependencies and couldn't that mean the same information composes the "global" namespace for this package?

I could not understand what you meant :)

>
> Norbert
>>>   There's no need for a system dictionary. It was a profound and
>>> long-lived mistake.
>>
>> In the midterm I want to get rid of it (by splitting it and distributing into module) but it will take
>> time.
>