Парадигма | Мультипарадигма : функциональная , императивная |
---|---|
Семья | МЛ |
Разработано | Жерар Юэ , Ги Кузино, Аскандер Суарес, Пьер Вайс, Мишель Мони (Heavy Caml), Ксавье Лерой (Caml Light) |
Разработчик | INRIA , ЭНС |
Впервые появился | 1985 ( 1985 ) |
Стабильный релиз | 0.75 [1] / 26 января 2002 г. ( 2002-01-26 ) |
Дисциплина набора текста | предполагаемый , статический , сильный |
Управление памятью | автоматический |
ОС | Кроссплатформенность : Unix , Linux , macOS ; Windows |
Лицензия | QPL 1, LGPL 2 (Caml Light) |
Веб-сайт | caml.inria.fr |
Под влиянием | |
МЛ | |
Под влиянием | |
OCaml |
Caml (первоначально аббревиатура от Categorical Abstract Machine Language ) — многопарадигмальный , универсальный , высокоуровневый , функциональный язык программирования , являющийся диалектом семейства языков программирования ML . Caml был разработан во Франции во Французском институте исследований в области компьютерных наук и автоматизации (INRIA) и Высшей нормальной школе (Париж) (ENS).
Caml статически типизирован , строго оценивается и использует автоматическое управление памятью . OCaml , главный потомок Caml, добавляет в язык множество функций, включая слой объектно-ориентированного программирования (объектный).
Далее #
представлено приглашение Caml.
Программа «Hello, World!» — это:
print_endline "Привет, мир!" ;;
Многие математические функции, такие как факториал, наиболее естественно представлены в чисто функциональной форме. Следующая рекурсивная, чисто функциональная функция Caml реализует факториал:
пусть рек факт n = если n = 0 , то 1 иначе n * факт ( n - 1 );;
Функцию можно эквивалентно записать, используя сопоставление с образцом :
пусть факт_реф = функция | 0 -> 1 | n - > n * факт ( n - 1 );;
Последняя форма представляет собой математическое определение факториала как рекуррентного соотношения.
Обратите внимание, что компилятор вывел тип этой функции как , что означает, что эта функция отображает целые числа в целые числа. Например, 12! — это:int -> int
# факт 12 ;; - : int = 479001600
Поскольку Caml является функциональным языком программирования , в программах Caml легко создавать и передавать функции. Эта способность имеет очень много применений. Вычисление числовой производной функции является одним из примеров. Следующая функция Caml d
вычисляет численную производную заданной функции f
в заданной точке x
:
пусть d delta f x = ( f ( x +. delta ) -. f ( x -. delta )) /. ( 2 . *. delta );;
Эта функция требует небольшого значения delta
. Хорошим выбором для дельты является кубический корень машинного эпсилона . [ требуется ссылка ] .
Тип функции d
указывает, что она отображает a float
на другую функцию с типом . Это позволяет нам частично применять аргументы. Этот функциональный стиль известен как каррирование . В этом случае полезно частично применить первый аргумент к , чтобы получить более специализированную функцию:(float -> float) -> float -> float
delta
d
# пусть d = d ( sqrt epsilon_float );; val d : ( float -> float ) -> float -> float = < fun >
Обратите внимание, что выведенный тип указывает, что замена d
ожидает функцию с типом в качестве первого аргумента. Мы можем вычислить численное приближение к производной at с помощью:float -> float
# d ( fun x -> x *. x *. x -. x -. 1 .) 3 .;; - : float = 26 .
Правильный ответ — .
Функция d
называется " функцией высшего порядка ", потому что она принимает другую функцию ( f
) в качестве аргумента. Двигаясь дальше, можно создать (приблизительную) производную f, применяя, d
опуская x
аргумент:
# пусть f' = d ( fun x -> x *. x *. x -. x -. 1 .) ;; значение f' : float -> float = < fun >
Концепции каррированных и высших функций явно полезны в математических программах. Эти концепции в равной степени применимы к большинству других форм программирования и могут использоваться для факторизации кода гораздо более агрессивно, что приводит к более коротким программам и меньшему количеству ошибок.
Одномерное вейвлет- преобразование Хаара для списка чисел длиной в целочисленную степень двойки может быть очень лаконично реализовано в Caml и является прекрасным примером использования сопоставления с образцом для списков, при котором пары элементов ( и ) берутся из начала списка и их суммы и разности сохраняются в списках и , соответственно:h1
h2
s
d
# let haar l = let rec aux l s d = сопоставить 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" in aux l [] [] ;; val haar : int list -> int list = < fun >
Например:
# хаар [ 1 ; 2 ; 3 ; 4 ; - 4 ; - 3 ; - 2 ; - 1 ];; - : int список = [ 0 ; 20 ; 4 ; 4 ; - 1 ; - 1 ; - 1 ; - 1 ]
Сопоставление с образцом позволяет представлять сложные преобразования ясно и лаконично. Более того, компилятор Caml превращает сопоставление с образцом в очень эффективный код, что порой приводит к программам, которые короче и быстрее, чем эквивалентный код, написанный с оператором case (Cardelli 1984, стр. 210.).
Первая реализация Caml была написана на языке Lisp Аскандером Суаресом в 1987 году во Французском институте исследований в области компьютерных наук и автоматизации (INRIA). [2]
Его преемник, Caml Light , был реализован на языке C Ксавье Леруа и Дэмиеном Долигесом [2] , а оригинал получил прозвище «Heavy Caml» из-за более высоких требований к памяти и процессору. [2]
Caml Special Light был еще одним полным переписыванием, которое добавило мощную модульную систему к основному языку. Он был дополнен объектно-ориентированным программным (объектным) слоем, чтобы стать Objective Caml , в конечном итоге переименованным в OCaml .