Subject: Local variables not so local within block
From: Robert Dodier
Date: Tue, 24 Jul 2012 04:28:16 +0000 (UTC)
On 2012-07-23, Stefano Ferri <ferriste at gmail.com> wrote:
> I've tried your implementation of "blex". It seems to work fine, do you
> think it could be used in a (more or less) stable code?
Well, blex is pretty simple-minded, so, although you can't expect much,
you can expect it to do its simple thing ....
> Anyway it doesn't support the "return" statement, Maxima complains
> that return is not inside a block.
Oh, you're right. I've appended an updated blex.lisp to this message.
> But, reading the documentation of block, I've just discovered the
> "local" command, wich seems to solve the problem.
Well, the effect of local is to remove properties from a symbol, so
there is a different set of unexpected consequences that are possible:
foo[123] : 456;
g(x) := foo[x];
g(123);
=> 456
f(x) := block (local(foo), foo:something, g(x));
f(123);
=> foo[123]
best,
Robert Dodier
PS.
;; blex.lisp -- lexical block for Maxima
;; copyright 2012 by Robert Dodier
;; I release this work under terms of the GNU GPL
;;
;; examples:
;; blex ([n:100], f(x) := n : n + x, g() := display(n));
;; blex ([f], f(x) := 2*x);
;; blex ([a], h(x) := a[x] : 1, i() := arrayinfo(a));
(defmspec $blex (x)
(let*
((args (cdr x))
(vars+inits (cdr (car args)))
(vars (mapcar #'(lambda (e) (if (symbolp e) e (second e))) vars+inits))
(inits (remove-if #'symbolp vars+inits))
(exprs (cdr args))
(gensym-vars (mapcar #'(lambda (s) (let ((s1 (gensym))) (setf (get s1 'reversealias) (or (get s 'reversealias) s)) s1)) vars))
(subst-eqns (mapcar #'(lambda (x y) `((mequal) ,x ,y)) vars gensym-vars))
(gensym-mprog ($psubstitute `((mlist) , at subst-eqns) `((mprog) ((mprogn) , at inits) , at exprs))))
(meval gensym-mprog)))