Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 152
Текст из файла (страница 152)
14.2. Заметим, что операция СО]чЯ в некотором смысле противоположна операциям САА и СО](. Операции СА]( и СРй разбивают списки на части, а операция со](Я создает новый список из его заданных частей. Два параметра операции СО)(Я становятся первым элементом и остальной частью нового списка. Таким образом, если 11в — это список, то результатом следующего выражения будет функция эквивалентности: (СО]ЧЯ (САА 11в) (СОВ 11а)) Функция ЕТЯТ создает список из переменного числа параметров. Это — сокращенная версия вложенных функций СО]ЧЯ, как показано ниже (Е1ЯТ 'арр1е 'огапде 'угаре) Это эквивалентно выражению (СО(4Я ' арр1е (СО]ЧЯ ' огапяе (СО]ЧЯ ' угаре ' () ) ) ] Тремя важными предикатными функциями среди элементарных функций языка Яс)зеве являются функции Е(2?, ]чОЬе? и ЫЯТ?.
Заметим, что все встроенные предикатные функции имеют имена, заканчивающиеся вопросительным знаком. Предикатной называется функция, которая возвращает булевское значение (истина или ложь). В языке Яс)зеше двумя булевскими значениями являются значения (]Т и (] Г. Интерпретатор языка Яс)зеве возвращает пустой список () вместо значения ()Е. Любой ненулевой список, возвращаемый предикатной функцией, интерпретируется как значение (]Т.
Функция ЕО? получает два символьных параметра. Она возвращает значение ()Т, если оба параметра валяются атомами и эквивалентны между собой; в противном случае она возвращает пустой список ( ) . Рассмотрим следующие примеры: (ЕО? 'А 'А) возвращает (]Т (ЕО? 'А 'В) возвращает (]Р (ЕО? 'А '(А В)) возвращает () (ЕО? '(А В) '(А В)] возвращает () или (]Т Глава 14. Функциональные языки программирования (СОНЯ 'А '()) (А) (СОХЯ 'А '(В С)) (А В С) (СОХЯ '() '(А В)) (()А В) х13 (СОНЯ ' (А В) ' (С О) ) ((А В)С О) Рис. 14.2. Результаты несколькит операций СОВ)Е Как показывает последний пример, результат сравнення списков с помощью функции Е()? зависит от конкретной реализации — в одних случаях получится значение ()Т, в других — пустой список ( ] .
Причина этого состоит в том, что функция Е0? часто реализуется как сравнение указателей (ссылаются лн два данных указателя на одно н то же место), н два абсолютно одинаковых списка часто не копируются в памяти, Прн создании списка система языка Бсйеше проверяет, существует лн уже такой список. Прн положительном ответе новый список представляет собой не более, чем указатель на сушествуюшнй список. В этих случаях два списка будут проверяться на совпадение функцией ЕЯ?. Однако иногда трудно обнаружить идентичный список при создании нового. Тогда функция Е0? возвращает пустой список ( ) . Заметим, что функция Е0? всегда работает правильно только с символьными атомами.
Предикаты для сравнения числовых атомов будут описаны ниже. Как уже отмечалось выше, функция Е(з? также ненадежно работаег, когда ее параметрами являются списки. Предикатная функции СТЕТ? возвращает значение ()Т, если ее единственным аргументом является список, в противном случае она возвращает пустой список (), как показано в следующих примерах: 391 14.5.
Введение в язык Вс()еше ().1ЯТ? ' (Х У) ) возвращает ()Т (ЫЯТ? 'Х) возвращает () (ЫЯТ? ' () ) возвращает ()Т Функция н0ьЬ? проверяет, не является ли ее параметр пустым списком, и возвращает в этом случае значение () Т. Рассмотрим следующие примеры: (НВЬЬ? '(А В)) возвращает () (НОЬЬ? '()) возвращает $Т (И0ЬЬ? 'А) возвращает () (%Л.Ь? '(())) возвращает (] В последнем случае возвращается пустой список ( ), потому что параметр — не пустой список, а список, содержащий один элемент, являющийся пустым списком.
Язык Бенеше содержит набор слелуюших предикатных функций для числовых данных. Смысл Фунлт(ил Равно Не равно Больше чем Меньше чем Больше нли равно Меньше или равно Четное ли число? Нечетное ли число? Равно ли число нулю? ЕЧЕ(Ч? 000? ЕЕКО? (НЕИЫИЕ) Эти функции имеют очевидный смысл.
Большинство выводов из программы на языке Бейсике, однако, являются обычными выволами интерпретатора, отображающими результаты применения функции ЕЧАЬ к функциям верхнего уровня. Параметры в языке Бсйеше передщотся по значению, так что независимо от того, что именно функция делает со своими параметрами, фактические параметры не изменяют своего значения. 592 Глава 14. Функциональные языки программирования В отличие от функции ЕО? предикат работает с числовыми, а не с символьными атомами. Для того чтобы проверить атомы на равенство, когда неизвестно, являются ли они символьными илн числовыми, язык Бенеше использует предикат ЕОН?, Работающий как с числовыми, так и с символьными атомами. Основная причина, по которой необходимо применять функции ЕО? или =, а не ЕГг?, там, где это возможно, состоит в том, что функции ЕО? и = работают быстрее, чем функция ЕаЧ?. Язык Бспеюе имеет несколько простых функций вывода, например: (01ЯРЬАУ выражение) 14.$.3. Функцин дпя ностреэвния функций Как указывалось ранее, языки, основанные на языке ЫЕР, используют для определения функций систему лямбла-обозначений в виде списка.
Например, следующий список, содержащий лямбда-выражение, является функцией, возвращающей второй элемент своего заданного параметра, являющегося списком: (ЬАМВРА (Ь) (САВ (СОВ 1 ) ) ) Эту функшпо можно применять таким же образом, как и именованные функции: помещая ее в начале списка, содержащего фактические параметры. Например, мы могли бы записать ( (ЬАИВРА (Ь) (САВ (СРВ Ь) ) ) ' (А В С) ) Это выражение дает в результате В. Заметим, что фактические параметры функций в языке Бс)геше, определенные как параметры лямбда-выражения, не заключаются в кавычки; примером этого является параметр Ь в вызове функции СОВ в приведенном выше выражении.
Параметр Ь называется переменной, связанной с лямбда-выражением. Связанная переменная никогда не изменяется в выражении, после того как она была связана со значением фактического параметра во время первого вызова лямбда-выражения с целью его вычисления. специальная форма — функция ОеГ1(че — предназначена лля связывания имени со значением и с лямбда-выражением. Это может звучать так, будто функцию РЕГ1(4Е можно использовать лля создания переменных в стиле императивных языков. Однако этн связывания имен создают именованные константы, а не переменные. Функция ОЕГ1ИЕО называется специальной формой, поскольку, как мы скоро увидим, она интерпретируется совершенно иначе, чем обычные элементарные функции, например, САВ или арифметические функции.
простейшей формой функции ОВГ1(че является функция, используемая для связывания символа со значением выражения. Эта форма имеет вид; (ОЕГ1(4Е символьное выражение) Например, (ОЕГ1(ЧЕ р1 3.14159) (РЕГ1НЕ Сио рз (" 2 р1)) Если эти два выражения были введены в интерпретатор языка Бенеше, то выводится число 3. 14159; если введено выражение сио рз, выводится число б. 28318. Функцию РЕГ1(ЧЕ можно также использовать для связывания лямбла-выражения с именем. В этом случае связывания лямбда-выражение сокращается, чтобы удалить слово !атЫа. В этой форме функция ОЕГ1)(Е получает в качестве параметров два списка. Первый параметр представляет собой прототип вызова функции, состоящий из имени функции и следующих за ним формальных параметров, перечисленных в виде списка. Второй список является выражением, с которым должно быть связано данное имя.
Общая форма такой функции РеГ1ме приведена ниже: (ОЕГ1(ЧЕ (имя функции параметры) тело ) 14.5. Введение в язык бс))еше Здесь параметры разделены пробелами (не запятыми), а тело представляет собоЯ последовательность выражений в виде списка. В приведенном ниже примере функция ОЕГ1((Е вызывается для того, чтобы связать имя вЧоаге со следующим за ним выражением: (ОЕГ1ЫЕ (вЧцаге пцжЬег) (' пожЬег пшпЬег)) Как только интерпретатор вычислит эту функцию, ее можно использовать, как показано ниже: (вЧоаге 5) Здесь функция в Чоаге дает в качестве результата число 2 5.
семантика специальной формы функции ОВГ1ые при ее использовании дяя определения функции состоит в следующем. Часть первого параметра и весь второй параметр рассматриваются вместе как некое лямбда-выражение. Имя первого параметра связывается с этим выражением. Для того чтобы проиллюстрировать разницу между элементарными функциями и специальной формой функции ОЕГ1(зЕ, рассмотрим выражение (ОЕГ1((Е х 10) если бы функция ОВГ1(че была элементарной, то первое действие функции е((АО над этим выражением заключалось бы в вычислении двух параметров функции ОЕГ1г(Е. Если бы имя х не было связано со значением, возникла бы ошибка.
В качестве следующего примера простой функции рассмотрим выражение (ОЕГ1г(Е (весопс( 1вс) (САВ (СОВ 1вг))) В этом случае имя весопс( связывается с лямбда-выражением ( (1АМВОА (1вс) (САР (СОВ 1вс) ) ) Как только зта функция будет вычислена, ее можно использовать, как показано ниже: (весопс) '(А В С)) Здесь функция возвращает в качестве результата символ В. я 4.$.4.
Поток управлвнив Механизм потока управления в языке Бсйете моделирует поток управления в математических функциях. Поток управления в определениях математических функций отличается от потока управления в программах, написанных на императивных языках программирования. В то время как функции в императивных языках программирования определяются как наборы операторов, содержащие некоторые виды последовательного потока управления, математические функции не имеют мноючисленных операторов и используют лля потока вычислениЯ только рекурсии и условные выражения.
Например, функцию факториала можно определить с помощью двух операторов в слелуюшем виде: ~),если и=О, /(л) = ~и'(Ди- )), если л >О. Заметим, что математические условные выражения записаны в виде списка пар, каждая из которых является защищенным выражением. Каждое защищенное выражение состоит Глава 14. Фуикциоипльнма языки программирования из преднкатной зашиты и выражения. Значение такого условного выражения — это значение выражения, связанного с предикатом, имеюшим значение "истина". Только один из предикатов имеет значение "истина' при заданном параметре или списке параметров.
Язык Яспеше имеет две управляюшие структуры: одну для двухвариантного ветвления и одну лля многовариантного ветвления. Обе структуры имеют специальные формы. Двухвариантный оператор ветвления. называемый 1Г, содержит три параметра: предикатное выражение, выражение если и выражение иначе. Вызов оператора 1Г имеет вид: (1Г предикат выражение если выражение иначе) Например, (0ЕГ1МЕ (1асссг1а1 г.! (1Г ( и 0) 1 (* г, (1ассог1а1 (- и 1))) )) Заметьте, как тесно форма этих функций связана с математическим определением факториала, данным выше.