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

ЛФЭ
ПарадигмаМультипарадигма : параллельная , функциональная
СемьяЭрланг , Лисп
РазработаноРоберт Вирдинг
РазработчикРоберт Вирдинг
Впервые появился2008 ; 16 лет назад ( 2008 )
Стабильный релиз
2.1.1 / 6 января 2023 г. ; 21 месяц назад ( 2023-01-06 )
Дисциплина набора текстадинамичный , сильный
Язык реализацииЭрланг
ОСКроссплатформенный
ЛицензияАпач 2.0
Расширения имени файла.lfe .hrl
Веб-сайтlfe.io
Под влиянием
Erlang , Common Lisp , Maclisp , Scheme , Elixir , Clojure , Hy
Под влиянием
Джокса, Конкурентный комбинатор

Lisp Flavored Erlang ( LFE ) — это функциональный , параллельный , собирающий мусор , универсальный язык программирования и диалект Lisp , созданный на основе Core Erlang и виртуальной машины Erlang ( BEAM ). LFE создан на основе Erlang, чтобы предоставить синтаксис Lisp для написания распределенных, отказоустойчивых , мягких приложений реального времени , работающих без остановок. LFE также расширяет Erlang для поддержки метапрограммирования с макросами Lisp и улучшенного опыта разработки с многофункциональным циклом чтения-вычисления-печати (REPL). [1] LFE активно поддерживается во всех последних выпусках Erlang; самая старая поддерживаемая версия Erlang — R14.

История

Роберт Вирдинг

Первоначальный выпуск

Первоначальная работа над LFE началась в 2007 году, когда Роберт Вирдинг начал создавать прототип Lisp, работающий на Erlang. [2] Эта работа была сосредоточена в первую очередь на разборе и исследовании того, как может выглядеть реализация. В то время не использовалась система контроля версий, поэтому отслеживание точных начальных дат было несколько проблематичным. [2]

Вирдинг объявил о первом выпуске LFE в почтовом списке Erlang Questions в марте 2008 года. [3] Этот выпуск LFE был очень ограничен: он не обрабатывал рекурсивные letrecs, binarys, receive, или try; он также не поддерживал оболочку Lisp. [4]

Первоначальная разработка LFE была выполнена с использованием версии R12B-0 Erlang [5] на ноутбуке Dell XPS. [4]

19581960196519701975198019851990199520002005201020152020
 LISP 1, 1.5, LISP 2 (заброшен)
 Маклисп
 Интерлисп
 молдавский лей
 Лисп-машина Лисп
 Схема Р5РС Р6РС R7RS маленький
 НОЛЬ
 ZIL (язык реализации Zork)
 Франц Лисп
 Общий Лисп стандарт ANSI
 Ле Лисп
 Схема Массачусетского технологического института
 XLISP
 Т
 Chez Схема
 Emacs Лисп
 АвтоЛИСП
 ПикоЛисп
 Гамбит
 EuLisp
 ИСЛИСП
 OpenLisp
 Схема ПЛТ Ракетка
 новыйLISP
 GNU-хитрость
 Визуальный ЛИСП
 Кложур
 Дуга
 ЛФЭ
 Хай
 Хиалисп

Мотивы

Роберт Вирдинг заявил, что было несколько причин, по которым он начал разрабатывать язык программирования LFE: [2]

  • У него был опыт программирования на Lisp.
  • Учитывая его предыдущий опыт, он был заинтересован в реализации собственного Lisp.
  • В частности, он хотел реализовать Lisp в Erlang: ему было не только любопытно посмотреть, как он будет работать и интегрироваться с Erlang, он хотел увидеть, как он будет выглядеть .
  • С тех пор как он помог создать язык программирования Erlang, у него появилась цель создать Lisp, специально предназначенный для работы на BEAM и способный полностью взаимодействовать с Erlang/OTP.
  • Он хотел поэкспериментировать с компиляцией другого языка на Erlang. Таким образом, он рассматривал LFE как средство для исследования этого, генерируя Core Erlang и подключая его к бэкэнду компилятора Erlang.

Функции

Синтаксис и семантика

Символические выражения (S-выражения)

Как и Lisp, LFE — это язык, ориентированный на выражения . В отличие от не- гомиконических языков программирования, Lisp не делает или делает небольшое синтаксическое различие между выражениями и операторами : весь код и данные записываются как выражения. LFE привнес гомоиконичность в Erlang VM.

Списки

В LFE тип данных list записывается с элементами, разделенными пробелами и заключенными в скобки. Например, это список, элементами которого являются целые числа и , а также атом [[foo| ]]. Эти значения неявно типизированы: они представляют собой соответственно два целых числа и специфичный для Lisp тип данных, называемый символическим атомом , и не должны быть объявлены как таковые.(list 1 2 'foo)12foo

Как видно из примера выше, выражения LFE записываются в виде списков с использованием префиксной нотации . Первый элемент в списке — это имя формы , т. е. функции, оператора или макроса. Остальная часть списка — это аргументы.

Операторы

Операторы LFE-Erlang используются таким же образом. Выражение

 ( * ( + 1 2 3 4 5 6 ) 2 )        

вычисляется как 42. В отличие от функций в Erlang и LFE, арифметические операторы в Lisp являются вариативными (или n-арными ), способными принимать любое количество аргументов.

Лямбда-выражения и определение функций

LFE имеет lambda , как и Common Lisp. Однако, он также имеет lambda-match для учета возможностей Erlang по сопоставлению с образцом в анонимных вызовах функций.

Идиомы Erlang в LFE

Этот раздел не представляет собой полное сравнение Erlang и LFE, но может дать представление.

Сопоставление с образцом

Эрланг:

 1 > { Лен , Статус , Сообщение } = { 8 , ок , «Триллиан» }. { 8 , ок , «Триллиан» } 2 > Сообщение . "Триллиан"       

ЛФЭ:

 lfe> ( set ( tuple len status msg ) #( 8 ok "Trillian" )) lfe> ;; или с синтаксисом кортежа литерала LFE: lfe> ( set `#(, len , status , msg ) #( 8 ok "Trillian" )) #( 8 ok "Trillian" ) lfe> msg "Trillian"                        

Список понятий

Эрланг:

 1 > [ trunc ( математика : pow ( 3 , X )) || X <- [ 0 , 1 , 2 , 3 ]]. [ 1 , 3 , 9 , 27 ]      

ЛФЭ:

 lfe> ( list-comp (( <- x ' ( 0 1 2 3 ))) ( trunc ( math:pow 3 x ))) ( 1 3 9 27 )               

Или идиоматический функциональный стиль:

 lfe> ( списки: карта ( лямбда ( x ) ( усечение ( математика: сила 3 ​​x ))) ' ( 0 1 2 3 )) ( 1 3 9 27 )               

Охранники

Эрланг:

 right_number ( X ) когда X == 42 ; X == 276709 -> true ; right_number (_) -> false .            

ЛФЭ:

 ( defun right-number? (( x ) ( when ( orelse ( == x 42 ) ( == x 276709 ))) 'true ) (( _ ) 'false ))             

cons'ing в головках функций

Эрланг:

 сумма ( L ) -> сумма ( L , 0 ). сумма ([], Всего ) - > Всего ; сумма ([ H | T ], Всего ) -> сумма ( T , H + Всего ).           

ЛФЭ:

 ( defun sum ( l ) ( sum l 0 )) ( defun sum (( ' () итого ) итого ) ((( cons h t ) итого ) ( сумма t ( + h итого ))))                   

или используя литерал ``cons`` вместо формы конструктора:

 ( defun sum ( l ) ( sum l 0 )) ( defun sum (( ' () итог ) итог ) (( ` ( , час . , t ) итог ) ( сумма t ( + час итог ))))                   

Сопоставление записей в заголовках функций

Эрланг:

handle_info ( ping , #state { remote_pid = undefined } = State ) -> gen_server : cast ( self (), ping ), { noreply , State }; handle_info ( ping , State ) -> { noreply , State };               

ЛФЭ:

( defun handle_info (( 'ping ( = ( match-state remote-pid ' undefined ) state )) ( gen_server:cast ( self ) 'ping ) `#( noreply , state )) (( 'ping state ) `#( noreply , state )))                

Получение сообщений

Эрланг:

 universal_server () -> receive { become , Func } -> Func () end .       

ЛФЭ:

 ( defun universal-server () ( receive (( tuple 'become func ) ( funcall func ))))        

или:

 ( defun universal-server () ( receive ( `#( become , func ) ( funcall func ))))       

Примеры

Совместимость с Erlang

Вызовы функций Erlang имеют вид (<модуль>:<функция> <arg1> ... <argn>) :

( io:format "Привет, мир!" ) 

Функциональная парадигма

Использование рекурсии для определения функции Аккермана :

( defun акерман (( 0 n ) ( + n 1 )) (( m 0 ) ( акерман ( - m 1 ) 1 )) (( m n ) ( акерман ( - m 1 ) ( акерман m ( - n 1 )))))                        

Функции сочинения:

( defun compose ( f g ) ( лямбда ( x ) ( funcall f ( funcall g x ))))          ( defun check () ( let* (( sin-asin ( compose #' sin/1 #' asin/1 )) ( expected ( sin ( asin 0.5 ))) ( compose-result ( funcall sin-asin 0.5 ))) ( io:format "Ожидаемый ответ: ~p~n" ( list expected )) ( io:format "Ответ с помощью compose: ~p~n" ( list compose-result ))))                       

Параллелизм

Передача сообщений с помощью легковесных «процессов» Erlang:

( defmodule messenger-back ( export ( print-result 0 ) ( send-message 2 )))      ( defun print-result () ( receive (( tuple pid msg ) ( io:format "Получено сообщение: '~s'~n" ( list msg )) ( io:format "Отправка сообщения процессу ~p ...~n" ( list pid )) ( ! pid ( tuple msg )) ( print-result ))))                   ( defun send-message ( calls-pid msg ) ( let (( spawned-pid ( spawn 'messenger-back ' print-result ()))) ( ! spawned- pid ( tuple calls-pid msg ))))              

Несколько одновременных HTTP-запросов:

( defun parse-args ( flag ) "Для заданного одного или нескольких аргументов командной строки извлечь переданные значения.    Например, если через командную строку было передано следующее: $ erl -мой-флаг мое-значение-1 -мой-флаг мое-значение-2 Затем его можно извлечь в программе LFE, вызвав эту функцию: (let ((args (parse-args 'my-flag)))  ...  )  В этом примере значение, присвоенное переменной arg, будет списком,  содержащим значения my-value-1 и my-value-2." ( let (( `#( ok , data ) ( init:get_argument flag ))) ( lists:merge data )))       ( defun get-pages () "Без аргументов предположим, что параметр 'url был передан через командную строку." ( let (( urls ( parse-args 'url ))) ( get-pages urls )))         ( defun get-pages ( urls ) "Запустить inets и сделать (потенциально много) HTTP-запросов." ( inets:start ) ( plists:map ( lambda ( x ) ( get-page x )) urls ))          ( defun get-page ( url ) "Сделать один HTTP-запрос." ( let* (( method 'get ) ( headers ' ()) ( request-data `#(, url , headers )) ( http-options ()) ( request-options ' ( #( sync false )))) ( httpc:request method request-data http-options request-options ) ( receive ( `#( http #(, request-id #( error , reason ))) ( io:format "Ошибка: ~p~n" ` ( , reason ))) ( `#( http #(, request-id , result )) ( io:format "Результат: ~p~n" ` ( , result ))))))                                   

Ссылки

  1. ^ Вирдинг, Роберт. "Lisp Flavored Erlang" (PDF) . Erlang Factory . Получено 17.01.2014 .
  2. ^ abc "История LFE в почтовой рассылке Lisp Flavored Erlang" . Получено 28.05.2014 .
  3. ^ "Объявление LFE в почтовой рассылке Erlang Questions" . Получено 17.01.2014 .
  4. ^ ab Armstrong, Joe; Virding, Robert (2013-12-30). "Аппаратное обеспечение, используемое при разработке Erlang и LFE" (переписка по электронной почте). Интервью с Дунканом Макгрегором . Получено 2014-01-17 .
  5. ^ "Продолжение объявления LFE в почтовой рассылке Erlang Questions" . Получено 2014-01-17 .
  • Официальный сайт
  • LFE на GitHub
  • Быстрый старт LFE
  • Руководство пользователя LFE
  • LFE о коде Rosetta
Взято с "https://en.wikipedia.org/w/index.php?title=LFE_(язык_программирования)&oldid=1165968745"