Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие Функциональное и логическое программирование.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
309.57 Кб
Скачать

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

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

Необязательные параметры. Значения параметров, объявленных при помощи ключевого слова &OPTIONAL, можно в вызове не указывать. В этом случае они связываются со значением NIL или со значением выражения по умолчанию, если таковое имеется.

Пример: х –обязательный параметр, у – необязательный параметр со значением по умолчанию.

(defun fn (x &optional (y (+ x 2))) (list x y)) => fn

(fn 2) => (2 4) - вычисляется значение по умолчанию

(fn 2 6) => (2 6) - умолчание не используется

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

(defun fn (x &optional y &rest z) (list x y z)) => fn

(fn 2 3) => (2 3 nil)

(fn 1 2 3 4 5) => (1 2 (3 4 5))

(defun fn (x &optional y &rest z) (list x y (car z))) => fn

(fn 1 2 3 4 5 ) => (1 2 3)

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

Ключом является имя формального параметра, перед которым поставлено двоеточие, например, «:Х». Соответствующий фактический параметр следует за ключом и отделяется от него пробелом.

Ключевые параметры являются необязательными.

(defun fn (&key x y (z 3)) (list x y z)) => fn

(fn :z 4 :x 5 :y 6) => (5 6 4)

(fn :y 6 :x 5) => (5 6 3)

Передача параметров и область их действия.

В программировании используются в основном два способа передачи параметров: по значению и по ссылке.

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

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

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

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

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

(setq x 'а) => а

(defun abc (x) (setq x 'в)) => авс

(авс х) => в

х => а – статическое значение х изменяется, но первоначальное значение не меняется.

Свободные переменные – это переменные, которые используются в функции, но не входят в число ее формальных параметров. Изменения свободных переменных остаются в силе после окончания выполнения функции.

(SETQ x 'r) => r

x => r

(defun abc1 () (setq x 'в)) => abc1

(abc1) => b

x => b – при вызове функции авс1 значение переменной х изменилось

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

Для задания динамических (глобальных) переменных используется директива

(DEFVAR переменная &OPTIONAL начальное значение)

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

  • использование статической переменной в качестве формального параметра во внешней форме не влияет на значение свободной переменной. Значение свободной переменной определяется в соответствии с глобальным значением, присвоенным на самом внешнем уровне с помощью setq;

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

(setq x 100) => 100 - глобальное значение х

(defun f1 (x) (f2 2 )) => f1 - статическая переменная х

(defun f2 (y) (list x y)) => f2 - свободная переменная х, ее значением является глобальное значение 100.

(f1 1) => (100 2)

(defvar x 100) => x - начиная с этого момента х определяется динамически по последней связи.

(f1 1) => (1 2)