Emacs Lisp: различие между (функция (лямбда …)) и (лямбда …)?

Переменные переменные и функции без сомнения!

$foo = 'bar';
$bar = 'foobar';
echo $foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$foo();    //This outputs What a wonderful world!

то же понятие относится к параметрам объекта ($some_object->$some_variable);

Очень, очень хороший. Кодирование Make с циклами и очень легкими шаблонами, и это быстрее и больше под управлением, чем оценка (Спасибо @Ross & @Joshi Spawnbrood!) .t

8
задан Yoo 5 December 2009 в 17:39
поделиться

2 ответа

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

Как можно это выяснить? Небольшая интроспекция Emacs lisp дает некоторые подсказки. Для начала: Ch f function RET :

функция - это специальная форма в 'C исходный код '.

(аргумент функции)

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

Хорошо, вот в чем разница между (функция (лямбда ...)) и '(лямбда ...) , первая сообщает байтовому компилятору что он может безопасно скомпилировать выражение. В то время как выражения ' ed необязательно могут быть скомпилированы (поскольку они могут быть просто списком чисел.

А как насчет простого (лямбда ...) ? ] Ch f lambda RET показывает:

lambda - это макрос Lisp в `subr.el '.

(lambda args [docstring] [interactive] body)

Возвращает лямбда-выражение. Призыв форма (lambda args docstring интерактивное тело) является самоцитируемым; в результат оценки лямбда выражение - это само выражение. Тогда лямбда-выражение может быть рассматривается как функция, т. е. сохраняется как значение функции переданного символа на 'funcall' или 'mapcar' и т. д.

Следовательно, (лямбда ...) и '(лямбда ...) эквивалентны.

Кроме того, существует запись # '(лямбда ...) , которая является синтаксическим сахаром для (функция (лямбда ...)) .

Для получения дополнительной информации о функциях в Emacs lisp, прочтите страницы информации о функциях .

Чтобы все это проверить, вы можете ввести следующее в * рабочий * буфер и оценить выражения:

(caddr '(lambda (x) (+ x x)))
(+ x x)

(caddr (lambda (x) (+ x x)))
(+ x x)

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

(equal '(lambda (x) (+ x x))
       (function (lambda (x) (+ x x))))
t

(equal '(lambda (x) (+ x x))
       (lambda (x) (+ x x)))
t

Итак, все три варианта использования лямбда просто создайте списки, которые можно использовать как функции (один из которых может быть байтовым).

12
ответ дан 5 December 2019 в 11:25
поделиться

Ну (цитата (лямбда ...)) и (лямбда ...) не эквивалентны (при байтовой компиляции). Цитированные лямбды не компилируются побайтово, в то время как все остальное компилируется.

Например:

(defun foo (a)  
    (byte-code-function-p a))

(defun bar ()  
    (foo '(lambda () (ignore 'me))))

(defun bar2 ()  
   (foo (lambda () (ignore 'me))))

(defun bar3 ()  
    (foo (function (lambda () (ignore 'me)))))

(defun bar4 ()  
    (foo #'(lambda () (ignore 'me))))

(byte-compile 'bar)  
(byte-compile 'bar2)  
(byte-compile 'bar3)  
(byte-compile 'bar4)  

(bar)  ; -> nil  

(bar2) ; -> t  
(bar3) ; -> t  
(bar4) ; -> t

Обычно вы не хотите цитировать лямбду, если только функция, которой вы собираетесь передать лямбду, не делает с ней что-то еще, кроме funcall it.

3
ответ дан 5 December 2019 в 11:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: