2
votes

I am using maxima inside SBCL and I want to do the following-simple demo for real time plotting without pause/delay-:

(loop for j from 1 below 10 do 
          #$plot2d(sin(x),[x,0,?j*%pi])$)

error:range must be of the form [variable, min, max]; found: [x,0,%pi*j]

I have to use setf/defvar, but I want to use local variables.

Questions:

  • How to pass common-lisp' local variable to maxima?

Thanks in advance.

2
I would guess that maxima looks up the symbol value, which would mean local variables can't be used. I'm not sure what exactly you mean by plotting "without pause/delay". Even if that worked, wouldn't the effect be exactly the same as just running for j: 1 thru 9 do plot2d(sin(x), [x, 0, j*%pi]); in maxima itself? - jkiiski
I mean by without pause/delay that a simple loop in lisp which would do some calculations from serial then plot them and it would wait-blocking- for the new data, so no need for pause. I want variables to go back and forth between them as I am more comfortable with lisp' data types. I am thinking of using tick and comma for that, but I am worried about customization and I think it's quite common usage case. - I.Omar

2 Answers

2
votes

Maxima uses only dynamic scope, not lexical scope. Maxima variables are implemented as Lisp symbols which are declared special. In order for J to be visible to Maxima, it must be declared special in one way or another (either via DEFVAR/DEFPARAMETER or (DECLARE (SPECIAL ...)), I forget if there are other ways).

I know this is not satisfying since dynamic scope makes it possible to have name collisions and therefore subtle bugs. Maybe you can ensure there are no name collisions by using a gensym; maybe write a macro to substitute a gensym for another variable and declare the gensym special, something like that.

0
votes

I am suing this macro:

(defmacro with-maxima (&body body)
  "write normal maxima exprs."
  `(progn
     ,@(mapcar (lambda (slot)
                 (destructuring-bind (&body args) slot
                   `(maxima:displa ,(read-from-string (concatenate 'string
                                                            "#$" (princ-to-string args) "$")))))
               body)
     ,(read-from-string "#$reset()$")
     ,(read-from-string "#$kill(all)$")))

example :

(with-maxima
  "y3: k-y1-2*y2"
  "gradef(y1,t,v1)"
  "gradef(y2,t,v2)"
  "gradef(v1,t,a1)"
  "gradef(v2,t,a2)"
  "diff(y3,t)")