Программирование на языке Ocaml
Покупка
Тематика:
Программирование и алгоритмизация
Издательство:
ДМК Пресс
Перевод:
Киселев Артём Николаевич
Год издания: 2014
Кол-во страниц: 536
Дополнительно
Вид издания:
Практическое пособие
Уровень образования:
ВО - Бакалавриат
ISBN: 978-5-97060-102-0
Артикул: 487694.02.99
К покупке доступен более свежий выпуск
Перейти
Эта книга введет вас в мир OCaml, надежный язык программирования, обладающий большой выразительностью, безопасностью и быстродействием. Пройдя через множество примеров, вы быстро поймете, что OCaml - это превосходный инструмент, позволяющий писать быстрый, компактный и надежный системный код. Вы познакомитесь с основными понятиями языка, узнаете о приемах и инструментах, помогающих превратить OCaml в эффективное средство разработки практических приложений. В конце книги вы сможете углубиться в изучение тонких особенностей инструментов компилятора и среды выполнения OCaml.
Тематика:
ББК:
УДК:
ОКСО:
- ВО - Бакалавриат
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.03: Прикладная информатика
- 09.03.04: Программная инженерия
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов.
Для полноценной работы с документом, пожалуйста, перейдите в
ридер.
Программирование на языке OCaml Ярон Мински, Анил Мадхавапедди и Джейсон Хикки
Real World OCaml Bruce A. Tate
Программирование на языке OCaml Москва, 2014 Ярон Мински, Анил Мадхавапедди и Джейсон Хикки
УДК 004.6 ББК 32.973.26 М57 Мински Я., Мадхавапедди А., Хикки Дж. М57 Программирование на языке OCaml / пер. с анг.л А. Н. Киселева. – М.: ДМК Пресс, 2014. – 536 с.: ил. Эта книга введет вас в мир OCaml, надежный язык программирования, обладаю щий большой выразительностью, безопасностью и быстродействием. Пройдя через множество примеров, вы быстро поймете, что OCaml – это превосходный инструмент, позволяющий писать быстрый, компактный и надежный системный код. Вы познакомитесь с основными понятиями языка, узнаете о приемах и инструмен тах, помогающих превратить OCaml в эффективное средство разработки практических приложений. В конце книги вы сможете углубиться в изучение тонких особенностей инструментов компилятора и среды выполнения OCaml. УДК 004.6 ББК 32.973.26 Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Материал, изложенный в данной книге, многократно проверен. Но поскольку вероятность технических ошибок все равно существует, издательство не может гарантировать абсолютную точность и правильность приводимых сведений. В связи с этим издательство не несет ответственности за возможные ошибки, связанные с использованием книги. ISBN 978-1-449-32391-2 (анг.) © 2014 Yaron Minsky, Anil Madhavapeddy, Jason Hickey ISBN 978-5-97060-102-0 (рус.) © Оформление, перевод, ДМК Пресс, 2014 ISBN 978-5-97060-102-0
Моей Лайзе, верящей в силу слов и помогшей мне найти меня. – Ярон Моим маме и папе, отведшим меня в библиотеку и освободившим мое воображение. – Анил Моей Нобу, наполняющей каждый мой день новыми событиями. – Джейсон
Содержание Вступление ...............................................................................................................................14 Часть I. Основы языка .....................................................................................................22 Глава 1. Введение ...............................................................................................................23 OCaml как калькулятор .............................................................................................................23 Функции и автоматический вывод типов ...........................................................................25 Автоматический вывод типов ..........................................................................................27 Автоматический вывод обобщенных типов ................................................................28 Кортежи, списки, необязательные значения и сопоставление с образцом ..............30 Кортежи ...................................................................................................................................30 Списки ......................................................................................................................................31 Необязательные значения .................................................................................................38 Записи и варианты ......................................................................................................................40 Императивное программирование.........................................................................................42 Массивы ...................................................................................................................................42 Изменяемые поля записей ................................................................................................43 Ссылки .....................................................................................................................................45 Циклы for и while .................................................................................................................46 Законченная программа ............................................................................................................48 Компиляция и запуск ..........................................................................................................48 Что дальше .....................................................................................................................................49 Глава 2. Переменные и функции ............................................................................50 Переменные....................................................................................................................................50 Сопоставление с образцом и let .......................................................................................53 Функции..........................................................................................................................................54 Анонимные функции ..........................................................................................................55 Функции нескольких аргументов ...................................................................................57 Рекурсивные функции ........................................................................................................59 Префиксные и инфиксные операторы ..........................................................................60 Объявление функций с помощью ключевого слова function ................................65 Аргументы с метками ..........................................................................................................66 Необязательные аргументы ..............................................................................................69 Глава 3. Списки и образцы ..........................................................................................77 Основы списков ............................................................................................................................77 Использование сопоставления с образцом для извлечения данных из списка .....78 Ограничения (и благословения) сопоставления с образцом .......................................80 Производительность ...........................................................................................................81 Определение ошибок ..........................................................................................................83
Содержание 7 Эффективное использование модуля List ..........................................................................84 Другие полезные функции из модуля List .................................................................88 Хвостовая рекурсия ....................................................................................................................91 Компактность и скорость сопоставления с образцом .....................................................93 Глава 4. Файлы, модули программы.................................................................98 Программы в единственном файле ........................................................................................98 Программы и модули из нескольких файлов .................................................................. 101 Сигнатуры и абстрактные типы ........................................................................................... 103 Конкретные типы в сигнатурах ............................................................................................ 106 Вложенные модули .................................................................................................................. 107 Открытие модулей .................................................................................................................... 109 Подключение модулей ............................................................................................................ 111 Типичные ошибки при работе с модулями ...................................................................... 113 Несовпадение типов ......................................................................................................... 113 Отсутствие определений ................................................................................................. 114 Несоответствие определений типов ........................................................................... 114 Циклические зависимости ............................................................................................. 115 Проектирование с применением модулей ........................................................................ 117 Старайтесь не экспортировать конкретные типы .................................................. 117 Продумывайте синтаксис вызовов .............................................................................. 117 Создавайте однородные интерфейсы ......................................................................... 118 Определяйте интерфейсы до реализации ................................................................. 119 Глава 5. Записи .................................................................................................................. 120 Сопоставление с образцом и полнота ................................................................................ 122 Уплотнение полей ..................................................................................................................... 124 Повторное использование имен полей .............................................................................. 125 Функциональные обновления .............................................................................................. 129 Изменяемые поля ..................................................................................................................... 131 Поля первого порядка ............................................................................................................. 132 Глава 6. Варианты ........................................................................................................... 137 Универсальные образцы и рефакторинг ........................................................................... 139 Объединение записей и вариантов ..................................................................................... 141 Варианты и рекурсивные структуры данных.................................................................. 145 Полиморфные варианты ........................................................................................................ 149 Пример: и снова о цветных терминалах .................................................................... 151 Когда следует использовать полиморфные варианты.......................................... 157 Глава 7. Обработка ошибок ..................................................................................... 159 Типы возвращаемых значений с признаком ошибки ................................................... 159 Кодирование ошибок в результате .............................................................................. 160 Error и Or_error .................................................................................................................. 161
Содержание Функция bind и другие идиомы обработки ошибок ............................................. 163 Исключения ................................................................................................................................ 165 Вспомогательные функции для возбуждения исключений ............................... 167 Обработчики исключений .............................................................................................. 169 Восстановление работоспособности после исключений ..................................... 169 Перехват определенных исключений ......................................................................... 170 Трассировка стека .............................................................................................................. 172 От исключений к типам с информацией об ошибках и обратно ...................... 174 Выбор стратегии обработки ошибок .................................................................................. 175 Глава 8. Императивное программирование ............................................. 177 Пример: императивные словари .......................................................................................... 177 Элементарные изменяемые данные ................................................................................... 182 Данные в формах, подобных массивам ...................................................................... 182 Изменяемые поля записей и объектов и ссылочные ячейки ............................. 183 Внешние функции ............................................................................................................. 184 Циклы for и while ..................................................................................................................... 184 Пример: двусвязные списки .................................................................................................. 186 Изменение списка ............................................................................................................. 188 Итеративные функции .................................................................................................... 189 Отложенные вычисления и другие благоприятные эффекты .................................. 190 Мемоизация и динамическое программирование ................................................. 192 Ввод и вывод ............................................................................................................................... 200 Терминальный ввод/вывод ............................................................................................ 200 Форматированный вывод с помощью printf ............................................................ 202 Файловый ввод/вывод .................................................................................................... 204 Порядок вычислений ............................................................................................................... 207 Побочные эффекты и слабый полиморфизм .................................................................. 209 Ограничение значений .................................................................................................... 210 Частичное применение и ограничение значения ................................................... 211 Ослабление ограничения значений ............................................................................ 212 В заключение .............................................................................................................................. 215 Глава 9. Функторы ........................................................................................................... 216 Простейший пример ................................................................................................................ 216 Более практичный пример: вычисления с применением интервалов .................... 218 Создание абстрактных функторов .............................................................................. 222 Совместно используемые ограничения ..................................................................... 223 Деструктивная подстановка .......................................................................................... 225 Использование нескольких интерфейсов ................................................................. 227 Расширение модулей ............................................................................................................... 231 Глава 10. Модули первого порядка .................................................................. 235 Приемы работы с модулями первого порядка ................................................................ 235
Содержание 9 Пример: фреймворк обработки запросов ......................................................................... 241 Реализация обработчика запросов .............................................................................. 242 Диспетчеризация запросов по нескольким обработчикам ................................. 244 Загрузка и выгрузка обработчиков запросов ........................................................... 248 Жизнь без модулей первого порядка ................................................................................. 252 Глава 11. Объекты ........................................................................................................... 253 Объекты OCaml ........................................................................................................................ 253 Полиморфизм объектов .......................................................................................................... 255 Неизменяемые объекты .......................................................................................................... 257 Когда следует использовать объекты ................................................................................. 258 Подтипизация ............................................................................................................................ 259 Подтипизация в ширину ................................................................................................. 259 Подтипизация в глубину ................................................................................................ 260 Вариантность ...................................................................................................................... 261 Сужение ................................................................................................................................ 265 Подтипизация и рядный полиморфизм .................................................................... 267 Глава 12. Классы .............................................................................................................. 269 Классы в OCaml ........................................................................................................................ 269 Параметры класса и полиморфизм ..................................................................................... 270 Типы объектов и интерфейсы ............................................................................................... 272 Функциональные итераторы ......................................................................................... 274 Наследование ............................................................................................................................. 276 Типы классов .............................................................................................................................. 277 Открытая рекурсия .................................................................................................................. 278 Скрытые методы ........................................................................................................................ 280 Бинарные методы ...................................................................................................................... 281 Виртуальные классы и методы ............................................................................................. 285 Создание простых фигур ................................................................................................ 285 Инициализаторы ....................................................................................................................... 288 Множественное наследование .............................................................................................. 288 Как выполняется разрешение имен ............................................................................ 289 Примеси ................................................................................................................................ 290 Отображение анимированных фигур ......................................................................... 293 Часть II. Инструменты и технологии ................................................................ 295 Глава 13. Отображения и хэш-таблицы ........................................................ 296 Отображения .............................................................................................................................. 297 Создание отображений с компараторами ................................................................. 298 Деревья .................................................................................................................................. 301 Полиморфные компараторы.......................................................................................... 302 Множества ........................................................................................................................... 304
Содержание Соответствие интерфейсу Comparable.S .................................................................. 304 Хэш-таблицы .............................................................................................................................. 307 Соответствие интерфейсу Hashable.S ........................................................................ 310 Выбор между отображениями и хэш-таблицами ........................................................... 311 Глава 14. Анализ командной строки ................................................................ 315 Простейший анализ командной строки ............................................................................ 315 Анонимные аргументы .................................................................................................... 316 Определение простых команд ....................................................................................... 317 Выполнение простых команд ........................................................................................ 317 Типы аргументов ....................................................................................................................... 319 Определение собственных типов аргументов ......................................................... 320 Необязательные аргументы и аргументы по умолчанию .................................... 321 Последовательности аргументов ................................................................................. 324 Добавление поддержки передачи именованных флагов в командной строке ..... 325 Группировка подкоманд ......................................................................................................... 327 Расширенное управление парсингом ................................................................................. 329 Типы в основе Command.Spec ....................................................................................... 330 Объединение фрагментов спецификаций ................................................................ 331 Интерактивный запрос ввода ........................................................................................ 333 Добавление аргументов с метками в функции обратного вызова .................... 335 Автодополнение командной строки средствами Bash ................................................. 336 Создание фрагментов автодополнения ..................................................................... 336 Установка фрагмента автодополнения ...................................................................... 337 Альтернативные парсеры командной строки .................................................................. 338 Глава 15. Обработка данных JSON .................................................................. 339 Основы JSON ............................................................................................................................. 339 Парсинг данных в формате JSON с помощью Yojson ................................................... 340 Выборка значений из структур JSON ............................................................................... 343 Конструирование значений JSON ..................................................................................... 346 Использование нестандартных расширений JSON ...................................................... 348 Автоматическое отображение JSON в типы OCaml ..................................................... 350 Основы ATD ........................................................................................................................ 350 Аннотации ATD ................................................................................................................. 351 Компиляция спецификаций ATD в код на OCaml ................................................ 352 Пример: запрос информации об организации в GitHub ..................................... 353 Глава 16. Парсинг с помощью OCamllex и Menhir ................................ 357 Лексический анализ и парсинг ........................................................................................... 358 Определение парсера ............................................................................................................... 360 Описание грамматики ...................................................................................................... 360 Парсинг последовательностей ...................................................................................... 362 Определение лексического анализатора........................................................................... 364
Содержание 11 Вступление ........................................................................................................................... 364 Регулярные выражения ................................................................................................... 365 Лексические правила ....................................................................................................... 366 Рекурсивные правила ...................................................................................................... 367 Объединяем все вместе ........................................................................................................... 368 Глава 17. Сериализация данных с применением s-выражений ........................................................................................................................ 371 Основы использования ........................................................................................................... 372 Преобразование типов OCaml в s-выражения ........................................................ 374 Формат Sexp ............................................................................................................................... 376 Сохранение инвариантов ....................................................................................................... 377 Вывод информативных сообщений об ошибках ............................................................ 380 Директивы sexp-преобразований ........................................................................................ 382 sexp_opaque .......................................................................................................................... 383 sexp_list ................................................................................................................................. 384 sexp_option ........................................................................................................................... 385 Определение значений по умолчанию ....................................................................... 385 Глава 18. Конкурентное программирование с помощью Async .............................................................................................................. 388 Основы Async ............................................................................................................................. 389 Ivar и upon ............................................................................................................................ 393 Примеры: эхо-сервер................................................................................................................ 395 Усовершенствование эхо-сервера ................................................................................ 399 Пример: поиск определений с помощью DuckDuckGo ............................................... 401 Обработка URI ................................................................................................................... 402 Парсинг строк JSON ......................................................................................................... 402 Выполнение запроса HTTP ........................................................................................... 403 Обработка исключений ........................................................................................................... 406 Мониторы ............................................................................................................................. 408 Пример: обработка исключений при работе с DuckDuckGo.............................. 410 Тайм-ауты, отмена и выбор .................................................................................................... 413 Работа с системными потоками ........................................................................................... 416 Защищенность данных в потоках и блокировки .................................................... 419 Часть III. Система времени выполнения ...................................................... 421 Глава 19. Интерфейс внешних функций ....................................................... 422 Пример: интерфейс к терминалу ......................................................................................... 423 Простые скалярные типы языка C ...................................................................................... 427 Указатели и массивы ................................................................................................................ 429 Выделение памяти для указателей .............................................................................. 430 Использование представлений для отображения составных значений ......... 431
Содержание Структуры и объединения ..................................................................................................... 432 Определение структуры .................................................................................................. 432 Добавление полей в структуры .................................................................................... 433 Незавершенные определения структур ..................................................................... 433 Определение массивов .................................................................................................... 437 Передача функций в код на C ............................................................................................... 438 Пример: быстрая сортировка в командной строке ................................................ 439 Дополнительная информация о взаимодействии с кодом на C ............................... 441 Организация структур в памяти .................................................................................. 442 Глава 20. Представление значений в памяти .......................................... 444 Блоки и значения OCaml ....................................................................................................... 445 Различение целых чисел и указателей во время выполнения ........................... 445 Блоки и значения ...................................................................................................................... 447 Целые числа, символы и другие простые типы ...................................................... 448 Кортежи, записи и массивы ................................................................................................... 448 Вещественные числа и массивы ................................................................................... 449 Варианты и списки ................................................................................................................... 450 Полиморфные варианты ........................................................................................................ 452 Строковые значения ................................................................................................................ 453 Нестандартные блоки памяти .............................................................................................. 454 Управление внешней памятью средствами Bigarray ............................................. 454 Глава 21. Сборка мусора ........................................................................................... 456 Алгоритм сборки мусора ....................................................................................................... 456 Сборка мусора с разделением на поколения ................................................................... 457 Быстрая вспомогательная куча ............................................................................................ 457 Выделение памяти во вспомогательной куче .......................................................... 458 Основная куча долгоживущих блоков .............................................................................. 459 Выделение памяти в основной куче ............................................................................ 460 Стратегии распределения памяти ............................................................................... 461 Маркировка и сканирование кучи ............................................................................... 462 Компактификация кучи .................................................................................................. 463 Указатели между поколениями .................................................................................... 464 Подключение функций-финализаторов к значениям ................................................. 467 Глава 22. Компиляторы: парсинг и контроль типов ........................... 470 Обзор инструментов компилятора ..................................................................................... 470 Парсинг исходного кода ......................................................................................................... 472 Синтаксические ошибки ................................................................................................. 473 Автоматическое оформление отступов в исходном коде .................................... 473 Автоматическое создание документации на основе интерфейсов ................... 475 Препроцессинг исходного кода ............................................................................................ 477 Использование Camlp4 в интерактивной оболочке .............................................. 479
Глава 1. Введение 13 Запуск Camlp4 из командной строки ......................................................................... 480 Препроцессинг сигнатур модулей ............................................................................... 482 Дополнительные источники информации о Camlp4 ............................................ 483 Статическая проверка типов ................................................................................................. 483 Демонстрация типов, выводимых компилятором ................................................. 484 Вывод типов ........................................................................................................................ 486 Модули и раздельная компиляция ............................................................................. 491 Упаковка модулей вместе ............................................................................................... 493 Сокращение путей к модулям в сообщениях об ошибках .................................. 495 Типизированное синтаксическое дерево .......................................................................... 496 Использование ocp-index для поддержки автодополнения ............................... 496 Непосредственное исследование типизированного синтаксического дерева ..................................................................................................................................... 497 Глава 23. Компиляторы: байт-код и машинный код .......................... 501 Нетипизированная lambda-форма ...................................................................................... 501 Оптимизация сопоставлений с образцом ................................................................. 501 Оценка производительности сопоставления с образцом .................................... 504 Переносимый байт-код ........................................................................................................... 506 Компиляция и компоновка байт-кода........................................................................ 507 Выполнение байт-кода .................................................................................................... 508 Встраивание байт-кода OCaml в программы на C ................................................. 509 Компиляция быстрого машинного кода ........................................................................... 511 Исследование ассемблерного кода .............................................................................. 511 Отладка двоичных выполняемых файлов ................................................................ 515 Профилирование машинного кода .............................................................................. 519 Встраивание машинного кода в программы на C ................................................... 521 Сводка по расширениям имен файлов .............................................................................. 522 Алфавитный указатель ............................................................................................... 523
Вступление Почему именно OCaml? Выбор языка программирования играет важную роль. Он влияет на надежность, безопасность и эффективность программ, а также простоту чтения кода, его рефакторинга и расширения. Языки способны также влиять на образ мышления программиста и приемы проектирования программ, даже когда они не используются. Мы решили написать эту книгу, потому что верим в важность выбора языка программирования и особенно в важность изучения OCaml. Каждый из нас имеет более чем 15-летний опыт использования OCaml в академической практике и профессиональной карьере, и к настоящему времени все мы уверены, что этот язык действительно является мощным инструментом для создания сложных программных систем. Наша цель – сделать этот инструмент более доступным для широкого круга программистов, рассказав о нем все, что необходимо для эффективного использования OCaml в повседневной практике. Что делает OCaml особенным, так это то, что он занимает золотую середину в пространстве языков программирования. Он обладает уникальной комбинацией эффективности, выразительности и практичности, которую вы не найдете ни в каком другом языке. В значительной степени это обусловлено превосходным сочетанием некоторых ключевых особенностей OCaml, перечисленных ниже, которые продолжают развиваться уже более 40 лет. Механизм сборки мусора, обеспечивающий автоматическое управление памятью. В наши дни этой особенностью обладают многие современные языки высокого уровня. Функции первого порядка (first-class functions)1, которые можно передавать как самые обычные значения. Аналогичной особенностью обладают, например, JavaScript, Common Lisp и C#. Статический контроль типов для увеличения производительности и снижения числа ошибок, проявляющихся во время выполнения, как в Java и C#. Параметрический полиморфизм, позволяющий конструировать абстракции, применимые к данным разных типов. Похожая особенность существует в Java и C# в виде поддержки обобщенных типов (generics) и в C++? в виде шаблонов. Великолепная поддержка неизменяемых (immutable) данных, обеспечивающих возможность создания программ, не вносящих подчас разрушительных 1 Термин «first-class functions» не имеет устоявшегося перевода на русский язык. В Интернете часто можно встретить такие толкования, как «функции первого рода», «функции первого класса» и даже «первоклассные функции». Однако, чтобы не вносить путаницу и подчеркнуть, что речь идет не о типах, а о свойстве функциональных языков, по согласованию с практиками, имеющими многолетний опыт функционального программирования, было решено использовать толкование «функции первого порядка». – Прим. перев.
15 изменений в структуры данных. Эта особенность является традиционным свойством функциональных языков, таких как Scheme, и поддерживается крупными фреймворками распределенных вычислений, такими как Hadoop. Механизм автоматического вывода типов, позволяющий избежать необходимости кропотливо объявлять тип каждой переменной в программе и автоматически определяющий типы на основе используемых значений. Эта особенность в ограниченном виде присутствует в C# в виде поддержки неявно типизированных локальных переменных (implicitly typed local variables) и в C++11 в виде ключевого слова auto. Алгебраические типы данных и механизм сопоставления с образцом, дающие возможность манипулировать сложными структурами данных. Подобные особенности доступны также в Scala и F#. Некоторые из вас уже знают и с удовольствием используют эти особенности, для других они станут настоящим открытием, но большинство из вас будет встречать некоторые из них и в других языках. Как будет демонстрироваться на протяжении всей книги, наличие всех этих особенностей в одном языке придает ему особую силу. Несмотря на их важность, эти идеи нашли лишь ограниченное применение в господствующих языках, но, даже проникнув в эти языки, например функции первого порядка в C# или параметрический полиморфизм в Java, они обычно принимают ограниченную и нелепую форму. Единственными языками, воплотившими эти идеи в полном объеме, являются функциональные языки со статическим контролем типов, такие как OCaml, F#, Haskell, Scala и Standard ML. В ряду этих достойных языков OCaml стоит особняком, потому что ему удается обеспечить большую власть, оставаясь при этом весьма практичным языком. Компилятор Ocaml использует довольно простую стратегию компиляции и производит высокоэффективный код, не требующий сложных оптимизаций и применения дорогостоящей динамической компиляции (Just-in-Time, JIT). Это, наряду со строгой моделью вычислений в языке OCaml, делает поведение программ легко предсказуемым. Сборщик мусора использует инкрементальный алгоритм, исключая возможность появления длительных пауз на сборку мусора, и обеспечивает высокую точность, в том смысле, что надежно соберет все неиспользуемые данные (в отличие от сборщиков мусора, использующих алгоритмы на основе подсчета ссылок). Все вышеперечисленное делает OCaml превосходным выбором для программистов, желающих освоить лучший язык программирования и в то же время продолжать решать практические задачи. Краткая история развития OCaml был написан группой разработчиков, в состав которой вошли Ксавье Леруа (Xavier Leroy), Джером Вуийон (Je' roˆme Vouillon), Дамиан Долигес (Damien Doligez) и Дидье Реми (Didier Re' my), в 1996 году в институте INRIA (Франция). Он явился результатом многолетних исследований языков семейства ML, разработка которых началась в 60-х годах и которые имеют глубокие связи с академическим сообществом. Почему именно OCaml?
Вступление Язык ML (Meta Language) был создан в 1972 году Робином Милнером (Robin Milner) (работавшим сначала в Стэнфордском, а потом в Кембриджском университете) как метаязык логики вычислимых функций (Logic for Computable Functions, LCF) для построения формальных доказательств. Со временем ML был преобразован в компилятор с целью упростить использование LCF на компьютерах с разной архитектурой и к началу 80-х постепенно превратился в полноценную, развитую систему. Первая реализация языка Caml появилась в 1987 году. Она была создана Аскандером Суаресом (Asca' nder Sua' rez) и продолжена Пьером Вейссом (Pierre Weis) и Мишелем Мони (Michel Mauny). В 1990 году Ксавье Леруа и Дамиан Долигес создали новую реализацию под названием Caml Light, выполненную в виде интерпретатора байт-кода с быстрым, последовательным сборщиком мусора. В течение следующих нескольких лет были разработаны практичные библиотеки, такие как инструменты управления синтаксисом, написанные Мишелем Мони, что способствовало продвижению Caml в академические и исследовательские круги. Ксавье Леруа продолжил работу над языком Caml Light, дополнив его новыми возможностями, что привело к выходу в 1995 году версии Caml Special Light. Она обеспечивала существенно более высокую производительность за счет собственного компилятора, сопоставимую с такими языками, как C++. Система модулей, реализованная в духе Standard ML, также обладала мощными возможностями и упрощала создание крупномасштабных программных продуктов. Современный язык OCaml появился в 1996 году, когда Дидье Реми и Джером Вуйион добавили в него мощную и изящную объектную систему. Примечательной особенностью этой объектной системы была поддержка многих типичных объектно-ориентированных идиом в сочетании со статическим контролем типов, тогда как поддержка тех же идиом в других языках, таких как C++ и Java, требовала дополнительных проверок во время выполнения. В 2000 году Жак Гарриг (Jacques Garrigue) добавил в OCaml еще несколько новых особенностей, таких как полиморфные методы (polymorphic methods), варианты, а также аргументы с метками (labeled arguments) и необязательные аргументы. В последнее десятилетие отмечался значительный рост популярности OCaml и постоянное его совершенствование с целью поддержать растущий коммерческий и академический интерес. Модули первого порядка, обобщённые алгебраические типы данных (Generalized Algebraic Data Types, GADT) и динамическое связывание повысили гибкость языка. Появилась также поддержка аппаратных архитектур x86_64, ARM, PowerPC и Sparc, что превратило OCaml в отличный выбор для систем, где потребление ресурсов, предсказуемость и производительность являются важными факторами. Стандартная библиотека Core Одного языка недостаточно для практического его применения. Для разработки прикладных программ необходим также богатый набор библиотек. Ограниченный объем возможностей стандартной библиотеки OCaml, распространяемой вместе
17 с компилятором, часто является причиной разочарований при изучении OCaml. Именно поэтому стандартную библиотеку не следует рассматривать как универсальный инструмент – она создавалась только для поддержки компилятора и потому целенаправленно сохранялась небольшой, с маленьким количеством функций. К счастью, в мире открытого программного обеспечения ничто не мешает созданию альтернативных библиотек в дополнение к стандартной, и именно они включаются в состав базового дистрибутива. В недрах Jane Street – компании, использующей OCaml уже более десяти лет, – для внутреннего применения была разработана стандартная библиотека Core. Она изначально проектировалась с прицелом на звание универсальной стандартной библиотеки. Как и сам язык OCaml, библиотека Core создавалась с учетом требований к безошибочности, надежности и производительности. Библиотека Core распространяется вместе с дополнительными синтаксическими расширениями, добавляющими новые возможности в язык OCaml, и другими библиотеками, такими как библиотека Async поддержки асинхронных сетевых взаимодействий, обеспечивающая возможность создания сложных распределенных систем только средствами библиотеки Core. Все эти библиотеки распространяются под свободной лицензией Apache 2, что дает возможность беспрепятственно использовать ее в любительских, академических и коммерческих разработках. Платформа OCaml Core – всеобъемлющая и эффективная стандартная библиотека, но, кроме нее, существует еще масса программного обеспечения на OCaml. С момента выхода первой версии OCaml в 1996 году сформировалось обширное сообщество программистов, которым было создано множество полезных библиотек и инструментов. Мы представим некоторые из этих библиотек при рассмотрении примеров в данной книге. Установка этих сторонних библиотек выполняется легко и просто, с помощью инструмента управления пакетами, известного как OPAM. Мы подробнее расскажем об этом инструменте далее в книге, а сейчас просто отметим, что он составляет основу платформы, образуемую инструментами и библиотеками, наряду с компилятором OCaml, которая позволяет быстро и эффективно создавать прикладные программы. Мы также воспользуемся этим инструментом для установки utop – интерфейса командной строки. Это современная интерактивная оболочка, поддерживающая историю команд, интерпретацию макросов, дополнение имен модулей и другие приятные мелочи, которые делают работу с языком намного удобнее. Мы будем использовать utop на протяжении всей книги для опробования примеров. Об этой книге Данная книга предназначена для программистов, имеющих некоторый опыт использования обычных языков программирования, причем необязательно функциональных. В зависимости от уровня подготовки многие понятия, рассматривае Об этой книге
Вступление мые здесь, окажутся для вас незнакомыми, включая названия таких традиционных инструментов функционального программирования, как функции высшего порядка и неизменяемые типы данных, а также некоторые особенности мощной системы типов OCaml и системы модулей. Если вы уже знакомы с языком OCaml, эта книга может преподнести вам немало сюрпризов. Библиотека Core переопределяет многие стандартные пространства имен с целью наделить систему модулей OCaml новыми особенностями и сделать доступными по умолчанию некоторые мощные структуры данных. Старый код на OCaml все еще сможет взаимодействовать с библиотекой Core, но вам может потребоваться изменить его, чтобы получить максимальную выгоду. Весь новый код, который еще только предстоит написать, изначально будет использовать Core, и мы уверены, что время на изучение модели Core не будет потрачено впустую – она с успехом используется многими программами и помогает устранить препятствия, возникающие при создании сложных приложений на OCaml. Код, использующий традиционную стандартную библиотеку компилятора, всегда будет существовать, однако для изучения ее особенностей существует масса ресурсов в Интернете. Книга «Практический OCaml», напротив, описывает приемы, используемые авторами в своей работе, для создания масштабируемых, надежных программных систем. План книги Данная книга делится на три части: первая часть описывает сам язык, начиная с общего обзора OCaml. Не отчаивайтесь, если при чтении этой части что-то останется для вас непонятным. Основная задача данной части – дать вам представление о различных аспектах языка, а идеи, представленные здесь, более подробно будут описаны в последующих главах. После начального знакомства с языком мы перейдем к более сложным особенностям, таким как модули, функторы и объекты, обзор которых займет достаточно много времени. Знание этих понятий играет важную роль. Эти идеи послужат вам хорошим фундаментом, даже при использовании других новейших языков, отличных от OCaml, многие из которых основаны на идеях, заложенных в ML; во второй части закладываются основы разработки типичных приложений на примерах использования инструментов и приемов программирования, от анализа аргументов командной строки до реализации асинхронных сетевых взаимодействий. Попутно вы увидите, как объединяются некоторые понятия, представленные в первой части, в действующие библиотеки и инструменты, сочетающие в себе различные возможности языка; в третьей части обсуждаются система времени выполнения OCaml и набор инструментов компилятора. Эта тема достаточно проста, если сравнивать с реализациями других языков (такими как виртуальная машина Java или .NET CLR). В этой части вы получите все знания, необходимые для соз
К покупке доступен более свежий выпуск
Перейти