Hi Tomas,

> Why to add this feature to picolisp if it is not supposed to be used?

Well, I didn't say it is not supposed to be used. People might indeed
use it.

> >> One of the most important operations on namespaces should be creating
> >> a local name (alias) for it.
> ...
> You'd need to separate the concept of symbol name and name of the symbol
> table.  An alias I'm talking about is about making an alias for a symbol
> table.

This is not needed.

> Suppose I'm using the default symbol table 'pico'.  There are also
> symbol tables 'st1' and 'st2'.  Symbol implementation would not have to
> change.  Only the reader would look up symbols in the specified symbol
> table.
> An example assuming symbol tables are first class objects:

Yep, they are first class objects.

>    # create new empty symbol table (missing from your original example?)
>    (symbols 'st1 NIL)
>    (symbols 'st2 NIL)
>    (setq st1~sym1 1
>          st2~sym1 2)
>    (symbols 'st1)
>    (setq sym1 3)
>    (symbols 'st2)
>    (setq sym1 4)
>    (symbols 'pico) # set current namespace
>    (println st1~sym1 st2~sym1) # => 3 4
>    # create symbol table alias
>    (setq x st1)
>    (setq x~sym1 5)
>    (print sym1 x~sym1 st1~sym1) # => 5 5 5
> Something like that.

With the current implementation, you can write this as:

   (symbols 'pico)
   (symbols 'st1 'pico)
   (setq sym1 1)

   (symbols 'pico)
   (symbols 'st2 'pico)
   (setq sym1 2)

   (symbols 'pico~st1)
   (setq sym1 3)

   (symbols 'pico~st2)
   (setq sym1 4)

   (symbols 'pico)
   (println st1~sym1 st2~sym1) # => 3 4

   (setq x st1)
   (setq x~sym1 5)
   (print sym1 x~sym1 st1~sym1) # => NIL 5 5

> Then Henrik's example:
> > (foo.bar.blabla.abra.kadabra.func arg1 arg2)
> >> (func> '+Foo.bar.blabla.abra.kadabra arg1 arg2)
> Library code:
>   (symbols (symbols 'foo~bar~blabla~abra~kadabra NIL))
>   (de func (arg1 arg2) ...)
> App code:
>   (setq x foo~bar~blabla~abra~kadabra)
>   (x~func arg1 arg2)

This is:

   (symbols 'foo 'pico)
   (symbols 'bar 'foo)
   (symbols 'blabla 'bar)
   (symbols 'abra 'blabla)
   (symbols 'kadabra 'abra)

   (de func (A B) C)

   (symbols 'pico)
   (setq x foo~bar~blabla~abra~kadabra)

   (pp 'x~func)


   (de "func" (A B)
      C )

> Your seems to stick many possible meanings into the 'symbols' fexpr but

No. The meaning is basically only: "Set the current namespace to the
first argument, optionally initialized by the second argument". In any
case, the current namespace is returned (also in the special case
without arguments).

> still doesn't cover interesting usage.  For example: How can I create a
> new empty symbol table?

This is easy. Just initialize it with an empty cons pair:

   (setq st1 (cons))

However, I just didn't want to support this on the API level (in the
'syntax' function), because this is a very dangerous operation. If you
should happen to set such an empty namespace to "current", you are lost,
as no symbol at all will be accessible any longer. You have no other
choice than to enter Ctrl-D ;-)

> How do I refer to a symbol table without making
> it the default one?

Just the normal way, as a symbol. You can manipulate namespaces manually
any way you like, as they are simply pairs of 'idx' trees.

About putting the name into the symbol table instead of the symbol:

> > This would be quite some overhead, destroying the "once cell per
> > symbol" feature, and make things even more complicated for the
> > programmer.
> I imagine the proposed change should be at the symbol table, reader and
> printer level.  It should not change anything about symbols.

No. You underestimate the problems involved with changing the basic
principle of names being symbol attributes.

It is critical that for a given symbol the name can be determined very
rapidly. This is not only for printing, but extremely important for
external symbols, where the name encodes the symbol's location in the

Then think about string manipulations, comparisons etc. If the name of a
symbol is stored in a namespace data structure, each time a symbol's
name is needed, potentially all namespaces need to be searched.

Finally, what to do with uninterned transient symbols, which constitute
the largest number of symbols in the heap? They have no symbol table at

Then you must go for a double strategy, storing some names in symbols
and some not. Confusion.

> > Also I think that an alias would not have such very big advantages
> > over writing the full specification 'myNames~Foo'.
> Once you start with the symbol table idea, it does;-)  Not with such a
> useless name as myNames.  Imagine a real world:
>    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.  Now he has a problem;-)

I don't see any problem. Here how this could be done (note that I use
the convention to save and restore the current namespace in each module.
This allows to load each module in arbitrary contexts):

   ### 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))

   A B

> However, in the scenario above, programmer E must change the sources if
> the is no support for symbol table aliases.

As you see, no problem.

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

Reply via email to