<import: PoolDict> for namespaces

Tagged:
Project:GNU Smalltalk
Component:VM
Category:feature
Priority:normal
Assigned:Unassigned
Status:fixed
Description

The two commits at the tip of my master as I write this:

a9a46e1... add namespace pragmas, like class pragmas, for new syntax                                
9d92f75... unexported importation of pools into namespaces for their classes' methods

Let you do things like this:

Eval [PackageLoader fileInPackages: #('Parser' 'NetClients')]

Namespace current: Test [
    <import: STInST>

    Object subclass: MyTest [
        test [^RBParser]
    ]

    <import: NetClients>

    MyTest extend [
        test2 [^URIResolver]
    ]
]

More or less as documented in sym.c. Tests are also included, although namespace pragmas are not tested for Compiler (though the above test file works).

Accessing pool vars with #at: and friends on the namespace is explicitly unsupported, as that would be tantamount to always reexporting imports, which I think would be most unfriendly. This may cause issues with Undeclared bindings, that I didn't test for.

Updates

#1 submitted by Paolo Bonzini on Mon, 05/19/2008 - 05:06

The implementation is okay, and obviously you cannot reexport via #at: as that would require computing a linearization of the namespaces on every #at:. In practice, that would mean that A.B would not refer to a B defined in a shared pool of A.

However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ]. Can you convince me otherwise?

Would it be difficult to implement? I imagine you'd use something like the complete TwistedPools with the superspace replacing the environment (which simplifies things in turn).

#2 submitted by Paolo Bonzini on Mon, 05/19/2008 - 05:06

The implementation is okay, and obviously you cannot reexport via #at: as that would require computing a linearization of the namespaces on every #at:. In practice, that would mean that A.Var would not refer to a Var defined in a shared pool of A.

However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ] to move it into A.B. Can you convince me otherwise?

Would it be difficult to implement? I imagine you'd use something like the complete TwistedPools with the superspace replacing the environment (which simplifies things in turn).

#3 submitted by Stephen Compall on Mon, 05/19/2008 - 06:04
Attachment:import-pooldict-ns.patch (21.08 KB)

> In practice, that would mean that A.Var would not refer to a Var defined in a shared pool of A.

I consider this to be a feature, not just an optimization. My template is the import feature in Common Lisp -- because GST namespaces don't distinguish between external and internal symbols, I thought it best to apply the most likely strategy globally for pools.

> However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ] to move it into A.B. Can you convince me otherwise?

I am not sure what you mean. The namespace-pool-add happens strictly when a namespace is visited, so all namespaces added by the class-containing-namespace walk will also have their pools added. For example:

"assuming A and B are undefined"
Namespace current: A [
    
    Namespace current: B [
        Object subclass: Va [
            test [
                "resolves to STInST.RBParser in
                 current implementation"
                ^RBParser
        ]
    ]
]

#4 submitted by Stephen Compall on Mon, 05/19/2008 - 06:06

...where an <import: STInST> appears above the Namespace current: B line.

#5 submitted by Stephen Compall on Mon, 05/19/2008 - 06:10

Also as a result of how namespace-pool-add is tied to namespace-add, superclasses' namespaces' pools are also included. See pools.st:149 and PoolResolutionTests.st:150 for tests of this implication.

#6 submitted by Paolo Bonzini on Mon, 05/19/2008 - 07:29
Status:committed» fixed
> > In practice, that would mean that A.Var would
> > not refer to a Var defined in a shared pool of A.
>

> I consider this to be a feature, not just an optimization.

I agree.

> all namespaces added by the class-containing-namespace
> walk will also have their pools added

Yes, I just tried it on this and it worked:

Namespace current: A [
    
    Object subclass: KlassA [ KlassA class >> pathSep [ ^PathSeparator ] ]
    Namespace current: B [
        Object subclass: KlassB [ KlassB class >> pathSep [ ^PathSeparator ] ]
    ]
]

A.KlassA pathSep printNl.
A.KlassA allSharedPoolDictionariesDo: [ :each | each printNl ].
A.B.KlassB pathSep printNl.
A.B.KlassB allSharedPoolDictionariesDo: [ :each | each printNl ]

Should have just tried it before asking you, sorry! :-) Merged to master.

User login