Code Select
(lambda()(setf a 3))
but not with
Code Select
(lambda()(let((a 4))(setf a 3))).
As long as one does not pass free variables around he is safe. The problem most frequently occurs with Newlisp macros (actually, fexprs). These rely on free variables. If one defines
Code Select
(define-macro (ifnt condition else then)
(if (eval condition)
(eval then)
(eval else)))
then all variables used in, for example,
Code Select
(ifnt (< a b) (setf a 4)(setf b 4))
are passed to
Code Select
(define (gensym)
(inc gensym-counter)
(sym (append "G-" (string gensym-counter))))
However, in almost all cases, use of
Code Select
(set-protected1 'ifnt (lambda(c e t)(if (eval c)(eval t)(eval e)))
'(e c t))
will actually produce code lambda-expression like
Code Select
(lambda([ifnt.c] [ifnt.e] [ifnt.t])
(if (eval [ifnt.c])
(eval [ifnt.t])
(eval [ifnt.e])))
Which is "safe" because it uses unique names. Good news is that you do not need to use my
Code Select
> (context 'ifnt)
ifnt
ifnt> (define-macro (ifnt:ifnt c e t)(if (eval c) (eval t) (eval e)))
(lambda-macro (c e t)
(if (eval c)
(eval t)
(eval e)))
ifnt> (context 'MAIN)
MAIN
> (ifnt (< 2 3) ">=" "<")
"<"
> ifnt:ifnt
(lambda-macro (ifnt:c ifnt:e ifnt:t)
(if (eval ifnt:c)
(eval ifnt:t)
(eval ifnt:e)))
>
It is probably exactly what you need. It is also recommended approach by designer of the language.
Neither
If problem is still interesting from theoretical point of view, you can look at my blogpost
It contains implementation of