Основные функции ЛИСПа

Из определение S-выражения также вытекает, что в ЛИСПе принята префиксная форма записи функции, имя которой расположено после открывающейся скобки. Например, выражение 2*x+3 запишется как (+ (* 2 x)), при этом действия выполняются из середины наружу. Структура программы не отличается от структуры данных и появляется возможность записывать функции в виде списков, т.е. данные (списки) и программа (списки) представляются единым образом.

При обращении к функции указывается ее имя и аргументы (фактические параметры – ACTUAL ARGUMENTS). Аргументами функции в общем случае могут быть S-выражения. Связь с формальными параметрами (FORMAL ARGUMENTS) осуществляется по значению.

В некоторых случаях не требуются вычисления значений выражений, а нужны сами выражения. Если нас не интересует значение функционального выражения, например (+ 2 3), значение которого равно 5, а нужно обработать форму как список, то это выражение записывают особым способом. А именно, для предупреждения вычислений перед ним ставят апостроф » ‘ «. Апостроф перед выражением – это сокращение лисповской формы QUOTE, которая записывается в единой для Лиспа префиксной нотации

‘ выражение ≡ (QUOTE выражение).

QUOTE – специальная функция с одним аргументом, которая возвращает в качестве значения этот аргумент. Апостроф автоматически переопределятся в QUOTE.

(QUOTE ‘ y ) (QUOTE y).

Перед константами не надо ставить апостроф, так как число и его значение совпадают.

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

(QUOTE (+ 1 2)) (+ 1 2),

(EVAL (QUOTE (+ 1 2))) 3.

EVAL – это универсальная функция Лиспа, которая может вычислить любое правильно составленное s-выражение.

2.2.1 Функции назначения

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

(SET ‘a (+ 2 3)) 5, (2)

(SET ‘a ‘(+ 2 3)) (+ 2 3).

В следующем примере происходит вычисление и первого аргумента

(set ‘name ‘(a b c) ), (set (car name) ‘town ),

в результате которого символ a будет связан со значением town.

Если перед первым аргументом нет апострофа, то значение будет присвоено значению этого аргумента. В этом случае необходимо быть довольно аккуратным, поскольку возможны ситуации, которые приводят к ошибкам. Так, если был вызов (2), то следующий вызов (SET a c) приводит к ошибке, поскольку константе 5 значение назначить невозможно.

Функция SETQ отличается от SET тем, что она вычисляет только свой второй аргумент. Она автоматически блокирует вычисление первого аргумента (буква от QUOTE в имени функции). При этом отпадает необходимость апострофа перед первым аргументом

(SETQ a (+ 2 3)) 5,

(SETQ a ‘(+ 2 3)) (+ 2 3).

2.2.2 Числовые функции

Числовые функции выполняют основные математические операции над целыми и дробными числами. К элементарным числовым функциям относятся: сложение, вычитание, умножение и деление. В языке программирования ЛИСП они являются n-арными, т.е. количество их аргументов неограниченно. Они имеют следующий синтаксис

1. (+ ). 3. (* )

2. ( — ) 4. (/ )

и действуют следующим образом

(+ x1 x2 … xn) x1 + x2 + x3 + … + xn.

(– x1 x2 … xn) x1 – x2 – x3 – … – xn.

(* y1 y2 … yn) y1 * y2 * y3 * … * yn.

(/ x1 x2 … xn) x1/x2/… /xn.

Функции увеличения и уменьшения на единицу имеют вид (ADD1 ), (SUB1 ) и возвращают значение, которое на единицу больше (меньше) чем аргумент.

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

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

(numberp n) – число; (integerp n) – целое; (zerop n) = 0;

(plusp n) > 0; (minusp n) < 0;

(oddp n) – четное; (evenp n) – нечетное.

и прочие. Они обычно применяются для построения условных функций.

2.2.3 Базовые функции ЛИСПа

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

(name arg1 arg2 …), где name – имя функции, arg1,arg2,… – ее аргументы.

1. (CAR ) – голова списка.

2. (CDR ) – хвост списка.

3. (CONS ) – присоединение объекта к списку.

4. (EQL ) – сравнение двух атомов.

5. (ATOM ) – проверка, является ли атомом.

CAR и CDR называются селекторными функциями, поскольку они дают возможность выбирать или уничтожать часть объекта. Результатом функции (CAR list) всегда есть первый элемент списка list, если он не пустой и NIL, в противном случае. Результатом функции (CDR list) есть список list без первого элемента, если list содержит больше одного элемента и NIL в противном случае.

(CAR ‘(a b c d)) a (CAR ‘((1 2) (2 3))) ’(1 2)

(CAR ‘()) NIL

(CDR ‘(f q h l t)) ‘( q h l t) (CDR ‘((f q h) l t)) ’( l t))

(CDR ‘(s w)) NIL (CDR ‘(( ) ( ) ( ))) (( ) ( ))

С помощью функций CAR, CDR можно находить по данному списку любой его подсписок или атом. Довольно удобны при обработке списков функции, которые являются комбинациями CAR и CDR. Имена таких функций начинаются на C и заканчиваются R, а между ними находится последовательность букв A (применение CAR) и D (применение CDR), которая указывает путь вычислений.

(CAR (CDR (CDR ‘(1 2 3 4 5 6)))) (CADDR ‘(1 2 3 4 5 6)) 3

(CAR (CAR ‘((1 2)))) (CAAR ‘((1 2))) 1

Вызовы происходят из середины наружу.

Функция конструктора CONS применяется для присоединения объекта к заданному списку. Объект, который добавляется, становится головой списка. Если второй аргумент не задан, то он считается равным NIL.

(CONS ‘a ‘(b c d)) (a b c d)

(CONS ‘(a b) ‘(c d)) ((a b) c d)

В последнем случае мы получили список с подсписками.

Для объединения двух списков в линейный список существует функция (APPEND ), результат действия которой для этого примера был бы

(APPEND ‘(a b) ‘(c d)) (a b c d)

Функцией сравнения является EQL. Она сравнивает значение первого и второго аргумента, которые обязательно должны быть атомами, и возвращает значение истина (Т) или ложь (NIL).

(EQL ‘df ‘df) T (EQL (CAR ‘(q w)) q) T

(EQL (CAR ‘(a h)) NIL) F

При программировании на Лиспе часто возникает вопрос: является ли данный объект атомом. Этот вопрос можно решить с помощью предиката ATOM, который возвращает Т, если объект является атомом и NIL в обратном случае. Пустой список NIL считается атомом.

(ATOM one) T (ATOM ‘(s d h)) F

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

(CONS a ( )) (a).

В общем случае для этой цели существует функция LIST, которая имеет следующий формат записи

(LIST ),

а в результате вызова имеем

(LIST a b c) ’(a b c)

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

(IF (условие) (Then form) (Else form)).

В том случае, когда условие (предикат) не равно NIL, функция возвращает значение Then form, а в противном случае значения Else form.

(IF (minusp a) 0 1)

Поскольку случаи, когда можно ограничиться только формой Then на практике встречаются очень часто и форма Else становится не нужной, в Лиспе существует сокращенная форма условной функции, в которой слово IF опускается

((minusp a) 0).

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *