Thanks Alex,
I had misgivings about using eval in my code, and a feeling that there
must be a better way.
The inability to add NIL is something I completely missed, though.
True not somthing that you would ordinarily do at the prompt but quite
likely deep inside application code.
As to useing Transient symbols. I think I will note it in my
description as you have. As far as I know Inadvertant variable capure
is a problem somwhere in most Lisp dialects. I know it can be an issue
in Common Lisp as well. Granted the circumstancs are different, but
the problem seems to keep cropign up.
regs
Konrad.
On 14/10/2008, Alexander Burger <[EMAIL PROTECTED]> wrote:
> Hi Konrad,
>
>> I decided to re-implemtn the fifo function using these primitives.
>
> Good idea! This will give a lot of useful and practical examples.
>
>
>> (de my-fifo (Fifo Item)
>> (let RealFifo (eval Fifo)
>> (if Item
>> (if RealFifo # Adding to a Fifo
>> (let NewHead (cons Item (cdr RealFifo))
>> (con RealFifo NewHead)
>> (set Fifo NewHead)
>> Item)
>> (prog # Creating a new fifo
>> (set Fifo (list Item) 'RealFifo (eval Fifo))
>> (con RealFifo RealFifo)
>> Item))
>> (if (== RealFifo (cdr RealFifo))
>> (prog1 # Returning the Last Item
>> (car RealFifo)
>> (set Fifo NIL))
>> (prog1 # Returning an Item
>> (cadr RealFifo)
>> (con RealFifo (cddr RealFifo)))))))
>>
>> Questions, Comments, Suggestions ?
>
> There are some minor changes I would suggest:
>
> 1. The 'Item' argument is used as an indicator whether a value is going
> to be inserted into the queue (non-NIL), or removed from the queue
> (NIL). The problem is then that NIL itself can never be inserted.
>
> Therefore, I would suggest to make 'Item' an optional argument, by
> using the '@' notation, and use retrieval functions like (args) and
> (next).
>
>
> 2. Instead of (eval Fifo) I would use (val Fifo). While this makes no
> difference if 'Fifo' is bound to a symbol, it also allows cell
> arguments (see also the 'var' discussion shortly ago):
>
> : (setq L (need 3))
> -> (NIL NIL NIL)
>
> : (my-fifo (cdr L) 1)
> -> 1
> : (my-fifo (cdr L) 2)
> -> 2
> : (my-fifo (cdr L) 3)
> -> 3
>
> : L
> -> (NIL (3 1 2 .) NIL)
>
> : (my-fifo (cdr L))
> -> 1
>
> : L
> -> (NIL (3 2 .) NIL)
>
>
> 3. The 'prog' ("Creating a new fifo") is not really needed, as it is
> implied in the 'else' part of 'if'. It does no harm, though.
>
>
> With these changes, my version would be:
>
> (de my-fifo (Fifo . @)
> (let RealFifo (val Fifo)
> (if (args)
> (if RealFifo # Adding to a Fifo
> (let NewHead (cons (next) (cdr RealFifo))
> (con RealFifo NewHead)
> (set Fifo NewHead)
> (arg) )
> # Creating a new fifo
> (set Fifo (list (next)) 'RealFifo (val Fifo))
> (con RealFifo RealFifo)
> (arg) )
> (if (== RealFifo (cdr RealFifo))
> (prog1 # Returning the Last Item
> (car RealFifo)
> (set Fifo NIL) )
> (prog1 # Returning an Item
> (cadr RealFifo)
> (con RealFifo (cddr RealFifo)) ) ) ) ) )
>
>
> However! Now one ugly detail remains, and I would probably not put this
> into such an educational example. But it is one of the sore spots in
> PicoLisp:
>
> 4. To make it absolutely correct, all locally bound symbols (i.e. Fifo,
> RealFifo and NewHead) should be transient symbols (i.e. "Fifo",
> "RealFifo" and "NewHead"). Otherwise a call like
>
> (my-fifo 'Fifo 1)
>
> would fail. This is explained a bit in "doc/faq.html#problems". Here
> we have the case that a symbol might be bound to itself and its value
> is being accessed.
>
> For a real production library, I would definitely write it with
> transient symbols. For part of an application, it is usually not so
> critical as you usually have some naming conventions. But even then
> you might run into an error during testing.
>
> Cheers,
> - Alex
> --
> UNSUBSCRIBE: mailto:[EMAIL PROTECTED]
>
--
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]