Local variables not so local within block



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)))