# [Maxima] hide local variables from substitution for a user defined object

Robert Dodier robert.dodier at gmail.com
Thu Nov 28 15:34:24 CST 2013

```On 2013-11-28, Litvinov Sergey <slitvinov at gmail.com> wrote:

> What is the best way to get this?
>
> (%i1) my_subst(k, i, i*my_sum(i, [i]));
> (%o1)                  k my_sum(i, [i]))
>
> (%i1) my_subst(k, j,  my_sum(j*i, [i]));
> (%o1)                    my_sum(k*i, [i]))
>
> Here [i] is a list of variables local to `my_sum' and they should not
> be substituted.

Well, I dunno if this is the best way, but it is a way.
You can try 'blex' (lexical block) which is implemented by the
attached code. It is pretty simple-minded but maybe useful.

(%i3) e1 : blex ([i], my_sum (i, [i]));
(%o3) my_sum(i,[i])
(%i4) subst (i = k, i * e1);
(%o4) k*my_sum(i,[i])
(%i5) e2 : blex ([i], my_sum (j*i, [i]));
(%o5) my_sum(j*i,[i])
(%i6) subst (j = k, e2);
(%o6) my_sum(k*i,[i])

For what it's worth, and hope this helps.

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) ,@ subst-eqns) `((mprog) ((mprogn) ,@ inits) ,@ exprs))))
(meval gensym-mprog)))

```