2012-03-23 2 views
3

У меня есть вопрос относительно оценки списков в lisp.Confused by Lisp Цитата

Почему (a) и (+ a 1) не оценивали,

(defun test (a) (+ a 1)) 

так же, как (print 4) не оценивается здесь

(if (< 1 2) (print 3) (print 4)) 

но (print (+ 2 3)) оценивается здесь

(test (print (+ 2 3))) 

Есть ли у него что-то делать с m - стандартные библиотечные функции? Возможно ли, чтобы я определял такие функции в моей программе lisp?

+0

Возможный дубликат [Когда использовать цитату в Lisp] (http://stackoverflow.com/questions/134887/when-to-use-quote-in-lisp) – sds

ответ

5

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

;; Common Lisp: define a class A derived from B and C 
(defclass a (b c)()) 

;; Common Lisp: define a function of two arguments 
(defun a (b c)()) 

;; add A to the result of calling function B on variable C: 
(+ a (b c)) 

Традиционно диалекты Лиспа делят формы на формы операторов и формы вызова функций. Форма оператора имеет совершенно произвольный смысл, определяемый фрагментом кода, который компилирует или интерпретирует эти функции (например, оценка просто пересчитывается по всем формам аргументов вызова функции, а результирующие значения передаются функции).

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

Оператор типа fexpr просто передается форме во время выполнения вместе с объектом среды, с помощью которого он может искать значения переменных и т. Д. Затем этот оператор просматривает форму и реализует поведение.

Оператор макроса передается форме в момент макрорасширения (что обычно происходит при чтении форм верхнего уровня непосредственно перед их оценкой или компиляцией). Его задача - не интерпретировать поведение формы, а вместо этого переводить ее, создавая код. То есть макрос - это мини-компилятор. (Сгенерированный код может содержать больше макросообщений, а макрорасширитель позаботится об этом, гарантируя, что все макровызывы будут уничтожены.)

Подход fexpr не срабатывает, скорее всего, потому что он неэффективен. Это в основном делает невозможным компиляцию, тогда как Lisp-хакеры оценивают компиляцию. (Лисп уже был скомпилированным языком уже около 1960 года.) Подход fexpr также враждебен в отношении лексических сред; он требует fexpr, который является функцией, чтобы иметь возможность заглянуть в среду привязки переменных формы, в которой он вызывается, что является своего рода нарушением инкапсуляции, которое не допускается лексическими областями.

Макросписание немного сложнее и в некотором смысле менее гибкое, чем fexprs, но поддержка макрокоманды улучшилась в Lisp в 1960-х годах до 70-х годов, чтобы сделать ее максимально приближенной. Макрос первоначально получал всю форму, а затем сам разбирал ее. Макроопределяющая система превратилась во что-то, что обеспечивает макрофункции аргументами, которые получают разбитый синтаксис в легко усваиваемых частях, включая некоторые вложенные аспекты синтаксиса. Был также разработан синтаксис backquote для написания шаблонов кода, что значительно облегчает выражение генерации кода.

Итак, чтобы ответить на ваш вопрос, как я могу написать такие формы самостоятельно? Например, если:

;; Imitation of old-fashioned technique: receive the whole form, 
;; extract parts from it and return the translation. 
;; Common Lisp defmacro supports this via the &whole keyword 
;; in macro lambda lists which lets us have access to the whole form. 
;; 
;; (Because we are using defmacro, we need to declare arguments "an co &optional al", 
;; to make this a three argument macro with an optional third argument, but 
;; we don't use those arguments. In ancient lisps, they would not appear: 
;; a macro would be a one-argument function, and would have to check the number 
;; of arguments itself, to flag bad syntax like (my-if 42) or (my-if).) 
;; 
(defmacro my-if (&whole if-form an co &optional al) 
    (let ((antecedent (second if-form)) ;; extract pieces ourselves 
     (consequent (third if-form)) ;; from whole (my-if ...) form 
     (alternative (fourth if-form))) 
    (list 'cond (list antecedent consequent) (list t alternative)))) 

;; "Modern" version. Use the parsed arguments, and also take advantage of 
;; backquote syntax to write the COND with a syntax that looks like the code. 
(defmacro my-if (antecedent consequent &optional alternative) 
    `(cond (,antecedent ,consequent) (t ,alternative)))) 

Это пример, потому что фитинг первоначально Лисп был только cond. В «Лиспе» Маккарти не было if. Этот «синтаксический сахар» был изобретен позже, вероятно, в виде макроса, расширяющегося до cond, как и в случае my-if.

6

if и defun - макросы. Макросы расширяют форму до более длинного фрагмента кода. Во время расширения ни один из аргументов макроса не оценивается.

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

Отказ от ответственности: В зависимости от того, какого типа вы используете, if и defun могут быть технически названы «специальными формами», а не макросами, но концепция отложенной оценки по-прежнему применяется.

1

Lisp состоит из модели оценки форм. Различные диалекты Лиспа имеют для них разные правила.

Давайте рассмотрим Common Lisp.

  • данные оценивают себе
  • функции форма вычисляются путем вызова функции по оцениваемым аргументам
  • специальных форм оцениваются в соответствии с правилами, определенными для каждого специального оператора. В стандарте Common Lisp перечислены все те, которые определяют, что они делают в неформальном режиме, и нет возможности определять новые специальные операторы пользователем.
  • макросы формы трансформируются, результат оценивается

Как IF, Defun и т.д. работает и что они оценили, когда она Doen и то, что не оценивается, определяется в Common Lisp стандарта.