Clean | |
---|---|
Семантика | функциональный |
Класс языка | чистый функциональный язык программирования[вд], язык программирования и non-strict programming language[вд] |
Появился в | 1987 |
Автор | Software Technology Research Group of Radboud University Nijmegen |
Выпуск | 3.1 (5 января 2022 ) |
Система типов | строгая |
Основные реализации | Clean |
Испытал влияние | Lean |
Лицензия | GNU LGPL |
Сайт | clean.cs.ru.nl (англ.) |
Clean — чистый функциональный язык программирования, поддерживающий основные принципы парадигмы функционального программирования. Для вычислений использует традиционные математические способы вывода значений — унифицированную подстановку и математическую индукцию.
Интегрированная среда разработки (IDE) для Windows включена в дистрибутив Clean.
Язык Clean во многом похож (в том числе и синтаксически) на язык Haskell. Главным отличием Clean от Haskell является способ взаимодействия с внешним состоянием (т.е. способ ввода/вывода): вместо монад Clean использует типы, гарантирующие уникальность. Это обеспечивает более высокую эффективность в соответствующих фрагментах кода, т.к. абстрактные структуры данных деструктивно обновляются, а не замещаются.
Транслятор языка Clean использует переписывание и редукцию[англ.] графов и порождает нативный код относительно высокой эффективности (то обгоняя Haskell, то отставая от него), используя Си в качестве промежуточного языка.
module hello
Start :: {#Char}
Start = "Hello, world!"
module factorial
import StdEnv
fac 0 = 1
fac n = n * fac (n-1)
// Найти факториал 10
Start = fac 10
|
module factorial2
import StdEnv
fac 0 = 1
fac n = prod [1..n] // Произведение чисел от 1 до n
// Найти факториал 6
Start = fac 6
|
module fibonacci
fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
Start = fib 7
Инфиксный оператор:
(^) infixr 8 :: Int Int -> Int
(^) x 0 = 1
(^) x n = x * x ^ (n-1)
В этом объявлении описывается, что функция является правоассоциативным инфиксным оператором с приоритетом 8: это означает, что x*x^(n-1)
эквивалентно x*(x^(n-1))
в противоположность (x*x)^(n-1)
. Этот оператор предварительно определён в StdEnv, стандартной библиотеке Clean.
Вычисления основаны на переписывании и редукции графов[англ.]. Константы, такие как числа, представляют собой графы, а функции — формулы перезаписи графа. Это, в сочетании с компиляцией в машинный код, делает программы, написанные на Clean и использующие высокий уровень абстракции, работающими относительно быстро. Это подтверждается тестами Computer Language Benchmarks Game.
Ранее версии Clean были полностью написаны на языке C во избежание проблем с раскруткой компилятора.
Система SAPL компилирует Core Clean на JavaScript и не использует байт-код ABC.
Чтобы закрыть промежуток между Core Clean, функциональным языком высокого уровня и машинным кодом, используется ABC-машина. Это императивная абстрактная машина для перезаписи графов. Генерирование конкретного машинного кода из абстрактного кода ABC является относительно небольшим шагом, поэтому с помощью ABC-машины гораздо проще генерировать код для нескольких архитектур.
ABC-машина имеет необычную модель памяти[англ.] . Она имеет хранилище графа, чтобы сохранять отредактированный граф во время перезаписи. Стек A (Argument — аргументы) хранит аргументы, относящиеся к узлам в хранилище графов. Таким образом, аргументы узла могут быть переписаны, что необходимо для сопоставления образцов. Стек B (Basic value — основные значения) содержит основные значения (целые числа, символы, числа и т. д.). Хотя это и не является строго необходимым (все эти элементы могут быть узлами в хранилище графов), использование отдельного стека намного эффективнее. Стек C (Control — управление) содержит адреса возвратов для управления потоком.
Clean имеет версии для Microsoft Windows, macOS и Linux.
Некоторые библиотеки недоступны для некоторых платформ. Например, ObjectIO, доступна только для Windows и macOS. Функция записи динамиков в файлы доступна только для Windows.
Синтаксис Clean очень похож на Haskell с некоторыми заметными отличиями:
Haskell | Clean | Remarks |
---|---|---|
[ x | x <- [1..10] , isOdd x]
|
[ x \\ x <- [1..10] | isOdd x]
|
Списковое включение |
x:xs
|
[x:xs]
|
Оператор cons |
data Tree a
= Empty
| Node (Tree a) a (Tree a)
|
:: Tree a
= Empty
| Node (Tree a) a (Tree a)
|
Алгебраический тип данных |
(Eq a, Eq b) => ...
|
... | Eq a & Eq b
|
class assertions and contexts |
fun t@(Node l x r) = ...
|
fun t=:(Node l x r) = ...
|
as-patterns |
if x > 10 then 10 else x
|
if (x > 10) 10 x
|
if |
В основном, у Haskell больше синтаксического сахара, чем у Clean.