Установка: opam, dune и REPL utop
Готовим рабочее окружение: менеджер пакетов opam, сборщик dune и интерактивную консоль utop.
opam — менеджер пакетов и версий компилятора OCaml; dune — система сборки; utop — улучшенный REPL для интерактивных экспериментов.
В мире OCaml экосистема собрана вокруг трёх инструментов, которые стоит понимать с самого начала. Это избавит от путаницы, типичной для новичков, которые пытаются запускать .ml-файлы напрямую и не понимают, где «main».
opam — фундамент
opam (OCaml Package Manager) делает то же, что cargo для Rust или pip+pyenv для Python вместе взятые: ставит библиотеки и управляет версиями самого компилятора.
# установка opam (Linux/macOS)
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh)"
# инициализация и установка компилятора
opam init
opam switch create 5.1.0
eval $(opam env)
# полезные инструменты
opam install dune utop ocaml-lsp-server
Понятие switch — это изолированное окружение с конкретной версией компилятора и набором пакетов, аналог виртуального окружения. Можно держать несколько switch'ей для разных проектов.
utop — площадка для экспериментов
utop — это REPL: вы вводите выражение, нажимаете ;; и Enter, получаете значение вместе с его выведенным типом. Это лучший способ изучать язык: каждое выражение немедленно показывает свой тип.
utop # 1 + 2 ;;
- : int = 3
utop # let greet name = "Привет, " ^ name ;;
val greet : string -> string = <fun>
utop # greet "Аня" ;;
- : string = "Привет, Аня"
Обратите внимание: вы нигде не написали типы, но utop сообщил, что greet имеет тип string -> string. Двойная точка с запятой ;; нужна только в REPL; в обычных файлах она почти не используется.
dune — сборка проектов
Для настоящих программ используют dune. Минимальный проект — это файл dune-project, файл dune с описанием цели и сам исходник:
(* файл: bin/main.ml *)
let () = Printf.printf "Сумма: %d\n" (2 + 3)
# dune-project
(lang dune 3.0)
# bin/dune
(executable (name main))
dune build # собрать
dune exec bin/main.exe # запустить
Вывод:
Сумма: 5
Как работает под капотом
Когда вы пишете dune build, dune строит граф зависимостей между модулями, вызывает компилятор в правильном порядке и кеширует результаты — повторная сборка пересобирает только изменённое. Файлы dune написаны на S-выражениях: это декларативное описание целей, а не императивный скрипт, поэтому dune может распараллеливать работу и точно отслеживать зависимости.
Частые ошибки
- Забыли
eval $(opam env)— тогда оболочка не видитdune/utop. Добавьте эту строку в профиль оболочки. - Ставят
;;в файлах. В.ml-файлах разделители не нужны;;;— артефакт REPL. - Путают точку входа. В OCaml нет обязательной функции
main; точка входа — верхнеуровневое выражениеlet () = ....
Итоги
- opam управляет версиями компилятора (switch) и пакетами.
- utop — REPL, который показывает значение и выведенный тип каждого выражения.
- dune собирает проекты декларативно через файлы
dune-projectиdune.