Paradigm | Мультипарадигма : функциональный, императивный |
---|---|
Семейство | ML |
Разработано | Жераром Юэ, (Heavy Caml), Xavier Leroy (Caml Light) |
Впервые появилось | 1985 |
Стабильный выпуск | 0.75 / 26 января 2002 г.; 18 лет назад (26.01.2002) |
Дисциплина ввода | Предполагаемый, статический, сильный |
OS | Кросс-платформенный |
Веб-сайт | caml.inria.fr |
Под влиянием | |
ML | |
Под влиянием | |
OCaml |
Caml (первоначально аббревиатура от Категориальный абстрактный машинный язык ) - это мультипарадигма, язык программирования общего назначения, который является диалектом семейства языков программирования ML. Caml был разработан во Франции в INRIA и ENS.
Caml статически типизирован, строго оценен и использует автоматическое управление памятью. OCaml, главный потомок Caml, добавляет в язык множество функций, в том числе объектный слой .
Далее #
представляет приглашение OCaml.
print_endline "Привет, мир!" ;;
Многие математические функции, такие как факториал, наиболее естественно представлены в чисто функциональной форме. Следующая рекурсивная чисто функциональная функция Caml реализует факториал:
let rec fact n = if n = 0 then 1 else n * fact (n - 1) ;;
Функция может быть записана эквивалентно с использованием сопоставления с образцом :
let rec fact = function | 0 ->1 | n ->n * fact (n - 1) ;;
Эта последняя форма является математическим определением факториала как рекуррентного отношения.
Обратите внимание, что компилятор определил тип этой функции как int ->int
, что означает, что эта функция отображает целые числа в целые числа. Например, 12! это:
# fact 12 ;; -: int = 479001600
Поскольку Caml является языком функционального программирования, легко создавать и передавать функции в программах на Caml. Эта возможность имеет огромное количество приложений. Вычисление числовой производной функции - одно из таких приложений. Следующая функция Caml d
вычисляет числовую производную заданной функции f
в заданной точке x
:
let d delta fx = (f (x +. Delta) -. F ( х -. дельта)) /. (2. *. Delta) ;;
Для этой функции требуется небольшое значение дельта
. Хорошим выбором для дельты является кубический корень машины epsilon.
. Тип функции d
указывает, что она отображает float
на другую функцию с типом (float ->float) ->float ->float
. Это позволяет нам частично применять аргументы. Этот функциональный стиль известен как каррирование. В этом случае полезно частично применить первый аргумент delta
к d
, чтобы получить более специализированную функцию:
# let d = d (sqrt epsilon_float) ;; val d: (float ->float) ->float ->float =
Обратите внимание, что выведенный тип указывает, что замена d
ожидает функцию с типом float ->float
в качестве первого аргумента. Мы можем вычислить численное приближение к производной от при с:
# d (fun x ->x *. X *. X -. X -. 1.) 3. ;; -: float = 26.
Правильный ответ: .
Функция d
называется «функцией высшего порядка», потому что она принимает другую функцию (f
) в качестве аргумента. Мы можем пойти дальше и создать (приблизительную) производную от f, применив d
, опуская аргумент x
:
# let f '= d (fun x ->x *. x *. x -. x -. 1.) ;; val f ': float ->float =
Понятия каррированных функций и функций высшего порядка явно полезны в математических программах. Фактически, эти концепции в равной степени применимы к большинству других форм программирования и могут использоваться для более агрессивного факторизации кода, что приводит к более коротким программам и меньшему количеству ошибок.
1D вейвлет Хаара преобразование целочисленного -степени- двухразмерный список чисел может быть очень лаконично реализован в Caml и является отличным примером использования сопоставления шаблонов над списками, с удалением пар элементов (h1
и h2
) из front и сохраняя их суммы и разности в списках s
и d
соответственно:
# let haar l = let rec aux lsd = сопоставить l, s, d с [s ], d ->s :: d |, s, d ->aux s d | h1 :: h2 :: t, s, d ->aux t (h1 + h2 :: s) (h1 - h2 :: d) | _ ->invalid_arg "haar" в aux l ;; val haar: int list ->int list =
Например:
# haar [1; 2; 3; 4; -4; -3; -2; -1] ;; -: int list = [0; 20; 4; 4; -1; -1; -1; -1]
Сопоставление с образцом позволяет четко и лаконично представить сложные преобразования. Более того, компилятор OCaml превращает сопоставление шаблонов в очень эффективный код, иногда приводя к программам, которые короче и быстрее, чем эквивалентный код, написанный с помощью оператора case (Cardelli 1984, стр. 210).
Первая реализация Caml была написана на Lisp в 1987 году во Французском институте исследований в области компьютерных наук и автоматизации (INRIA).
Его преемник, Caml Light, был реализован в C Xavier Leroy и Damien Doligez, а оригинал получил прозвище «Heavy Caml "из-за более высоких требований к памяти и процессору.
Caml Special Light был дальнейшим полным переписыванием, добавившим мощную модульную систему к основному языку. Он был дополнен объектным слоем и стал Objective Caml, в конечном итоге переименованный в OCaml.