dotdistrib:true$ /* a.(b+c) = a.b + a.c */
facsum(l1 . sum(bra(n+1) . a . ket(n) . l2, n, 1, 64),
[l1,l2], operator("."));
spits out
Maxima encountered a Lisp error:
Condition in MACSYMA-TOP-LEVEL [or a callee]: INTERNAL-SIMPLE-PROGRAM-ERROR: MACSYMA-TOP-LEVEL [or a callee] requires less than sixty-five arguments.
The same works fine without dotdistrib
or with the regular *
operator.
at Maxima 5.46.0 @ GCL 2.6.12
PS: emotionally shouldn't be GCL considered a bug? I think this is not the first time that its argument number limitation is to be tackled with (and this is also annoying when writing your own programs!). And there are more bugs and limitations it seems: at least of what I encountered with GCL myself there is also bug #4084. And still the GCL version is shipped in the Linux packages available at the Sourceforge.
facexp contains several cases where
apply
is used on what could be a long list. If I'm not mistaken, these cases could all be replaced bymap
to avoid the GCL limitation.The doc for apply should probably mention the number-of-args limitation.
Note that Maxima supports
map
andxreduce
for different cases whereapply
might be used, and those shouldn't be affected by the GCL limitation.Thanks for a comment! A "workaround" I needed to do to run my old code that uses a similar call of
facsum
was to (finally) waste some time and compile Maxima with SBCL. I should say that Maxima compiles quite fast and the configuration process is straightforward; I would like to thank everyone responsible for that.Looks like the bug fix is for
facexp
to callmap
or an appropriate variety ofreduce
, as suggested.About the GCL argument limitation, the Common Lisp standard allows implementations to set the arguments limit as low as 64, so GCL is standard-conforming in that respect. If that doesn't work for Maxima, it's our problem to work around it.
Ideally Maxima
apply
would detect associative operators and apply areduce
function. I don't know what could be done about Lisp functions which have 65 or more actual arguments; on the face of it, it seems like such functions wouldn't be portable across CL implementations. I don't know if there actually are any such functions, aside from associative functions.On looking at this again, I think there isn't any simple solution such as replacing
apply
withmap
.facsum
callsratsimp
with extra arguments which are derived from its first argument. In the case shown in the problem statement, there are a lot of those extra arguments; 64 in fact. Thenratsimp
is supposed to be called asratsimp(expr, arg1, arg2, arg3, ..., arg64)
. Sinceratsimp
is a Lisp function, that's too many arguments for GCL.The extra arguments for
ratsimp
are supposed (I think) to be treated likeratvars
. I don't understand what that's supposed to do; trying some examples, I don't see what's the effect of the extraratsimp
arguments.I am guessing that
ratsimp
is supposed to do some of the work offacsum
here. But since I don't understand what's going on with the extra arguments, I don't know how to change it.For the record, the function
argsplit
constructs the list which is supplied toratsimp
as the extra arguments.I speculate that perhaps the same effect of
ratsimp(expr, e1, e2, e3, ...)
could be achieved byev(ratsimp(expr), ratvars = [e1, e2, e3, ...])
.On looking at the code for
ratsimp
(src/rat3e.lisp), mayberatsimp(expr, e1, e2, e3, ...)
is equivalent toi.e. taking into account whatever is the prevailing value of
ratvars
.I guess we would want to verify that
ratvars
gets restored correctly.Fixed by commit [ b31b96a ]. I ended up writing
instead of
because calling
ev
tickles a scope bug --x
is a variable in test cases, and also a local variable in share/simplification/genut.mac.Tried it with GCL and the case shown in problem statement apparently works okay.