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]

Reply via email to