Миранда (язык программирования)
Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( сентябрь 2016 г. ) |
Парадигма | ленивый , функциональный , декларативный |
---|---|
Разработано | Дэвид Тернер |
Разработчик | ООО «Исследовательское программное обеспечение» |
Впервые появился | 1985 год |
Стабильная версия | 2.066 [1]
/ 31 января 2020 г |
Дисциплина набора текста | сильный , статичный |
Лицензия | Лицензия BSD из 2 пунктов [2] |
Веб-сайт | Миранда |
Основные реализации | |
Миранда | |
Под влиянием | |
KRC , ML , SASL , Хоуп | |
Под влиянием | |
Чистый , Haskell , Orwell , Microsoft Power Fx |
Miranda — это ленивый , чисто функциональный язык программирования , разработанный Дэвидом Тёрнером в качестве преемника его более ранних языков программирования SASL и KRC , с использованием некоторых концепций ML и Hope . Он был произведен английской компанией Research Software Ltd. (которая владеет торговой маркой Miranda ). [3] и был первым чисто функциональным языком, получившим коммерческую поддержку. [ нужна ссылка ]
Миранда была впервые выпущена в 1985 году как быстрый интерпретатор C для операционных систем Unix с последующими выпусками в 1987 и 1989 годах. Она оказала сильное влияние на более поздний язык Haskell . [4] Тернер заявил, что преимущества Миранды перед Хаскеллом заключаются в следующем: «Меньший язык, более простая система типов, более простая арифметика». [5]
В 2020 году версия Miranda была выпущена с открытым исходным кодом под лицензией BSD . Код был обновлен для соответствия современным стандартам C ( C11 / C18 ) и для создания 64-битных двоичных файлов. Это было протестировано на операционных системах, включая Debian , Ubuntu , WSL /Ubuntu и macOS ( Catalina ). [5] [6]
Имя
[ редактировать ]Имя Миранда происходит от герундивной формы латинского глагола miror . [7] означает «вызывать восхищение».
На логотипе изображена Джон Уильям Уотерхаус в исполнении персонажа Миранды из шекспировской «Бури» .
Обзор
[ редактировать ]Миранда — ленивый , чисто функциональный язык программирования. То есть в нем отсутствуют побочные эффекты и обязательные функции программирования. Программа Миранды (называемая скриптом ) представляет собой набор уравнений , определяющих различные математические функции и алгебраические типы данных . слов Здесь важен набор : порядок уравнений, как правило, не имеет значения, и нет необходимости определять сущность перед ее использованием.
Поскольку алгоритм синтаксического анализа разумно использует макет (отступы с помощью правила off-side ), операторы заключения в скобки используются редко, а терминаторы операторов не нужны. Эта функция, вдохновленная ISWIM , также используется в occam и Haskell и позже была популяризирована Python .
Комментарий вводится персонажами в обычные сценарии. ||
и продолжайте до конца той же строки. Альтернативное соглашение о комментариях влияет на весь файл исходного кода, известный как « грамотный сценарий », в котором каждая строка считается комментарием, если она не начинается с символа. >
знак.
Миранды Основные типы данных : char
, num
и bool
. Строка символов — это просто список char
, пока num
автоматически преобразуется между двумя базовыми формами: целыми числами произвольной точности (также известными как большие числа) по умолчанию и обычными с плавающей запятой значениями по мере необходимости.
Кортежи представляют собой последовательности элементов потенциально смешанных типов, аналогичные записям в языках, подобных Паскалю , и записываются через круглые скобки:
this_employee = ("Folland, Mary", 10560, False, 35)
является Вместо этого список наиболее часто используемой структурой данных в Миранде. Он записывается через квадратные скобки и с элементами, разделенными запятыми, причем все они должны быть одного типа:
week_days = ["Mon","Tue","Wed","Thur","Fri"]
Конкатенация списков ++
, вычитание --
, строительство :
, размер есть #
и индексация есть !
, так:
days = week_days ++ ["Sat","Sun"]
days = "Nil":days
days!0
⇒ "Nil"
days = days -- ["Nil"]
#days
⇒ 7
Существует несколько ярлыков для создания списков: ..
используется для списков, элементы которых образуют арифметическую серию, с возможностью указания приращения, отличного от 1:
fac n = product [1..n]
odd_sum = sum [1,3..100]
Более общие и мощные средства построения списков предоставляются « пониманиями списков » (ранее известными как «выражения ZF»), которые существуют в двух основных формах: выражение, применяемое к ряду терминов, например:
squares = [ n * n | n <- [1..] ]
(читается: список n в квадрате, где n берется из списка всех положительных целых чисел) и ряд, в котором каждый член является функцией предыдущего, например:
powers_of_2 = [ n | n <- 1, 2*n .. ]
Как следует из этих двух примеров, Миранда допускает списки с бесконечным числом элементов, из которых самым простым является список всех положительных целых чисел: [1..]
Обозначение применения функции представляет собой просто сопоставление, как в sin x
.
В Миранде, как и в большинстве других чисто функциональных языков, функции являются первоклассными гражданами, то есть их можно передавать в качестве аргументов другим функциям, возвращать как результаты или включать в качестве элементов структур данных. Более того, функция с двумя или более параметрами может быть «частично параметризована» или каррирована , предоставляя меньше аргументов, чем полное количество параметров. Это дает еще одну функцию, которая, учитывая оставшиеся параметры, вернет результат. Например:
add a b = a + b
increment = add 1
это обходной способ создания функции «приращение», которая добавляет единицу к своему аргументу. В действительности, add 4 7
принимает двухпараметрическую функцию add
, применяет его к 4
получение функции с одним параметром, которая добавляет четыре к своему аргументу, а затем применяет это к 7
.
Любую функцию с двумя параметрами (операндами) можно превратить в инфиксный оператор (например, учитывая определение add
функция выше, термин $add
во всех отношениях эквивалентно +
оператор), и каждый инфиксный оператор, принимающий два параметра, можно превратить в соответствующую функцию.
Таким образом:
increment = (+) 1
это самый короткий способ создать функцию, которая добавляет единицу к своему аргументу. Аналогично, в
half = (/ 2)
reciprocal = (1 /)
генерируются две однопараметрические функции. Интерпретатор в каждом случае понимает, какой из двух параметров оператора деления предоставляется, предоставляя функции, которые соответственно делят число на два и возвращают обратное значение.
Хотя Miranda является строго типизированным языком программирования , он не требует явного объявления типов . Если тип функции не объявлен явно, интерпретатор определяет его на основе типа ее параметров и того, как они используются внутри функции. Помимо основных типов ( char
, num
, bool
), он включает в себя тип «что угодно», где тип параметра не имеет значения, как в функции обращения списка:
rev [] = []
rev (a:x) = rev x ++ [a]
который можно применить к списку любого типа данных, для которого явное объявление типа функции будет выглядеть так:
rev :: [*] -> [*]
Наконец, он имеет механизмы для создания и управления программными модулями , внутренние функции которых невидимы для программ, вызывающих эти модули.
Пример кода
[ редактировать ]Следующий скрипт Миранды определяет набор всех подмножеств набора чисел.
subsets [] = [[]]
subsets (x:xs) = [[x] ++ y | y <- ys] ++ ys
where ys = subsets xs
а это грамотный скрипт для функции primes
который дает список всех простых чисел
> || The infinite list of all prime numbers.
The list of potential prime numbers starts as all integers from 2 onwards;
as each prime is returned, all the following numbers that can exactly be
divided by it are filtered out of the list of candidates.
> primes = sieve [2..]
> sieve (p:x) = p : sieve [n | n <- x; n mod p ~= 0]
Вот еще несколько примеров
max2 :: num -> num -> num
max2 a b = a, if a>b
= b, otherwise
max3 :: num -> num -> num -> num
max3 a b c = max2 (max2 a b) (max2 a c)
multiply :: num -> num -> num
multiply 0 b = 0
multiply a b = b + (multiply (a-1) b)
fak :: num -> num
fak 0 = 1
fak n = n * fak (n-1)
itemnumber::[*]->num
itemnumber [] = 0
itemnumber (a:x) = 1 + itemnumber x
weekday::= Mo|Tu|We|Th|Fr|Sa|Su
isWorkDay :: weekday -> bool
isWorkDay Sa = False
isWorkDay Su = False
isWorkDay anyday = True
tree * ::= E| N (tree *) * (tree *)
nodecount :: tree * -> num
nodecount E = 0
nodecount (N l w r) = nodecount l + 1 + nodecount r
emptycount :: tree * -> num
emptycount E = 1
emptycount (N l w r) = emptycount l + emptycount r
treeExample = N ( N (N E 1 E) 3 (N E 4 E)) 5 (N (N E 6 E) 8 (N E 9 E))
weekdayTree = N ( N (N E Mo E) Tu (N E We E)) Th (N (N E Fr E) Sa (N E Su))
insert :: * -> stree * -> stree *
insert x E = N E x E
insert x (N l w E) = N l w x
insert x (N E w r) = N x w r
insert x (N l w r) = insert x l , if x <w
= insert x r , otherwise
list2searchtree :: [*] -> tree *
list2searchtree [] = E
list2searchtree [x] = N E x E
list2searchtree (x:xs) = insert x (list2searchtree xs)
maxel :: tree * -> *
maxel E = error "empty"
maxel (N l w E) = w
maxel (N l w r) = maxel r
minel :: tree * -> *
minel E = error "empty"
minel (N E w r) = w
minel (N l w r) = minel l
||Traversing: going through values of tree, putting them in list
preorder,inorder,postorder :: tree * -> [*]
inorder E = []
inorder N l w r = inorder l ++ [w] ++ inorder r
preorder E = []
preorder N l w r = [w] ++ preorder l ++ preorder r
postorder E = []
postorder N l w r = postorder l ++ postorder r ++ [w]
height :: tree * -> num
height E = 0
height (N l w r) = 1 + max2 (height l) (height r)
amount :: num -> num
amount x = x ,if x >= 0
amount x = x*(-1), otherwise
and :: bool -> bool -> bool
and True True = True
and x y = False
|| A AVL-Tree is a tree where the difference between the child nodes is not higher than 1
|| i still have to test this
isAvl :: tree * -> bool
isAvl E = True
isAvl (N l w r) = and (isAvl l) (isAvl r), if amount ((nodecount l) - (nodecount r)) < 2
= False, otherwise
delete :: * -> tree * -> tree *
delete x E = E
delete x (N E x E) = E
delete x (N E x r) = N E (minel r) (delete (minel r) r)
delete x (N l x r) = N (delete (maxel l) l) (maxel l) r
delete x (N l w r) = N (delete x l) w (delete x r)
Ссылки
[ редактировать ]- ^ «Страница загрузки Миранды» . Проверено 17 мая 2024 г.
- ^ "Миранда: КОПИРОВАНИЕ" . Проверено 17 мая 2024 г.
- ^ Тернер, Д.А. (сентябрь 1985 г.). «Миранда: нестрогий функциональный язык с полиморфными типами» (PDF) . В Жуанно, Жан-Пьер (ред.). Функциональные языки программирования и архитектура компьютеров . Конспекты лекций по информатике. Том. 201. Берлин, Гейдельберг: Шпрингер. стр. 1–16. дои : 10.1007/3-540-15975-4_26 . ISBN 978-3-540-39677-2 .
- ^ Худак, Пол; Хьюз, Джон; Пейтон Джонс, Саймон; Уодлер, Филип (9 июня 2007 г.). «История Haskell: лень с классами» . Материалы третьей конференции ACM SIGPLAN по истории языков программирования . Нью-Йорк, штат Нью-Йорк, США: ACM. дои : 10.1145/1238844.1238856 . ISBN 9781595937667 . S2CID 52847907 .
- ^ Jump up to: а б Тернер, Дэвид (22 марта 2021 г.). «Открытый исходный код Миранды» . Синхронизация кода . Лондон (опубликовано в ноябре 2020 г.) . Проверено 30 декабря 2021 г.
- ^ «Страница загрузки Миранды» . www.cs.kent.ac.uk. Проверено 30 декабря 2021 г.
- ^ «Об имени Миранда» . Проверено 18 мая 2024 г.