On Wed, Oct 22, 2008 at 01:22:50PM +0100, Tomas Hlavaty wrote:
> The trick with run/eval in parent environment is used quite often in
> picoLisp to avoid variable binding clashes.  I was wandering whether
> it would not be better sometimes to do something like Common Lispers
> do with gensyms which would avoid clashes by using fresh symbols:

The disadvantage of gensym'd symbols is that the code is more difficult
to understand when pretty printed, and cannot be written to some file
and retrieved later.

The PicoLisp solution of transient symbols has an identical effect
(especially if you surround the function definition(s) with (====)).

Interesting is perhaps the reason why the environment argument to 'run'
and 'eval' was invented in the first place.

Though the usage of transient symbols (like gensym'd symbols) nicely
protects from symbol capture, there is one nasty detail: Symbols that we
*want* to be evaluated in the outer environment, most notably '@'.

If you use transient symbols

   (de foo "Prg"
      (when (car "Prg")
         (run (cdr "Prg")) ) )

then it basically works

   : (foo T (+ 1 2 3))
   -> 6
   : (foo NIL (+ 1 2 3))
   -> NIL

BUT if you want to use '@'

   :  (and 2 (foo T (+ 1 @ 3)))
   !? (+ 1 @ 3)
   T -- Number expected

Trying instead

   (de foo Prg
      (when (car Prg)
         (run (cdr Prg) 1) ) )


   : (and 2 (foo T (+ 1 @ 3)))
   -> 6


- Alex

Reply via email to