stringtranslate.com

Миранда (язык программирования)

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]

Имя

Миранда, картина Джона Уильяма Уотерхауса, 1917 год.

Имя Миранда происходит от герундивной формы латинского глагола 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         будний день ::= Пн | Вт | Мы | эт | Пт | Сб | Вс isWorkDay :: будний день -> bool isWorkDay Sa = False isWorkDay Su = False isWorkDay Anyday = True             дерево * ::= 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 ) Вт ( N E Мы 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 ) = вставить 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 l w r ) = minel l                      || Обход : просмотр значений дерева , помещение их в список         предварительный заказ , дополнительный заказ , последующий заказ :: дерево * -> [ * ] заказ E = [] заказ N l w r = заказ l ++ [ w ] ++ заказ r                    предзаказ 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 ||мне еще нужно это проверить                       isAvl :: tree * -> bool isAvl E = True isAvl ( N l w r ) = and ( isAvl l ) ( isAvl r ), if sum (( nodecount l ) - ( nodecount r )) < 2 = False , в противном случае                              удалить :: * -> дерево * -> дерево * удалить x E = E удалить x ( N E x E ) = E удалить x ( N E x r ) = N E ( 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 )                                                             

Рекомендации

  1. ^ "Страница загрузки Миранды" . Проверено 17 мая 2024 г.
  2. ^ "Миранда: КОПИРОВАНИЕ" . Проверено 17 мая 2024 г.
  3. ^ Тернер, Д.А. (сентябрь 1985 г.). «Миранда: нестрогий функциональный язык с полиморфными типами» (PDF) . В Жуанно, Жан-Пьер (ред.). Функциональные языки программирования и архитектура компьютеров . Конспекты лекций по информатике. Том. 201. Берлин, Гейдельберг: Шпрингер. стр. 1–16. дои : 10.1007/3-540-15975-4_26. ISBN 978-3-540-39677-2.
  4. ^ Худак, Пол; Хьюз, Джон; Пейтон Джонс, Саймон; Уодлер, Филип (9 июня 2007 г.). «История Haskell: лень с классами». Материалы третьей конференции ACM SIGPLAN по истории языков программирования . Нью-Йорк, штат Нью-Йорк, США: ACM. дои : 10.1145/1238844.1238856. ISBN 9781595937667. S2CID  52847907.
  5. ^ Аб Тернер, Дэвид (22 марта 2021 г.). «Открытый исходный код Миранды». Синхронизация кода . Лондон (опубликовано в ноябре 2020 г.) . Проверено 30 декабря 2021 г.
  6. ^ "Страница загрузки Миранды" . www.cs.kent.ac.uk. ​Проверено 30 декабря 2021 г.
  7. ^ "Об имени Миранда" . Проверено 18 мая 2024 г.

Внешние ссылки