Переименование лямбды в Common Lisp - PullRequest
11 голосов
/ 04 марта 2012

Я недавно начал изучать Common Lisp и (просто для удовольствия) решил переименовать лямбда-макрос.

Моя попытка была такой:

> (defmacro λ (args &body body) `(lambda ,args ,@body))

Кажется, что правильно расширяется, когда само по себе:

> (macroexpand-1 '(λ (x) (* x x)))
(LAMBDA (X) (* X X))

Но когда оно вложено в выражение, выполнение завершается неудачно:

* * 1010

Возможно, я упускаю что-то очевидное в расширении макросов, но не могу понять, что это такое.

Может быть, вы можете мне помочь?

редактировать: Работает с лямбдой:

> ((lambda (x) (* x x)) 2)
4

изменить 2: Один из способов заставить это работать (как предложено Райнером):

> (set-macro-character #\λ (lambda (stream char) (quote lambda)))

(проверено в Clozure CL)

Ответы [ 2 ]

20 голосов
/ 04 марта 2012

В Common Lisp LAMBDA - это две разные вещи: макрос и символ, которые можно использовать в выражении LAMBDA.

Выражение LAMBDA:

(function (lambda (x) (foo x)))

короче написано как

#'(lambda (x) (foo x))

Применяется также лямбда-выражение:

((lambda (x) (+ x x)) 4)

Выше обе формы являются частью основного синтаксиса Common Lisp.

Позднее в определении Common Lisp был добавлен макрос с именем LAMBDA. Достаточно запутанно, но с добрыми намерениями. ;-) Это задокументировано как Макро LAMBDA .

(lambda (x) (+ x x))

расширяется до

(function (lambda (x) (+ x x))

Это делает код Common Lisp немного похожим на код Scheme, и тогда нет необходимости писать

(mapcar #'(lambda (x) (+ x x)) some-list)

С помощью макроса LAMBDA мы можем написать

(mapcar (lambda (x) (+ x x)) some-list)

Ваш пример терпит неудачу, потому что

((my-lambda (x) (* x x)) 2)

недопустим синтаксис Common Lisp.

Common Lisp ожидает либо

  • объект данных
  • переменная
  • вызов функции в виде (function args...)
  • вызов функции в виде ((lambda (arglist ...) body) args...)
  • форма макроса типа (macro-name forms...)
  • специальная форма с использованием одного из встроенных специальных операторов, таких как FUNCTION, LET, ... определенные в списке специальных операторов в Common Lisp

Как вы можете видеть синтаксис

((macro-name forms...) forms...)

не является частью Common Lisp.

Можно прочитать символ λ как LAMBDA:

(defun λ-reader (stream char)
  (declare (ignore char stream))
  'LAMBDA)

(set-macro-character #\λ #'λ-reader)

Пример: * 1 069 *

CL-USER 1 > ((λ (x) (* x x)) 3)
9

CL-USER 2 > '(λ (x) (* x x))
(LAMBDA (X) (* X X))
2 голосов
/ 12 октября 2012

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

...