Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[16]

Глава 3

3.1 Обзор

Возможность разложения большой программы на некоторое количество относительно независимых модулей с четко определенным интерфейсом является крайне важной при разработке крупных программных продуктов. Модули в ML предназначены для решения этой проблемы.

Многие из современных языков программирования обладают подобными свойствами. К сожалению, в этой области не сложилось единой терминологии. Программные компоненты называются "модулями", "пакетами", "кластерами" и т.д., и т.п. В ML используется термин "структура", как сокращение для "структура среды". Такой выбор терминологии говорит о том, что в ML программный модуль есть инструмент построения среды. Напомним, что среда есть хранилище информации о смысле идентификаторов, объявленных в программе. Например, в результате выполнения объявления val х=3 в среде появляется запись о том, что идентификатор х привязан к значению 3 типа int. Таким образом, разбиение программы на модули в ML понимается как разбиение среды на отдельные части, которыми можно манипулировать относительно независимо друг от друга. Мы говорим "относительно", поскольку, если несколько модулей объединяются в одну программу, они должны хоть как-то взаимодействовать между собой. Следовательно, должна быть какая-то возможность описания и организации этого взаимодействия. Это называется проблемой соиспользования (sharing).

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


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

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

Функтором называется функция, преобразующая структуры в структуры. Идея функтора состоит в следующем: если какая-либо структура S зависит от структуры T только в той части, которая описана в сигнатуре T, то структура S может быть изолирована от деталей реа-T

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

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

ТИПОВ ДЭННТ>ТХ..

Мы начнем наше введение в модульную структуру ML с рассмотрения структур и сигнатур.

3.2 Структуры и сигнатуры

Структура есть не что иное, как "материализованная" среда, превращенная в объект, которым можно манипулировать. Основным средством определения структур являются инкапсулированные объявления, состоя-


щие из последовательности объявлений, заключенных в синтаксические скобки struct и end. Вот простой пример инкапсулированного объявления:

type t = int; val x = 3;

fun f(x) = if x=0 then 1 else x*f(x-1) end

"Значением" этого инкапсулированного объявления является структура, в которой идентификатор типа t привязан к типу int, а идентификаторы значений х и f привязаны соответственно к числу 3 и к функции вычисления факториала. Хотя мы и склонны рассматривать структуры как некоторый сорт значений, их статус отличается от статуса обычных значений. В частности, инкапсулированное объявление нельзя просто написать на верхнем уровне диалога - как, например, можно написать арифметическое выражение. Однако к нему можно привязать идентификатор - но и эта форма объявления, называемая привязкой к структуре, может появиться только либо на верхнем уровне диалога, либо внутри инкапсулированного объявления. На время мы ограничим наше внимание только привязками к структурам на верхнем уровне, а привязки внутри инкапсулированного объявления рассмотрим позже. К приведенному выше инкапсулированному объявлению может быть привязан идентификатор следующим способом:

- structure S = struct

type t = int; val x = 3;

fun f(x) = if x=0 then 1 else x*f(x-l) end;

> structure S = struct

type t = int

val f = fn : int -> int

val x = 3 : int end

Обратите внимание на то, что результат привязки к структуре является средой1. ML печатает среду, получающуюся в результате выполнения объявлений между struct и end почти в той же форме, в какой выводятся сообщения после объявлений на верхнем уровне. Конечно, структура

1По техническим причинам некоторые реализации ML переупорядочивают компоненты среды перед выводом на экран.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32]