2016-05-14 2 views
3

Предположим, что у нас есть символ со значением символа и значением функции и списком свойств, и назовем его q. Предположим также, что мы имеем функцию f с формальным параметром v, например. (f (v) ...) и вызывайте функцию как (f q).Common-Lisp: обязательные формальные параметры, точно, что передается?

Мой вопрос: что именно передано v? Are

  1. значение q;
  2. значение функции q;
  3. список свойств q,

перешел к формальному параметру v?

Если все они переданы v, то я озадачен тем фактом, что нам действительно нужны функции funcall и apply. Если v действительно имеет как значение, так и значение функции, то он сам может решить, что когда мы пишем (v 3), тогда он должен использовать значение функции v вместо (funcall v 3). И когда мы используем (setq v 3), тогда он должен использовать значение v.

Что точно передано v и почему v не является символом, а просто «параметром» или «переменной», является загадкой для меня. Но я считаю, что именно в Lisp 1.5 действительно был символ. Но, в общем, Lisp, кажется, есть некоторая комната для замешательства.

ответ

0

Значение переменной q.

(f q) является оценивали формы, в данном случае имя q интерпретируется в качестве переменной.

Если вы хотите получить значение функции или список свойств имени q в функции f, вам нужно указать его имя и сказать 'q. Делая это, вы ссылаетесь на глобальный реестр значений функций и значений списка свойств, а не на локальную информацию , переданную внутри функции f.

Только значение переменной q передается внутри функции f.

+0

Эта информация очень полезна. В литературе иногда очень сложно. Я видел в литературе очень разные мнения и объяснения по этому поводу. Иногда мне кажется, что это не вызвано длинной историей lisp. Путаница в отношении символов против переменных, передача функций функциям, терминология о привязках является источником долговременной путаницы. –

1

Поскольку вы цитируете его, вы передаете символ q не любые его значения; эти значения можно получить в пределах f, используя (symbol-value v) или (symbol-function v).

Причина, по которой вам нужно funcall, состоит в том, что Common Lisp использует значение функции символа, когда оно появляется во главе списка для оценки. Так что, если вы пишете

(v 3) 

будет вызывать функцию значение символа v. Но значение, которое было передано в f, находится в значении v, а не в значении функции. Но когда вы пишете

(funcall v 3) 

v находится в списке аргументов, поэтому она оценивается, чтобы получить его значение. Это значение является символом q, и при попытке вызвать символ, funcall просматривает свою функцию значения, так что эквивалентно в этом случае

(funcall (symbol-function v) 3) 
5

Если у вас есть

(f q) 

это означает вызовите функцию f со значением q.

  1. Лисп видит, что f является функцией, так что вся (f q) является функцией формы.
  2. Lisp оценивает q по своей стоимости.
  3. Lisp вызывает f с одним значением.
  4. Лисп связывает локальную переменную v с переданным значением
  5. Лисп выполняет тело функции f ...

v находится в исходном коде символ, но оно обозначает переменную. В скомпилированном коде символ ушел. Поскольку Common Lisp использует лексические привязки, переменные теперь являются лексическими ссылками.

Смежные вопросы