Is there a way to interact with Lisp programmatically ?
I am aware of the (interactive) :lisp command. But I am not aware of any way to use Lisp code in a Maxima function.
An example of what I would like to do : both Sage and Mathematica allow to define piecewise functions (in slightly different ways (cases in Sage, Piecewise in Mathematica). A Maxima macro implementing (awkwardly) this functionality would be :
/* Port to Maxima of Sage's cases. */
cases(x) ::=block([L],
L:maplist(lambda([cl],
if length(cl) # 2
then error("cases : clauses must be of length two.")
else buildq([c:[first(cl)], a:[second(cl)]],
if splice(c) then return(splice(a)))),
x),
buildq([L:L],ev(block(splice(L), false))));
This works:
(%i37) display2d:false;
(%o37) false
(%i38) maplist(foo, [-2, 2, a]);
(%o38) [1/2,4,unknown]
(%i37) display2d:false;
(%o37) false
(%i38) maplist(foo, [-2, 2, a]);
(%o38) [1/2,4,unknown]
But this has its limits : the block must be rebuilt at each evaluation, not once :
(%i40) define(foo(x), cases([(x<0, -1/x), (x>=0, x^2), (true, unknown)]));
(%o40) foo(x):=unknown
(%i41) maplist(foo, [-2, 2, a]);
(%o41) [unknown,unknown,unknown]
What I'd like to do is to call Lisp's cond, passing it a term-to-term translation of the argument.
Is there a way to do this without recompiling Maxima with this addition ? If not, this (calling Lisp from Maxima) should be considered as a highly desirable feature...
Sincerely yours,
I think that you should see the "Lisp and Maxima" section of the Maxima manual.
If you want to use the on-line manual, then as follows:
When entering the "?? lisp" at the prompt of Maxima, all documented items which contain "lisp" in their titles are shown.
So enter 0 in order to select the "Lisp and Maxima" title.
Thanks,
Hi Emmanuel, I don't understand the expected output here. Can you give an example of a
casesexpression and what the expected translation of that in Maxima would be? Do you want to construct an expression likeif--then--else?There is a built-in function named
charfunwhich might be related also.What I can do :
What I would like to do (warning : highly hypothetical pseudocode, written with vague Lisp macro memories 40 years old...) :
The point is that going to the Lisp code directly saves the building of the Maxima code at each execution ; This code generation is done once at
definetime, and the(cond ...)can be executed immediately after the translation of the argument to Lisp (necessary anyway...). BTW, you'll note that I used:=, notdefine, in order to obtain this translation.Mathematica and Sympy return some-to-many results of this kind (especially to express branches in integration problems...) ; an effort is made in Sagemath to translate these results back (
casesexists but is perfectible, the difficultty of definingAnd,OrandNotis bilateral translation to Maxima... exactly for the same reasons as forcases.HTH,
PS : as far as I understand it,
charfunis only remotely related...Thanks for the explanation. Here's a simple-minded implementation of
casesusing Maxima'sif.If that's not going in the right direction, you can say why and I'll try again.
I don't think Common Lisp
CONDis going to help here, since Maxima logical expressions aren't required to evaluate to true or false;ifhas the necessary machinery to handle values which are nottrueorfalse.I see your point Your solution is very elegant.
I ignored that applying
ifonLwould insert the requiredifelseandelse, the documentation doesn't even hints it.. It might be useful to d an explicit example along the lines of:to the documentaton of the (very) special
ifoperator.As far as I remember,
condtreats any non-nilvalue as true ; doesifacts the same ?A possible snag, though : what happens if there is no default clause (i. e. no
(true, ...)finat expression in L ? I'd like to rase an error,. What wouldifdo ? As far as I understand theifdocumentation, it would returnfalse...Notwithstanding the special case of
cases, I still think that documenting how to extend Maxima in Lisp would be useful...ifrequires that Boolean values be eithertrueorfalse; non-null values are not handled the same astrue. When the global flagprederroristrue, a value other thantrueorfalsetriggers an error; whenprederrorisfalse, the result is again a conditional expression.If you want
ifto not fall through to an implicitfalsevalue, you'll have to put something there. You could fix upcasesto paste on two more elements,trueanderror("HEY")(or whatever). I guesscaseswould want to ensure the second-to-last value is not alreadytruebefore pasting it on.About documentation, there is already some about Lisp and Maxima in "Minimal Maxima". There might be other resources on https://maxima.sourceforge.io/documentation.html . No doubt it could all be better organized.
Closing this ticket since it appears the original request has been fulfilled.