пятница, 30 июля 2010 г.

Cltl2 vs ANSI

Читал на сон грядущий честно купленный "Common Lisp: The Language, 2nd edition", изготовленный из тел мёртвых деревьев, и с удивлением обнаружил функции evalhook и applyhook. Если в двух словах, то эти функции позволяют простым способом организовать пошаговое выполнение формы. Или легко сделать песочницу, запрещая лезть, куда не надо, и делать, что не надо.

К сожалению, в ANSI Common Lisp эти функции убрали :( Осталась только функция step, которой можно делать интерактивный степпинг. В SBCL сделан step в варианте permissive, т.е. форма просто выполняется и выводится результат, даже если переключить sb-ext:*evaluator-mode* на :interpreter. Упоминаний evalhook в исходниках не нашёл. Зато в LispWorks и step работает, и evalhook сидит в пакете system, и в IDE есть возможность визуального отображения степпинга.

Побаловался немного с evalhook в Лиспворксе. Блин, ну это же малина! Нафиг такое убирать было? :( Вот пример песочницы:


(defun forbiddenp (form)
  (member (car form) '(quit)))

(evalhook `(progn
             (quit)
             (1+ (* 6 8)))
          #'(lambda (x y)
              (unless (forbiddenp x)
                (eval x)))
          nil)

=> 49

Здесь quit не будет выполнен.

5 комментариев:

  1. Я так понимаю, убрали их из стандарта (как и многие другие функции, дающие доступ к внутренностям code walker-а) дабы не накладывать дополнительных ограничений на внутренности реализации. Например, чтобы полноценно реализовать evalhook, необходимо наличие настоящего интерпретатора (и требование наличия evalhook, таким образом, сразу запрещает в рамках стандарта compiler-only реализций).

    ОтветитьУдалить
  2. Ну вот как раз работу с окружением и хотелось бы иметь в стандарте. Блин, забыл название библиотеки, которой волкер предоставляет на разных имплементациях, и вот в ней всё примерно одинаково на разных лиспах выглядело.

    ОтветитьУдалить
  3. А вот в CMUCL остались и *evalhook* и *applyhook*, в SBCL оставили только *macroexpand-hook* - правда,
    зачем было убирать одно, но оставлять другое.

    ОтветитьУдалить
  4. > в SBCL оставили только *macroexpand-hook* - правда,
    зачем было убирать одно, но оставлять другое.

    *macroexpand-hook* - часть стандарта, поэтому и оставили. А *evalhook* с *applyhook*, видимо, создавал какие-то дополнительные сложности, вот и выпилили их...

    ОтветитьУдалить

Архив блога