Переменные переменные и функции без сомнения!
$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
Они довольно взаимозаменяемы. Ответ заключается в том, что функция
позволяет байтовую компиляцию лямбда, в то время как две другие не делают (и эквивалентны). Примечание: это не означает, что функция
на самом деле байт компилирует лямбда.
Как можно это выяснить? Небольшая интроспекция 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
Итак, все три варианта использования лямбда просто создайте списки, которые можно использовать как функции (один из которых может быть байтовым).
Ну (цитата (лямбда ...))
и (лямбда ...)
не эквивалентны (при байтовой компиляции). Цитированные лямбды не компилируются побайтово, в то время как все остальное компилируется.
Например:
(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.