function1() := block ( [var], var: 1, function2(), var);
function2() := block( , var: var + 1, nil);
to do the same thing in a modern Lisp, we have to use a so-called proclamation:
(declaim special var) (defun f1 () (prog (var) (setq var 1) (f2) (return var) ) ) (defun f2 () (setq var (+ 1 var)) )
Scope rules were a simple thing in the early days of Lisp: Lisp was dynamically scoped. Regrettably, scope rules were later complicated as a consequence of discussions as they can happen only among scientists or among the members of a of a standardization committee. As a consequence of standardization, Lisp was changed to lexical scoping with optional dynamical scoping for proclaimed variables.
Maxima was written when Lisp was a dynamically scoped language. Huge parts of Maxima still require the availability of dynamic scope rules. The changes that were introduced into commercially available Lisp systems certainly did not facilitate the maintenance of Macsyma (and Maxima) and there are even reasons to assume that the quite ideologically led discussions about the correct scoping rules for Lisp encouraged the creators of Maple and Mathematica to choose C as the implementation language of their programs. (C was also much cheaper to obtain than one of the big Lisps in the eighties of the 20th century.)
The situation with Maxima is difficult: A quick examination of the symbolic integrator (in file sinint.lisp) shows that the integration routines for rational functions still use dynamical scope rules. The file sinint.lisp contains this declaration to enforce dynamical binding for selected variables:
(declare-top (SPECIAL RISCHPF GENVAR $SAVEFACTORS CHECKFACTORS EXP VAR $FACTORFLAG $RATFAC $LOGABS $EXPOP $EXPON $KEEPFLOAT RATFORM ROOTFACTOR PARDENOM $ALGEBRAIC WHOLEPART PARNUMER VARLIST LOGPTDX SWITCH1))
The SPECIAL is the 'magic word' that we need to keep that old code running in a CommonLisp environment.