Как создать интерпретируемую функцию в SBCL? - PullRequest
0 голосов
/ 19 июня 2020

Я хочу создать интерпретируемое определение функции, а не скомпилированное.

Руководство по SBCL говорит:

Переменная: * режим оценки * [ sb-ext]: переключение между различными реализациями оценщика. Если установлено: compile, будет использоваться реализация eval, которая вызывает компилятор. Если установлено: интерпретатор, будет использоваться интерпретатор.

Итак, я пытаюсь создать функцию BAR (которой не существует):

(let ((sb-ext::*evaluator-mode* :interpret))
  (defun bar (x) (+ x 1)))

Но тогда я check, и BAR уже скомпилирован:

CL-USER> (compiled-function-p #'bar)
T

Итак, как создать интерпретируемую версию BAR?

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Форма let в вашем вопросе устанавливает режим оценщика только во время выполнения. К тому времени функция уже скомпилирована.

Вам нужно установить ее во время загрузки, а также убедиться, что load файл вместо компиляции и загрузки.

Попробуйте следующее:

In your-file.lisp:

;; at load time, set evaluator mode to interpret (before bar definition is met)
(eval-when (:load-toplevel :execute)
  (setf sb-ext::*evaluator-mode* :interpret))

;;define your interpreted function
(defun bar (x)
  (+ x 1))

;; set evaluator back to compile mode (optional)
(eval-when (:load-toplevel :execute)
  (setf sb-ext::*evaluator-mode* :compile))

;;check if bar is a compiled function
(print (compiled-function-p #'bar)) ;;prints NIL

Затем загрузите его с помощью (load "your-file.lisp") (файл сначала не компилируется).

0 голосов
/ 20 июня 2020

Я думаю, что *evaluator-mode* по сути своей является глобальной переменной. Например, если вы сделаете это:

> (setf sb-ext:*evaluator-mode* ':interpret)
:interpret
> (setf (symbol-function 'bar)
        (lambda (x) x))
#<interpreted-function nil {10026E7E2B}>
> (compiled-function-p #'bar)
nil

, вы получите интерпретируемую функцию. Но если вы сделаете это:

> (setf sb-ext:*evaluator-mode* ':compile)
:compile
> (setf (symbol-function 'bar)
        (let ((sb-ext:*evaluator-mode* ':interpret))
          (lambda (x) x)))
#<function (lambda (x)) {52C3687B}>
> (compiled-function-p #'bar)
t

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

И обратите внимание, что существует сложное определение «формы верхнего уровня», и в частности, что при обработке файла в такой форме, как

(let (...)
  (x ...))

тогда (x ...) не является формой верхнего уровня.

...