Hi all,

please note that I released a slight modification of the namespace
support: The 'load' function will preserve the current namespace, even
if it is changed by 'symbols' while loading a file.

The reasons can be seen best in the example from the previous discussion
with Tomas:

> >    Programmer A develops a groundbreaking library called xml.
> >    Programmer B develops another groundbreaking library called xml.
> >    Programmer C develops a library which uses A's xml library.
> >    Programmer D develops a library which uses B's xml library.
> >    Programmer E develops an application using libraries developed by
> >    programmers C and D.
> ...
>    ### File "libA.l" ###
>    (setq "ns" (symbols 'a 'pico))
>    (de xml (A) 'A)
>    (symbols "ns")
>    ### File "libB.l" ###
>    (setq "ns" (symbols 'b 'pico))
>    (de xml (B) 'B)
>    (symbols "ns")
>    ### File "libC.l" ###
>    (load "libA.l")
>    (setq "ns" (symbols 'c 'a))
>    (de foo (X)
>       (xml X) )
>    (symbols "ns")
>    ### File "libD.l" ###
>    (load "libB.l")
>    (setq "ns" (symbols 'd 'b))
>    (de foo (X)
>       (xml X) )
>    (symbols "ns")
>    ### Program E ###
>    (load "libC.l" "libD.l")
>    (println (c~foo) (d~foo))
> Output:
>    A B

As you see, this ends up with saving the current namespace in each
module (source file), by keeping it in a transient symbol "ns", defining
the module's contents, and then restoring it with (symbols "ns").

I think this is necessary, because otherwise I got a surprising behavior.

If I simply did

   ### File "libA.l" ###
   (symbols 'a 'pico)
   (de xml (A) 'A)

   ### File "libB.l" ###
   (symbols 'b 'pico)
   (de xml (B) 'B)

   ### File "libC.l" ###
   (load "libA.l")
   (symbols 'c 'a)
   (de foo (X) (xml X))

   ### File "libD.l" ###
   (load "libB.l")
   (symbols 'd 'b)
   (de foo (X) (xml X))

then back in the the main program

   (load "libC.l" "libD.l")
   (println (c~foo) (d~foo))

I got an error: "c -- Bad symbol namespace"

Why that? Answer: After loading "libC.l", and then "libD.l", the current
namespace is on 'd'.

The namespace 'c', however, was defined while namespace 'a' was current
(after loading "libA.l" in "libC.l"), so 'c' is neither in 'pico' nor in
'b' (which was then used to derive 'd').

'c' is accessible only via 'a'.

'foo' could now be accessed as a~c~foo, because 'a' was inherited from
'pico' -> 'b' -> 'd' ('b' was created later in 'pico' than 'a').

Confusing, isn't it?

It is desirable to have 'c' accessible from 'pico' (or whatever
namespace was current when the main program loaded the two libraries),
so that c~foo and d~foo are valid.

The only clean way I can see is to save the currently active namespace
at the beginning of a module. For that reason I wrote in the initial
exampes, at the beginning of each module

   (setq "ns" (symbols 'newLib 'oldLib))

and at the end

   (symbols "ns")

This looks ugly. And as it is indeed needed for _each_ module, we may as
well hard-code it into the 'load' function.

With that, the situation suddenly becomes very simple and clear. A
source file (or several nested source files) gets its own namespace
simply by calling (symbols 'newLib 'oldLib) at the beginning, possibly
after loading other required sources.

Here, 'oldLib' can be anything, it must not necessarily be the current
namespace. It should be whatever this module needs, i.e. where it builds
upon. However, 'newLib' will be automatically created in the current
namespace, i.e. the namespace of the caller.

As 'symbols' sets the new current namespace to 'newLib', all newly
created symbols will go into that namespace.

(Caution! You should be aware that all this namespace stuff operates
strictly on the symbol level. It is not concerned about values,
definitions, properties etc. of the involved symbols. Note the term
"created symbols" in the previous paragraph. Especially, if a symbol
already exists in 'oldLib', it will stay there, of course, and possible
definitions for that symbol will be visible there too).

When 'load' finishes, the current namespace is automatically reset to
the previous one. Now the new symbols in 'newLib' can be either accessed
via the '~' read macro


or by switching completely to the new namespace with

   (symbols 'newLib)

and further referring to it simply as 'foo'.

Side note: The above tests print the warning

   # d redefined

This is correct, because 'd' is a debugger function. In practice, it
would be better to select non-conflicting names for the namespaces.
Besides this, the examples work (just the 'd' function is gone ;-)

- Alex
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to