Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Языки программирования. Практический сравнитель...doc
Скачиваний:
31
Добавлен:
09.09.2019
Размер:
2.68 Mб
Скачать

16.6. Исключения

Вычисление выражения в языке ML может привести к исключению. Сущест­вуют стандартные исключения, которые в основном возникают при вычисле­ниях со встроенными типами, например при делении на ноль или попытке взять первый элемент пустого списка. Программист также может объявлять исключения, у которых могут быть необязательные параметры:

exception BadParameter of int;

После этого может возникнуть исключение, которое можно обработать:

fun only_positive n =

if n <= 0 then raise BadParameter n

else...

val i = ...;

val j = only_positive i

handle

BadParameter 0 => 1;

BadParameter n => abs n;

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

16.7. Среда

Помимо определений функций и вычисления выражений программа на язы­ке ML может содержать объявления:

val i = 20

val'S = "Hello world"

Таким образом, в языке ML есть память, но, в отличие от процедурных язы­ков, эта память необновляемая; в данном примере нельзя «присвоить» другое значение i или s. Если мы теперь выполним:

val i = 35

будет создано новое именованное значение, скрывающее старое значение, но не заменяющее содержимое i новым значением. Объявления в языке ML ана­логичны объявлениям const в языке С в том смысле, что создается объект, который нельзя изменить; однако повторное определение в языке ML скры­вает предыдущее, в то время как в языке С запрещено повторно объявлять объект в той же самой области действия.

Блочное структурирование можно делать, объявляя определения или вы­ражения как локальные. Синтаксис для локализации внутри выражения по­казан в следующем примере, который вычисляет корни квадратного уравне­ния, используя локальное объявление для дискриминанта:

val а = 1.0 and b = 2.0 and с = 1.0

let

D = b*b-4.0*a*c

in

((- b + D)/2.0*a, (- b - D)/2.0*a )

end

Каждое объявление связывает (binds) значение с именем. Набор всех таких связей, действующих в какой-либо момент времени, называется средой (envi­ronment), и мы говорим, что выражение вычислено в контексте среды. Мы фактически обсуждали среды детально в контексте областей действия и види­мости в процедурных языках; различие состоит в том, что связывания не мо­гут изменяться в среде функционального программирования.

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

abstype int tree =

Empty

| Т of (int tree x int x int tree)

with

fun sumtree t = . . .

fun equal_nodes t1 t2 = .. .

end

Смысл этого объявления состоит в том, что только перечисленные функ­ции имеют доступ к конструкторам абстрактного типа аналогично приватно­му типу в языке Ada или классу в языке C++ с приватными (private) компо­нентами. Более того, абстрактный тип может быть параметризован типовой переменной:

abstype 't tree = . . .

что аналогично созданию родовых абстрактных типов данных в языке Ada.

Язык ML включает очень гибкую систему для определения и управления модулями. Основное понятие — это структура (structure), которая инкапсули­рует среду, состоящую из объявлений (типов и функций), аналогично классу в языке C++ или пакету в языке Ada, определяющему абстрактный тип дан­ных. Однако в языке ML структура сама является объектом, который имеет тип, названный сигнатурой (signature). Структурами можно управлять, ис­пользуя функторы (functors), которые являются функциями, отображающими одну структуру в другую. Это — обобщение родового понятия, которое ото­бражает пакет или шаблоны класса в конкретные типы. Функторы можно ис­пользовать, чтобы скрыть или совместно использовать информацию в струк­турах. Детали этих понятий выходят за рамки данной книги, и заинтересован­ного читателя мы отсылаем к руководствам по языку ML.

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