Сила OCaml. Разбираемся с типизацией и пишем скрипты

Статически типизированные языки обычно вынуждают писать типы переменных по любому поводу. Но уже далеко не всегда: теория и практика языков программирования значительно ушли вперед, просто эти достижения не сразу принимаются индустрией. Сегодня мы рассмотрим язык OCaml и увидим, что статическая типизация необязательно связана с неудобствами.
 

OCaml и семейство ML

OCaml относится к семейству языков ML. К нему же относятся ныне редкий Standard ML, Microsoft F#, который во многом представляет собой клон OCaml, и, с оговорками, Haskell.

Многие языки семейства ML способны производить статическую проверку типов в коде, где нет ни одного объявления типа переменной благодаря механизму вывода типов. Ограниченную форму вывода типов многие уже видели в Go, где можно не объявлять примитивные типы, а просто писать var x = 10. Swift предоставляет те же возможности. OCaml идет гораздо дальше и выводит типы функций.

let sqr x = x * x (* sqr : int -> int *)

Теоретическая основа вывода типов — алгоритм Хиндли — Милнера. Детерминированный вывод типов возможен не во всех системах. В частности, Haskell использует тот же подход, но функции в нем требуют явного объявления типа. Цена детерминированности — отсутствие полиморфизма ad hoc (перегрузки функций). Каждая функция в OCaml может иметь один и только один тип. Отсутствие перегрузки функций компенсируется «функторами» — параметризованными модулями.

Swift заимствовал многие концепции из ML, в частности алгебраические типы и параметрический полиморфизм, которые обеспечивают удобную и безопасную работу функций с коллекциями (списками) независимо от типа значений. Новые языки для JS также зачастую заимствуют из них, так что знакомство с ML полезно для их понимания.

 

Почему OCaml?

Традиционное применение OCaml и языков семейства ML — разработка компиляторов, средств статического анализа и автоматического доказательства теорем. К примеру, на нем был написан компилятор Rust до того, как он научился компилировать сам себя. OCaml также нашел применение в финансовой сфере, где ошибка в коде может за пару минут довести компанию до банкротства, например в Lexifi и Jane Street.

Пригодным к применению в качестве скриптового его делает особенность реализации: он предоставляет одновременно интерпретатор, компилятор в байт-код и компилятор в машинный код для популярных платформ, в том числе x86 и ARM. Можно начать разработку в интерактивной оболочке интерпретатора, затем записать код в файл. А если скрипт превращается в полноценную программу, скомпилировать ее в машинный код.

В отличие от Haskell, в OCaml используется строгая, а не ленивая модель вычислений, что упрощает ввод-вывод и анализ производительности. Кроме того, он поддерживает изменяемые переменные (ссылки) и прочие средства императивного программирования.

Мы не будем затрагивать веб-скрипты и сосредоточимся на традиционных. В этой статье я также намеренно опускаю создание собственных типов, систему модулей и многие другие возможности. Первая цель — показать «вкус» языка.

 

Установка

Стандартным менеджером пакетов для OCaml стал OPAM. Он может устанавливать сам компилятор, библиотеки и переключаться между разными версиями. Многие системы предоставляют какую-то версию OCaml в репозиториях (часто устаревшую), но с помощью OPAM легко поставить самую свежую от имени обычного пользователя. Для Linux и macOS авторы предоставляют статически скомпилированную версию.

После установки мы поставим самую новую на настоящий момент версию компилятора 4.07 и несколько утилит и библиотек, которые потребуются нам в примерах.

$ opam switch 4.05
$ opam install utop lambdasoup

Для проверки работоспособности запустим utop — интерактивную оболочку интерпретатора. Стандартный интерпретатор (ocaml) слишком «спартанский» — без поддержки истории команд и автодополнения, поэтому его мы будем использовать только в неинтерактивном режиме.

$ utop

utop # print_endline "hello world" ;;
hello world
- : unit = ()

Интерактивный интерпретатор позволяет вводить многострочные выражения, но из-за этого для завершения ввода нужно применять символ ;;. Использовать его в исходном коде допустимо, но излишне.

Источник: xakep.ru

Ответить

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