Понимание резких цитат в общих словах - PullRequest
1 голос
/ 26 апреля 2019

В моих экспериментах ниже я сократил, где REPL возвращает ошибку, и добавил [num], чтобы на них можно было ссылаться в обсуждении.

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

Почему я не могу выдать ни (f 3), ни даже (#'f 3)? Разве острая цитата не допускается в качестве первого элемента формы? Почему funcall требуется здесь?

[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

[236]> (abs 3)                      ; This is fine
3

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

[239]> (funcall #'f 3)              ; seems very long winded...!
3

Означает ли это, что системные функции обрабатываются не так, как пользовательские функции?

Для полноты:

[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.

[241]> (funcall #'abs 3)                ; Isn't this verbose... ?
3

Я еще не дошел до главы о символах в ANSI Common Lisp, возможно, это поможет ... спасибо за любые советы.

1 Ответ

7 голосов
/ 26 апреля 2019
[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

Приведенный выше тип устанавливает переменную с именем f для объекта функции - из функции с именем abs.

[236]> (abs 3)                      ; This is fine
3

Выше вызывается функция abs.

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.

Вверху: нет функции с именем f.

-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

Вверху: Common Lisp принимает только символы как имена функций, символы как имена макросов, символы как специальные операторы или лямбда-выражения какпервый элемент формы минусов.(function f) не является именем функции.

Означает ли это, что системные функции обрабатываются иначе, чем пользовательские функции?

Нет.

[239]> (funcall #'f 3)              ; seems very long winded...!
3

Выше вызывается функция funcall с объектом функции из названной функции f.funcall затем вызывает этот функциональный объект с 3 в качестве аргумента.

кажется очень длинным сгибом

Это.

Почему я не могу выпустить ни (f 3), ни даже (# 'f 3)?Разрешается использовать четкие кавычки в качестве первого элемента формы?

Поскольку f не называет функцию.Он называет переменную.#'f также не является именем функции.Мы должны использовать имя функции (фактически символ).

Пространства имен

Common Lisp (как и некоторые другие диалекты Lisp) имеет два пространства имен для функций и для переменных.

Определение переменной foo:

CL-USER 54 > (defvar foo 3)
FOO

Определение функции foo:

CL-USER 55 > (defun foo (x) (* foo 10))
FOO

Мы можем вызвать функцию foo со значениемполучено из переменной foo:

CL-USER 56 > (foo foo)
30

Как получить объект функции из глобального имени функции:

CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>

CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>

То же, что и выше, но с коротким обозначением:

CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>

CL-USER 59 > (function foo)            ; works also for local functions
#<interpreted function FOO 4230008AAC>

Как получить значение из глобальной переменной:

CL-USER 60 > (symbol-value 'foo)
3

Или просто использовать переменную:

CL-USER 61 > foo
3

Некоторые положительные значения:

Положительный: имя не конфликтует.

Мы можем написать

(defun foo (list) (list list))

и не нужно писать

(defun foo (lst) (list lst))

Положительный: более простая компиляция

(let ((list 3))
  (list 1 list 3))

Выше никогда не будет ошибки в Common Lisp.На схеме это будет ошибка: 3 is not a function.

...