(symbols) inside a function

2012-01-31 Thread Imran Rafique
Alex, Tomas, Axel (and all other picolisp coders out there),

Another newbie question here, this time using (symbols) inside a function.

The intention behind the code (see below) is pretty simple. (mk) will
create a new namespace (well, a new symbol table), and (dset) should
set a variable in a specified namespace.

However:
+ even though (dset) switches the active symbol table with (symbols Dict-ns)
+ and (symbols) returns  as the active symbol table
+ but the variable |Key| is still only set in the pico symbol table

Some questions (in addition to the obvious "why isn't this working?"):

1) What am I doing wrong when I'm trying to (setq) the variable?

2) is there a way to create a new symbol-table/namespace without it
becoming the active one?

3) is there a way to check if a symbol is interned, without actually
interning it and setting it to NIL (if it didn't previously exist).
Basically, some way to do (interned? 'sym) => T/NIL .

4) is there a way to concatenate two symbol-names together, without
creating a transient symbol? (symbol+ 'foo 'bar) => 'foobar

As always, thanks in advance :)


### code (dicts2.l)
(de mk X
  # switch back to orig ns, after creating new ns
  (symbols (symbols (car X) 'pico)) )

(de dset X
  (let (
 Dict-ns (car X)
 # switch to Dict-ns
 Orig-ns (symbols Dict-ns)
 Key (cadr X)
 Value (eval (caddr X)) )
(prinl (pack "Current namespace is " (symbols)))
(prinl (pack "Setting " Key " to " Value))
(eval (list 'setq Key Value))
(symbols Orig-ns)
(prinl (pack "Current namespace is " (symbols))) ))

(mk Dc)
(dset Dc k1 (pack (time) " elapsed seconds"))
(prinl (pack "pico~k1 => " pico~k1))
(prinl (pack "Dc~k1 => " Dc~k1))


### output
# note: this is with (de *Prompt (pack (symbols) " λ"))

pico λ: (load "/home/imran/src/picolisp/labs/dicts2.l")
Current namespace is Dc
Setting k1 to 17820 elapsed seconds
Current namespace is pico
pico~k1 => 17820 elapsed seconds
Dc~k1 =>

--
Regards,
       Imran Rafique

(skype: imran_rafique)
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: (symbols) inside a function

2012-01-31 Thread Alexander Burger
Hi Imran,

> The intention behind the code (see below) is pretty simple. (mk) will
> create a new namespace (well, a new symbol table), and (dset) should
> set a variable in a specified namespace.

For one thing, you can easily set a variable in another namespace with:

   (setq Dc~k1 123)

This works, btw, also with further indirections:

   (setq Dc~ns1~ns2~k1 777)


> However:
> + even though (dset) switches the active symbol table with (symbols Dict-ns)
> + and (symbols) returns  as the active symbol table
> + but the variable |Key| is still only set in the pico symbol table

You must keep in mind that namespaces affect only the reader, not
expressions which already have been read. The namespace which is active
at the moment an expression is read determines which symbol with a given
name will be in the expression.


> 1) What am I doing wrong when I'm trying to (setq) the variable?

> (mk Dc)

creates a new namespace 'Dc', and immidiately sets the current namespace
back to 'pico'. That's all right. The expression

> (dset Dc k1 (pack (time) " elapsed seconds"))

is _read_ while 'pico' is the active namespace. A symbol 'k1' didn't
exist at the moment the above 'mk' was called, so an entry for that name
will be created in 'pico', and the expression '(setq Dc ...)' is
returned, and then evaluated. It is irrelevant what 'dset' does with its
arguments during that evaluation, the symbol 'k1' exists in 'pico'.


> 2) is there a way to create a new symbol-table/namespace without it
> becoming the active one?

Yes. The above 'mk' is fine for that.


> 3) is there a way to check if a symbol is interned, without actually
> interning it and setting it to NIL (if it didn't previously exist).
> Basically, some way to do (interned? 'sym) => T/NIL .

Yes, but I can't think of a peculiarly efficient way at the moment. You
could check with

   (member "foo" (all))

i.e. use a transient symbol to avoid the interning.

Technically, an efficient way would be possible (avoiding 'all', which
first collects all symbols into a list), by indexing directly into the
name tree. There is even such a function in the interpreter, i.e.
'isInternEXY_F' in src64/sym.l:37, but unfortunately there is no
top-level frontend for it.

Where would such a function be useful?


> 4) is there a way to concatenate two symbol-names together, without
> creating a transient symbol? (symbol+ 'foo 'bar) => 'foobar

No, but creating a transient symbol first does no harm. A transient
symbol is just a symbol which happens not to be referred to from the
current namespace. Each internal symbol is first created (by the reader)
as a transient symbol, and then immediately interned.

So (pack "foo" "bar") and (pack 'foo 'bar) both return "foobar", and
(intern (pack "foo" "bar")) is just fine.

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


Re: (symbols) inside a function

2012-02-01 Thread Imran Rafique
Thanks for responding Alex.

As you know, I'm just trying out picolisp in my spare time (hence my slow
responses on this list, sorry about that). To put some context to these
questions, I thought that using seperate namespaces to simulate a key/value
dictionary/hash-table would be a nice idea to play with, to understand picolisp
better.

(alists are nice and easy, but if you update it frequently cons'ing changes to
the begining, it gets slower & slower to work with the less frequently changing
key/values at the end of the alist)

Anyway, as the symbol-table/namespace itself is just a big hash-table, then all
we would need are: + a way to create a new namespace + check if a variable
exists in that namespace + get or set a variable in that namespace

I'm going to pull my original comments, and your replies, out of order and put
them under the above 3 headings, just to get a bit of order in here :)

(BTW, I hope this doesn't come across as "dogshedding" - or "arguing for
aguments sake". I'm genuinely interested to see where I can use picolisp in my
current stack - its 1/10th the memory footprint of racket!)

# a way to create a new namespace
#
>> (mk Dc)
>
> creates a new namespace 'Dc', and immidiately sets the current namespace
> back to 'pico'. That's all right.

It works, but it doesn't feel right. There's additional, unecessary work being
done here (switching the *current* namespace to the new one, then switching it
back to the old namespace).

I think that the lisp forms provided to cover the namespace functionality you
added to the vm ('symbols', and the ~ read macro) don't go far enough. They
cover one use case for namespaces, but not all potential uses.

Creating a new namespace, without changing the current namespace, would be one
addition ?


# check if a variable exists in that namespace
##
Thats why I was asking about (interned?).

>> 3) is there a way to check if a symbol is interned, without actually
>> interning it and setting it to NIL (if it didn't previously exist).
>> Basically, some way to do (interned? 'sym) => T/NIL .
>
> Yes, but I can't think of a peculiarly efficient way at the moment. You
> could check with
>
>   (member "foo" (all))
>
> i.e. use a transient symbol to avoid the interning.
>
> Technically, an efficient way would be possible (avoiding 'all', which
> first collects all symbols into a list), by indexing directly into the
> name tree.

Is the symbol 'pico itself just an idx tree, or some derivative of that? I
didn't fully grok the explanation of idx tree's from the ref - is there a
Rosetta example (or other snippet) which you can point me to to explain them?
Thanks :)

> There is even such a function in the interpreter, i.e.
> 'isInternEXY_F' in src64/sym.l:37, but unfortunately there is no
> top-level frontend for it.
>
> Where would such a function be useful?

Being able to check for a variable, without the side-effect of automatically
interning it with NIL, would make NIL a more useful value to use.

Again, similar to 'creating a new namespace', you have more fine-grained
functionality in the vm, which hasn't been wrapped in picolisp forms.


# get or set a variable in that namespace
#

> For one thing, you can easily set a variable in another namespace with:
>
>   (setq Dc~k1 123)

Yup - if we knew that the namespace is |Dc| and the variable in that namespace
is |k1|. But thats not what I'm trying to do in dset.

In the original example, inside (dset) we have Dict-ns = Dc, and Key = k1. So,
how would one access (set or get) the variable Dc~k1 , using just Dict-ns and
Key.

Is there some other way of accessing the contents of other namespaces, other
than using the ~ read macro?

>> However:
>> + even though (dset) switches the active symbol table with (symbols Dict-ns)
>> + and (symbols) returns  as the active symbol table
>> + but the variable |Key| is still only set in the pico symbol table
>
> You must keep in mind that namespaces affect only the reader, not
> expressions which already have been read. The namespace which is active
> at the moment an expression is read determines which symbol with a given
> name will be in the expression.
>
> The expression
>
>> (dset Dc k1 (pack (time) " elapsed seconds"))
>
> is _read_ while 'pico' is the active namespace. A symbol 'k1' didn't
> exist at the moment the above 'mk' was called, so an entry for that name
> will be created in 'pico',

Interesting. So the reader automatically intern's any "free symbol" (for want of
a better term) that it finds, before evaluating the expr?

Is this just a way of avoiding "variable doesn't exist" exceptions in any
situation?

But ...

If a function doesn't evaluate the argument, any non-existant variable name
menioned in the call to that function are still interned, before the function
gets its (unevaluated) arg list.

Doesn't that seem, well, wrong?


(de dummy X (print

Re: (symbols) inside a function

2012-02-01 Thread José Romero
On Wed, 1 Feb 2012 05:53:11 -0800
Imran Rafique  wrote:

> Thanks for responding Alex.
> 
> As you know, I'm just trying out picolisp in my spare time (hence my
> slow responses on this list, sorry about that). To put some context
> to these questions, I thought that using seperate namespaces to
> simulate a key/value dictionary/hash-table would be a nice idea to
> play with, to understand picolisp better.
> 
> (alists are nice and easy, but if you update it frequently cons'ing
> changes to the begining, it gets slower & slower to work with the
> less frequently changing key/values at the end of the alist)
> 
Why not use a 'idx tree then? http://software-lab.de/doc/refI.html#idx

##
# I used 'name here to prevent accidental clobbering
(de iset (Tree Key Value)
   (set
  (or
 (car (idx Tree Key))
 (prog1 (name Key) (idx Tree @ T)) )
  Value ) )

(de iget (Tree Key)
   (val (car (idx Tree Key))) )

## Tests ##
: (iset 'mydict "Foo" 42)
-> 42

: (iset 'mydict "Bar" T)
-> T

: (iset 'mydict "Bam" "Baz")
-> "Baz"

: (iget 'mydict "Foo")
-> 42

: (iget 'mydict "Bam")
-> "Baz"

: (iget 'mydict "Bar")
-> T

: (mapcar show (idx 'mydict)) 
"Bam" "Baz"
"Bar" T
"Foo" 42
-> ("Bam" "Bar" "Foo")
###

> Anyway, as the symbol-table/namespace itself is just a big
> hash-table, then all we would need are: + a way to create a new
> namespace + check if a variable exists in that namespace + get or set
> a variable in that namespace
> 
[...]

Cheers,
José
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: (symbols) inside a function

2012-02-01 Thread Alexander Burger
Hi Imran,

> As you know, I'm just trying out picolisp in my spare time (hence my slow
> responses on this list, sorry about that). To put some context to these

That's perfect. No hurry :)

I also want to spend more time concentrating on project work.


> questions, I thought that using seperate namespaces to simulate a key/value
> dictionary/hash-table would be a nice idea to play with, to understand 
> picolisp
> better.

While this is theoretically possible, I would stronly disadvise it.

Namespaces are a huge overhead, if you just want to create some data
lookup structure. Calling 'symbols' creates a copy of the current
namespace, so this means that for a (relatively small) namespace of 1000
symbols, a tree of 1000 nodes (or roughly 1500 cells) is copied. That's
24000 bytes of memory. Searching for a few symbols in that big tree is
also unnecessarily slow.


> (alists are nice and easy, but if you update it frequently cons'ing changes to
> the begining, it gets slower & slower to work with the less frequently 
> changing

A simple linear list search is for up to 100 or so items probably faster
than a lookup in the above large tree.

> key/values at the end of the alist)

You might consider using symbol properties then. Properties are
implemented using a last-recently-used scheme. When a property is found
with 'get' or related functions, it is moved to the front of the list.

But for large data sets, 'idx' (as José Romero pointed out) is probably
better. In fact, namespaces internally have the same structure as 'idx'
trees.


> Anyway, as the symbol-table/namespace itself is just a big hash-table, then 
> all
> we would need are: + a way to create a new namespace + check if a variable
> exists in that namespace + get or set a variable in that namespace

Yes, but with a really big overhead (see above).


> (BTW, I hope this doesn't come across as "dogshedding" - or "arguing for
> aguments sake". I'm genuinely interested to see where I can use picolisp in my
> current stack - its 1/10th the memory footprint of racket!)

OK.


> >> (mk Dc)
> >
> > creates a new namespace 'Dc', and immidiately sets the current namespace
> > back to 'pico'. That's all right.
> 
> It works, but it doesn't feel right. There's additional, unecessary work being
> done here (switching the *current* namespace to the new one, then switching it
> back to the old namespace).

Compared to the amount of work of creating the namespace (copying
thousands of tree cells), the setting of the current namespace is
ridiculously small. It involves not more than switching a pointer.

The creation and immediately setting of the namespace is just convenient.
The intention of namespaces is to build indpendent modules, and in such
cases you will want to do

   (symbols 'newspace 'pico)
   (de a () ...)
   (de b () ...)

If you put such a code sequence into a single file, you have an isolated
module, because 'load' restores the current namespace when it is done,
effectively making 'newspace' available in 'pico'.


> I think that the lisp forms provided to cover the namespace functionality you
> added to the vm ('symbols', and the ~ read macro) don't go far enough. They
> cover one use case for namespaces, but not all potential uses.

To my feeling, they fit together perfectly. At least for the intended
purpose.


> Is the symbol 'pico itself just an idx tree, or some derivative of that? I

Yes. To be precise: It is a cons-pair of two idx trees, one for short
names (7 or less characters), and one for long names.

But: The internal matching algorithm is not compatible to 'idx'. It
doesn't use comparison functions (=, < etc.) on the symbol names
(strings) as 'idx' does, but compares complete chunks of 64-bit words.
This is the reason for the distinction between short and long words.
Therefore, 'idx' can't really be used with namespaces.


> didn't fully grok the explanation of idx tree's from the ref - is there a
> Rosetta example (or other snippet) which you can point me to to explain them?

Yes, for example

   http://rosettacode.org/wiki/Associative_arrays/Iteration
   http://rosettacode.org/wiki/Anagrams
   http://rosettacode.org/wiki/Anagrams/Deranged anagrams
   http://rosettacode.org/wiki/Hamming_numbers
   http://rosettacode.org/wiki/Huffman_coding
   http://rosettacode.org/wiki/Inverted_index
   http://rosettacode.org/wiki/LZW_compression
   http://rosettacode.org/wiki/Priority_queue
   http://rosettacode.org/wiki/Set
   http://rosettacode.org/wiki/Sokoban


> Is there some other way of accessing the contents of other namespaces, other
> than using the ~ read macro?

Not really, AFAIK at the moment.


> > is _read_ while 'pico' is the active namespace. A symbol 'k1' didn't
> > exist at the moment the above 'mk' was called, so an entry for that name
> > will be created in 'pico',
> 
> Interesting. So the reader automatically intern's any "free symbol" (for want 
> of
> a better term) that it finds, before evaluating the expr?

Yep. This is a ve

Re: (symbols) inside a function

2012-02-23 Thread Imran Rafique
Jose & Alex,

Please excuse my rudeness in not replying sooner (on business, then Yosemite
trip). Thanks for the pointers on idx trees.

--
Regards,
       Imran Rafique

2012/2/1 José Romero :
> Why not use a 'idx tree then? http://software-lab.de/doc/refI.html#idx
>
> ##
> # I used 'name here to prevent accidental clobbering
> (de iset (Tree Key Value)
>   (set
>  (or
> (car (idx Tree Key))
> (prog1 (name Key) (idx Tree @ T)) )
>  Value ) )
>
> (de iget (Tree Key)
>   (val (car (idx Tree Key))) )
>
> ## Tests ##
> : (iset 'mydict "Foo" 42)
> -> 42
>
> : (iset 'mydict "Bar" T)
> -> T
>
> : (iset 'mydict "Bam" "Baz")
> -> "Baz"
>
> : (iget 'mydict "Foo")
> -> 42
>
> : (iget 'mydict "Bam")
> -> "Baz"
>
> : (iget 'mydict "Bar")
> -> T
>
> : (mapcar show (idx 'mydict))
> "Bam" "Baz"
> "Bar" T
> "Foo" 42
> -> ("Bam" "Bar" "Foo")
> ###

On 1 February 2012 19:59, Alexander Burger  wrote:
>> didn't fully grok the explanation of idx tree's from the ref - is there a
>> Rosetta example (or other snippet) which you can point me to to explain them?
>
> Yes, for example
>
>   http://rosettacode.org/wiki/Associative_arrays/Iteration
>   http://rosettacode.org/wiki/Anagrams
>   http://rosettacode.org/wiki/Anagrams/Deranged anagrams
>   http://rosettacode.org/wiki/Hamming_numbers
>   http://rosettacode.org/wiki/Huffman_coding
>   http://rosettacode.org/wiki/Inverted_index
>   http://rosettacode.org/wiki/LZW_compression
>   http://rosettacode.org/wiki/Priority_queue
>   http://rosettacode.org/wiki/Set
>   http://rosettacode.org/wiki/Sokoban
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe