ТОП 10:

SYMBOL-FUNCTION выдает определение функции



Ранее был рассмотрен предикат BOUNDP, проверяющий наличие у символа значения. Соответственно предикат FBOUNDP проверяет, связано ли с символом определение функции:

 

_(fboundp ’list1)

T

Значение символа можно было получить при помощи функции SYMBOL-VALUE. Аналогично функция SYMBOL-FUNCTION дает определение функции, связанное с символом:

 

_(symbol-function ’list1)

(LAMBDA (X Y) (CONS X (CONS Y NIL)))

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

 

_(setq list1 ’a)

A

_(list1 list1 ’b)

(A B)

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

В некоторых системах (например, Franz Lisp) определение функции может храниться как значение символа, а не располагаться в специально отведенном месте в памяти. В Коммон Лиспе последняя возможность отсутствует.

Значение символа в таких системах интерпретируется как определение функции лишь тогда, когда с символом не связано определение функции.

В некоторых системах функцию можно задавать произвольным вычислимым выражением. В таких случаях говорят, что функции – это «полноправные граждане» (first class citizen).

 

Задание параметров в лямбда-списке

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

С помощью ключевых слов в лямбда-списке можно выделить:

1) необязательные (optional) аргументы;

2) параметр, связываемый с хвостом списка аргументов изменяющейся длины;

3) ключевые (key) параметры;

4) вспомогательные (auxiliary) переменные функции.

Аргументу и вспомогательной переменной можно присвоить значение по умолчанию (default).

Ключевые слова начинаются со значка &, и их записывают перед соответствующими параметрами в лямбда-списке. Действие ключевого слова распространяется до следующего ключевого слова. Приведем список наиболее важных ключевых слов и типов параметров или вспомогательных переменных, обозначаемых ими:

Ключевое слово Значение

&OPTIONAL Необязательные параметры

&REST Переменное количество параметров

&KEY Ключевые параметры

&AUX Вспомогательные переменные

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

Значения объявленных при помощи &OPTIONAL необязательных параметров можно в вызове не указывать. В этом случае они связываются со значением NIL или со значением выражения по умолчанию (initform), если таковое имеется. Например, у следующей функции есть обязательный параметр Х и необязательный Y со значением по умолчанию (+ Х 2):

 

_(defun fn (x &optional (y (+ x 2)))

(list x y))

FN

_(fn 2) ; вычисляется значение по

(2 4) ; умолчанию Y=X+2

_(fn 2 5) ; умолчание не используется

(2 5)

Естественно, ключевые слова можно использовать и в лямбда-выражениях:

 

_(lambda (x &optional (y (+ x 2)))

(list x y) 2 5)

(2 5)

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

Например:

 

_(defun fn (x &optional y &rest x) (list x y z))

FN

_(fn ’a)

(A NIL NIL)

_(fn ’a ’b ’c ’d)

(A B (C D))

Обратите внимание, что &REST-параметр связывается со значениями последних аргументов, поскольку отсутствует QUOTE.

Фактические параметры, соответствующие формальным параметрам, обозначенным ключевым словом &KEY, можно задавать в вызове при помощи символьных ключей. Ключом является имя формального параметра, перед которым поставлено двоеточие, например «:Х». Соответствующий параметр будет следовать в вызове функции за ключом и отделяться от него пробелом. Достоинством ключевых параметров является то, что их можно перечислять в вызове, не зная их порядок в определении функции или лямбда-выражении. Например, у следующей функции параметры X, Y, Z являются ключевыми:

_(defun fn (&key x y (z 3)) (list x y z))

FN

_(fn :y 2 :x 1)

(1 2 3)

Параметр Z можно было не задавать, так как ключевые параметры являются необязательными.

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

 

 

Изображение функций в справочных руководствах

Механизм ключевых слов лямбда-списка применяется не только для определения функций, в справочниках и учебниках его используют, объясняя употребление аргументов в описаниях функций. Например, тот факт, что функцияLIST имеет неограниченное количество параметров записывается в виде

 

(LIST &REST элементы)

Многим функциям Коммон Лиспа можно передавать необязательные и ключевые параметры. Например, традиционная функция Лиспа

 

(MEMBER элемент список)

проверяющая, входит ли данный элемент в данный список, может в Коммон Лиспе иметь три ключевых аргумента, модифицирующие действия функции по умолчанию:

 

(MEMBER элемент список

&KEY :TEST :TEST-NOT :KEY)

В некоторых Лисп-системах при описании используется m-нотация (meta-notation). Эта запись соответствует префиксной записи в математике, когда имя функции пишется непосредственно перед открывающей скобкой.

Например:

 

list(x1 x2 …xn)

 

 

Функции вычисляют все аргументы

В Коммон Лиспе нет механизма, с помощью которого можно было бы обозначать параметры, не требующие вычисления. Блокирующие вычисление аргумента функции и формы, такие как QUOTE, SETQ, DEFUN, определяются через механизм макросов или макрооператоров, который мы рассмотрим позже.

 

 

Многозначные функции

Ранее мы использовали функции, возвращающие одно значение, или один лисповский объект. Во многих Лисп-системах, в том числе и в Коммон Лиспе, можно определить и многозначные функции (multiple valued functions), которые возвращают множество значений. Этот механизм более удобен, чем возврат значений через глобальную переменную или через построение списка результатов. Для выдачи и принятия многокомпонентных значений используются специальные формы.

 

 

При вычислении NLAMBDA аргументы не вычисляются

Функции, которые трактуют свои аргументы так же, как QUOTE и DEFUN, часто называют функциями типа FEXPR. Если вычислять значения аргументов не надо, то такую функцию нужно определять с помощью NLAMBDA-выражения, имеющего ту же структуру, что и лямбда-выражение:

 

(NLAMBDA параметры тело-функции)

Определяемые лямбда-выражением функции типа EXPR(*) и определяемые NLAMBDA-выражением функции типа FEXPR(*) могут получать фиксированное или неопределенное число параметров в зависимости от того, определяются ли параметры через список атомов или одним атомом.

 

 

ЛАБОРАТОРНАЯ РАБОТА №5

1. Определите с помощью лямбда-выражения функцию, вычисляющую x+y-x*y.

 

 

2. Вычислите значения следующих лямбда-вызовов:

a) ((lambda (x) (cons x nil)) ’y)

b) ((lambda (x y) (list y x)) ’x y)

c) ((lambda (x) (list x)) (list nil))

d) ((lambda (x) (list x)) ((lambda (x) (list x)) (list nil)))

 

3. Определите функции (NULL x), (CADDR x), (LIST x1 x2 x3) с помощью базовых функций.

 

4. Определите функцию (НАЗОВИ x y), которая определяет функцию с именем, заданным аргументом х, и лямбда-выражением y. Определите с помощью этой функции функцию, вычисляющую сумму квадратов двух чисел, и саму функцию НАЗОВИ.

 

5. Вычислите значения следующих лямбда-вызовов:

a) ((lambda (a &optional (b 2)) (+ a (* b 3))) 4 5)

b) ((lambda (a b &key c d) (list a b c d)) :a 1 :d 8 :c 6)

c) ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x)) 1)

d) ((lambda (a &optional (b 3) &rest x &key c (d a)) (list a b c d x))

e) (list a b c d x)) 1 6 :c 7)

 

 

ПЕРЕДАЧА ПАРАМЕТРОВ И ОБЛАСТЬ ИХ ДЕЙСТВИЯ







Последнее изменение этой страницы: 2016-09-05; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.206.13.28 (0.007 с.)