[squeak-dev] Namespaces, Packages: Image available for download, screencast.

Igor Stasenko siguctua at gmail.com
Sat Jul 26 07:24:54 UTC 2008


2008/7/26 Michael van der Gulik <mikevdg at gmail.com>:
> On Wed, 16 Jul 2008 16:40:42 +0300
> "Igor Stasenko" <siguctua at gmail.com> wrote:
>
>> >> To my understanding, the above should look like:
>> >>
>> >> Kernel.Classes addClass: (
>> >>    Kernel.Classes.ClassCategoryReader subclass: #ClassCommentReader
>> >>    type: 'normal'
>> >>    instanceVariableNames: ''
>> >>    classVariableNames: ''
>> >> ).
>> >
>> > This looks much more logical, but the problem here is that all globals need a context, meaning that any packages, namespaces, classes and shared variables that you refer to need to be included in the import list of the importer. That could be done, but it is less elegant than what I did above.
>> >
>>
>> Sure, but in SecureSqueak, you always compiling code in some context -
>> some instance of Namespace, which is first which will be asked for
>> returning a symbol's associated value.
>> So, for a file-ins you have to work out (if you don't have it already)
>> the model, how to switch to different namespace, before compiling some
>> code.
>> In same manner, as you open 'Scoped workspace' , all fileins should be
>> scoped as well.
>> And since browser is scoped already, the code above should be
>> interpreted just fine by compiler.
>
> Umm... thinking...
>
> Your code snippet above would be read as a chunk, and then compiled into a temporary class in a temporary method in the Kernel.Classes namespace, and then executed. It would make sense for the browser and scoped workspaces. It would certainly make some of the code there more elegant. The importer (when filing in) would somehow need to know that this particular chunk needed to be scoped in Kernel.Classes. Hmm. You'd need to implement some way of determining which context each chunk would be compiled and evaluated in. That would be a bit yuck.
>

Hmm, i don't see the yucky things here :)
Compiler should always known in which environment it compiles a method.
Then, it is up to environment to install and run the above code
snippet in proper class/namespace.
And you mistaken (or mislead) here: the above code should not use
Kenel.Classes namespace.

Lets imagine a following code chunk:

-----------
Packages addPackage: #Universe !   " a "
Universe addNamespace: #Earth !  " b "

!Universe beDefaultScope!  " c "

Earth addClass: (  "d"
   Kernel.Classes subclass: #House
   type: 'normal'
   instanceVariableNames: ''
   classVariableNames: ''
).
!

!Earth beDefaultScope!  " e "

!House methodsFor:.... blabla!  " f "

.. here comes the House class methods..
!
!
-----------

Ok, here, an "a"  method should be compiled within default image
namespace, which currently imports the code.
It should be quite irrelevant, in which environment you executing the
code, since Packages should be a reserved name which used throughout a
system to work with global packages from any scope. For this you
should disallow shadowing this name by namespace(s).

In "b", we compiling and executing method in same environment as in
"a" , but we already having an Universe package, and it should be
accessible by name, so compiler should resolve the 'Universe' symbol
just fine.
In "c" we diving both: into new scope and into a subchunk telling a
system to compile subchunk within Universe scope.
In "e" we diving into another nested scope, and compiling subchunk
with Universe.Earth scope.
And finally in "f" we diving into a Universe.Earth.House class scope
and compiling and installing methods for this class.

To me it is quite simple - you nesting code chunks in parallel to
nesting scopes, so that methods
#beDefaultScope, and #methodsFor:. ..  controlling in which
environment nested code chunks should be compiled.


> For now, I'll put a comment in CodeBuilder giving this as another option, and revisit this later. I need to think about it more; I have a funny gut feeling about this that I can't put my finger on.
>
>> One more thing is about namespace imports. I find it not quite
>> convenient in having each namespace keep own imports.
>>
>> This could lead to complexity issues:
>> Suppose package having 10 namespaces, and each one of them could have
>> own list of imports. And there can be probability that two different
>> namespaces importing two different versions of same package. This
>> means, that by occasion, developer can make his package depending from
>> some Package X v1, and Package X v2, which i think can't be his real
>> intention :)
>
> I was planning to let the tools deal with issues like this. It gets equally messy if you're working with multiple packages referring to different versions of other packages, so I was going to implement a "Upgrade all" method on the package manager to make sure everything referred to the latest versions of all packages in the package manager.
>
>> I think it would be better to make only packages having imports, and
>> regular namespace should have only parent.
>
> This has advantages and disadvantages. Thinking...
>
> If all imports were defined only on the package rather than individual namespaces, then management of package dependencies would be made a lot simpler, avoiding problems like you mention above and giving a very quick oversight of what dependencies the package has.
>
> However, this makes it harder to resolve an overloaded literal name. Say for example you have XML.Parser.Document and Network.Mime.Document. If a package wants to refer to both of these, it will need to refer to them using a fully quantified name rather than just "Document". This is no big deal, I guess, as the same would apply if classes in the same namespace wanted to do the same.
>
> I'm undecided. I can see the merit in your suggestion, and I'll give it some serious thought as I work with Namespaces some more.
>
>> So, the definition here is superfluous:
>>
>> IdentityDictionary subclass: #Namespace
>>       instanceVariableNames: 'name imports package fullyQuantifiedName parent'
>>       classVariableNames: ''
>>       poolDictionaries: ''
>>       category: 'Namespaces'
>>
>> it should be only:
>>
>> IdentityDictionary subclass: #Namespace
>>       instanceVariableNames: 'name parent'
>>       classVariableNames: ''
>>       poolDictionaries: ''
>>       category: 'Namespaces'
>>
>> fullyQuantifiedName can be computed based on name + parent(s).
>> Also, i don't see a real need in having namespace directly pointing to
>> package. Package is the root parent of namespace, isn't? So it can be
>> computed at any time. Why referencing to it directly?
>
> I agree on all of this. I'll add TODOs in my code and refactor it later. I want to push on with other parts of SecureSqueak for now.
>

I'm glad to see you taking my points into consideration :)


-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list