Как передать переменную local-lisp в максимумы? - PullRequest
0 голосов
/ 27 августа 2018

Я использую Максимум внутри SBCL , и я хочу сделать следующую простую демонстрацию для построения графиков в реальном времени без паузы / задержки -:

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

ошибка: range must be of the form [variable, min, max]; found: [x,0,%pi*j]

Мне нужно использовать setf / defvar, но я хочу использовать локальные переменные.

Вопросы:

  • Как передать локальную переменную common-lisp в максимумы?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Я подаю в суд на этот макрос:

(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)$")))

пример:

(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)")
0 голосов
/ 04 сентября 2018

Maxima использует только динамическую область видимости, а не лексическую область видимости. Переменные Maxima реализованы в виде символов Lisp, которые объявлены специальными. Для того, чтобы J был виден для Maxima, он должен быть объявлен специальным так или иначе (либо через DEFVAR / DEFPARAMETER, либо (DECLARE (SPECIAL ...)), я забыл, если есть другие способы).

Я знаю, что это неудовлетворительно, поскольку динамическая область позволяет создавать конфликты имен и, следовательно, скрытые ошибки. Может быть, вы можете убедиться, что нет конфликтов имен, используя gensym; может быть, написать макрос для замены gensym на другую переменную и объявить gensym специальным, что-то вроде этого.

...