Миранда (язык программирования)
Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( сентябрь 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 = ( «Фолланд, Мэри» , 10560 , False , 35 )
является Вместо этого список наиболее часто используемой структурой данных в Миранде. Он записывается в квадратных скобках и с элементами, разделенными запятыми, причем все они должны быть одного типа:
Week_days = [ "Пн" , "Вт" , "Ср" , "Чт" , "Пт" ]
Конкатенация списков ++
, вычитание --
, строительство :
, размер есть #
и индексация есть !
, так:
дни = Week_days ++ [ "Суббота" , "Вс" ]
дни = "Ноль" : дни
дни ! 0
⇒ «Ноль»
дней = дней -- [ «Ноль» ]
# дней
⇒ 7
Существует несколько ярлыков для создания списков: ..
используется для списков, элементы которых образуют арифметическую серию, с возможностью указания приращения, отличного от 1:
fac n = произведение [ 1 .. n ]
нечетная_сумма = сумма [ 1 , 3 .. 100 ]
Более общие и мощные средства построения списков предоставляются « пониманиями списков » (ранее известными как «выражения ZF»), которые существуют в двух основных формах: выражение, применяемое к ряду терминов, например:
квадраты = [ п * п | п <- [ 1 .. ] ]
(читается: список n в квадрате, где n берется из списка всех положительных целых чисел) и ряд, в котором каждый член является функцией предыдущего, например:
полномочия_of_2 = [ n | n <- 1 , 2 * n .. ]
Как следует из этих двух примеров, Миранда допускает списки с бесконечным числом элементов, из которых самым простым является список всех положительных целых чисел: [1..]
Обозначение применения функции представляет собой просто сопоставление, как в sin x
.
В Миранде, как и в большинстве других чисто функциональных языков, функции являются первоклассными гражданами, то есть их можно передавать в качестве аргументов другим функциям, возвращать как результаты или включать в качестве элементов структур данных. Более того, функция с двумя или более параметрами может быть «частично параметризована» или каррирована , предоставляя меньше аргументов, чем полное количество параметров. Это дает еще одну функцию, которая, учитывая оставшиеся параметры, вернет результат. Например:
добавить a b = a + b
приращение = добавить 1
это обходной способ создания функции «приращение», которая добавляет единицу к своему аргументу. В действительности, add 4 7
принимает двухпараметрическую функцию add
, применяет его к 4
получение функции с одним параметром, которая добавляет четыре к своему аргументу, а затем применяет это к 7
.
Любую функцию с двумя параметрами (операндами) можно превратить в инфиксный оператор (например, учитывая определение add
функция выше, термин $add
во всех отношениях эквивалентно +
оператор), и каждый инфиксный оператор, принимающий два параметра, можно превратить в соответствующую функцию.
Таким образом:
приращение = ( + ) 1
это самый короткий способ создать функцию, которая добавляет единицу к своему аргументу. Аналогично, в
половина = ( / 2 )
обратная = ( 1 / )
генерируются две однопараметрические функции. Интерпретатор в каждом случае понимает, какой из двух параметров оператора деления предоставляется, предоставляя функции, которые соответственно делят число на два и возвращают обратное значение.
Хотя Miranda является строго типизированным языком программирования , он не требует явного объявления типов . Если тип функции не объявлен явно, интерпретатор определяет его на основе типа ее параметров и того, как они используются внутри функции. Помимо основных типов ( char
, num
, bool
), он включает в себя тип «что угодно», где тип параметра не имеет значения, как в функции обращения списка:
rev [] = []
rev ( a : x ) = rev x ++ [ a ]
который можно применить к списку любого типа данных, для которого явное объявление типа функции будет выглядеть так:
рев :: [ * ] -> [ * ]
Наконец, он имеет механизмы для создания и управления программными модулями , внутренние функции которых невидимы для программ, вызывающих эти модули.
Пример кода [ править ]
Следующий скрипт Миранды определяет набор всех подмножеств набора чисел.
подмножества [] = [ [] ]
подмножества ( x : xs ) = [[ x ] ++ y | y <- ys ] ++ ys
где ys = подмножества xs
а это грамотный скрипт для функции primes
который дает список всех простых чисел
> || Бесконечный список всех простых чисел.
Список потенциальных простых чисел начинается со всех целых чисел, начиная с 2;
при возврате каждого простого числа все следующие числа, которые могут быть в точности
разделенные по нему, отфильтровываются из списка кандидатов.
> простые числа = решето [2..]
> сито (p:x) = p : сито [n | п <- х; п мод р ~= 0]
Вот еще несколько примеров
max2 :: num -> num -> num
max2 a b = a , если a > b
= b , иначе
max3 :: num -> num -> num -> num
max3 a b c = max2 ( max2 a b ) ( max2 a c )
умножить :: num -> num -> num
умножить 0 b = 0
умножить a b = b + ( умножить ( a - 1 ) b )
fak :: num -> num
fak 0 = 1
fak n = n * fak ( n - 1 )
номер элемента :: [ * ] -> номер
номер элемента [] = 0
номер элемента ( a : x ) = 1 + номер элемента x
день недели ::= Пн | Вт | Мы | эт | Пт | Сб | Su
isWorkDay :: будний день -> bool
isWorkDay Sa = False
isWorkDay Su = False
isWorkDay Anyday = True
Tree * ::= E | N ( дерево * ) * ( дерево * )
количество узлов :: дерево * -> число
узлов E = 0
количество узлов ( N l w r ) = количество узлов l + 1 + количество узлов r
пустое число :: дерево * -> число
пустое количество E = 1
пустое количество ( N l w r ) = пустой счетчик l + пустой счетчик r
TreeExample = N ( N ( N E 1 E ) 3 ( N E 4 E )) 5 ( N ( N E 6 E ) 8 ( N E 9 E ))
будний деньДерево = N ( N ( N E Mo E ) Tu ( N E We E )) Th ( N ( N E Fr E ) Sa ( N E Su ))
вставить :: * -> улица * -> улица *
вставить x E = N E x E
вставить x ( N l w E ) = N l w x
вставить x ( N E w r ) = N x w r
вставить x ( N l w r ) = вставить x l , если x < w
= вставить x r , в противном случае
list2searchtree :: [ * ] -> дерево *
list2searchtree [] = E
list2searchtree [ x ] = N E x E
list2searchtree ( x : xs ) = Insert x ( list2searchtree xs )
maxel :: Tree * -> *
maxel E = ошибка «пустой»
maxel ( N l w E ) = w
maxel ( N l w r ) = maxel r
minel :: дерево * -> *
minel E = ошибка «пустой»
minel ( N E w r ) = w
minel ( N л ш р ) = минель л
|| Обход: проход по значениям дерева ] , размещение их в списке
preorder , inorder , postorder :: tree * -> [ * ]
inorder E = [
inorder N l w r = inorder l ++ [ w ] ++ inorder r
preorder E = []
предварительный заказ N l w r = [ w ] ++ предварительный заказ l ++ предварительный заказ r
последующий заказ E = []
постпорядок N l w r = постпорядок l ++ постпорядок r ++ [ w ]
высота :: дерево * -> число
высота E = 0
высота ( N l w r ) = 1 + max2 ( высота l ) ( высота r )
сумма :: num -> num
сумма x = x , если x >= 0
сумма x = x * ( - 1 ), в противном случае
и :: bool -> bool -> bool
и True True = True
и x y = False
|| AVL - дерево это дерево , котором разница между дочерними узлами не превышает — 1 в
|| мне все еще нужно проверить nodecount это
isAvl :: дерево * -> bool
isAvl E = True
isAvl ( N l w r ) = и ( isAvl l ) ( isAvl r ), if sum (( nodecount l ) - ( r ) ) < 2
= Ложь , противном случае
удалить :: * -> дерево * -> дерево *
удалить x E = E
удалить x ( N E x E ) = E
удалить x ( N E x r ) = NE ( ( minel r ) ( удалить в minel r ) r )
удалить x ( N l x r ) = N ( удалить ( maxel l ) l ) ( maxel l ) r
удалить x ( N l w r ) = N ( удалить x l ) w ( удалить 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 .
- ^ Перейти обратно: а б Тернер, Дэвид (22 марта 2021 г.). «Открытый исходный код Миранды» . Синхронизация кода . Лондон (опубликовано в ноябре 2020 г.) . Проверено 30 декабря 2021 г.
- ^ «Страница загрузки Миранды» . www.cs.kent.ac.uk. Проверено 30 декабря 2021 г.
- ^ «Об имени Миранда» . Проверено 18 мая 2024 г.