В этой статье слишком много ссылок на первоисточники . ( Август 2020 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) |
Парадигма | Мультипарадигма : параллельная , функциональная |
---|---|
Семья | Эрланг , Лисп |
Разработано | Роберт Вирдинг |
Разработчик | Роберт Вирдинг |
Впервые появился | 2008 |
Стабильный выпуск | 1.3 / 4 июня 2017 г . |
Печатная дисциплина | динамичный , сильный |
Язык реализации | Erlang |
Платформа | IA-32 , x86-64 |
Операционные системы | Кроссплатформенность |
Лицензия | Apache 2.0 |
Расширения имени файла | .lfe .hrl |
Интернет сайт | lfe |
Под влиянием | |
Эрланг , Common Lisp , Maclisp , Scheme , Elixir , Clojure , Hy | |
Под влиянием | |
Джокса, параллельный программист |
Лисп ароматизированное Erlang ( LFE ) является функциональным , одновременно , сбор мусора , универсальный язык программирования и Lisp диалект построен на ядре Erlang и виртуальной машины Erlang ( ЛУЧ ). LFE основан на Erlang, чтобы предоставить синтаксис Lisp для написания распределенных, отказоустойчивых , непрерывных приложений , работающих в режиме мягкого реального времени . LFE также расширяет Erlang для поддержки метапрограммирования с помощью макросов Lisp и улучшенного взаимодействия с разработчиками с помощью многофункционального цикла чтения-оценки-печати (REPL). [1]LFE активно поддерживается во всех последних выпусках Erlang; Самая старая поддерживаемая версия Erlang - R14.
История [ править ]
Первый выпуск [ править ]
Первоначальная работа над LFE началась в 2007 году, когда Роберт Вирдинг начал создавать прототип Lisp, работающий на Erlang. [2] Эта работа была сосредоточена в первую очередь на синтаксическом анализе и изучении того, как может выглядеть реализация. В то время система контроля версий не использовалась, поэтому отслеживать точные начальные даты несколько проблематично. [2]
Вирдинг объявил о первом выпуске LFE в списке рассылки Erlang Questions в марте 2008 года. [3] Этот выпуск LFE был очень ограниченным: он не обрабатывал рекурсивные letrec
s, binary
s receive
, или try
; он также не поддерживает оболочку Lisp. [4]
Первоначальная разработка LFE была выполнена с помощью Erlang [5] версии R12B-0 на ноутбуке Dell XPS. [4]
1955 г. | 1960 г. | 1965 г. | 1970 г. | 1975 г. | 1980 г. | 1985 г. | 1990 г. | 1995 г. | 2000 г. | 2005 г. | 2010 г. | 2015 г. | 2020 г. | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LISP 1, 1.5, LISP 2 (заброшен) | ||||||||||||||
Маклисп | ||||||||||||||
Интерлисп | ||||||||||||||
Лисп-машина Лисп | ||||||||||||||
Схема | R5RS | R6RS | R7RS маленький | |||||||||||
Ноль | ||||||||||||||
Ференц Лисп | ||||||||||||||
Common Lisp | ||||||||||||||
Le Lisp | ||||||||||||||
Т | ||||||||||||||
Chez Scheme | ||||||||||||||
Emacs Lisp | ||||||||||||||
AutoLISP | ||||||||||||||
ПикоЛисп | ||||||||||||||
EuLisp | ||||||||||||||
ISLISP | ||||||||||||||
OpenLisp | ||||||||||||||
Схема PLT | Ракетка | |||||||||||||
GNU Guile | ||||||||||||||
Визуальный LISP | ||||||||||||||
Clojure | ||||||||||||||
Дуга | ||||||||||||||
LFE | ||||||||||||||
Hy |
Мотивы [ править ]
Роберт Вирдинг заявил, что он основал язык программирования LFE по нескольким причинам: [2]
- У него был предыдущий опыт программирования на Лиспе.
- Учитывая его предыдущий опыт, он был заинтересован в реализации своего собственного Лиспа.
- В частности, он хотел реализовать Lisp на Erlang: ему не только было любопытно посмотреть, как он будет работать и интегрироваться с Erlang, он хотел увидеть, как это будет выглядеть .
- С момента оказания помощи в создании языка программирования Erlang у него была цель создать Lisp, который был специально разработан для работы в BEAM и мог полностью взаимодействовать с Erlang / OTP.
- Он хотел поэкспериментировать с компиляцией другого языка на Erlang. Таким образом, он рассматривал LFE как средство для изучения этого, создав Core Erlang и вставив его в бэкэнд компилятора Erlang.
Особенности [ править ]
- Виртуальная машина Erlang с языковым таргетингом (BEAM)
- Полная интеграция с Erlang : вызовы функций Erlang без штрафных санкций (и наоборот)
- Метапрограммирование с помощью макросов Лиспа и гомоиконность Лиспа
- Документация в стиле Common Lisp через комментарии к исходному коду и строки документации
- Параллельное программирование архитектуры без общего доступа через передачу сообщений ( модель акторов )
- Акцент на рекурсию и высшие порядки функций вместо побочного эффекта основанного зацикливание
- Полный цикл чтения-оценки-печати (REPL) для интерактивной разработки и тестирования (в отличие от оболочки Erlang, LFE REPL поддерживает определения функций и макросов)
- Сопоставление с образцом
- Горячая загрузка кода
- Лисп-2 разделение пространств имен для переменных и функций
- Взаимодействие с Java через JInterface и Erjang
- Возможность написания сценариев с обоими
lfe
иlfescript
Синтаксис и семантика [ править ]
Символьные выражения (S-выражения) [ править ]
Как и Лисп, LFE - это язык, ориентированный на выражения . В отличии от не- homoiconic языков программирования, лепечет не делают или мало синтаксических различий между выражениями и заявлениями : весь код и данные записываются в виде выражений. LFE привнесла гомиконность в Erlang VM.
Списки [ править ]
В LFE тип данных списка записывается с элементами, разделенными пробелами и заключенными в круглые скобки. Например, это список, элементами которого являются целые числа и , а также атом . Эти значения неявно типизированы: они представляют собой соответственно два целых числа и специфичный для Лиспа тип данных, называемый символическим атомом , и их не нужно объявлять как таковые.(list 1 2 'foo)
1
2
foo
Как видно из приведенного выше примера, выражения LFE записываются в виде списков с использованием префиксной нотации . Первый элемент в списке - это имя формы , т. Е. Функции, оператора или макроса. Остальная часть списка - аргументы.
Операторы [ править ]
Аналогичным образом используются операторы LFE-Erlang. Выражение
( * ( + 1 2 3 4 5 6 ) 2 )
принимает значение 42. В отличие от функций в Erlang и LFE, арифметические операторы в Lisp являются вариативными (или n-мерными ), способными принимать любое количество аргументов.
Лямбда-выражения и определение функции [ править ]
LFE , как и Common Lisp, имеет лямбда . Однако он также имеет лямбда-сопоставление для учета возможностей сопоставления шаблонов Erlang при вызове анонимных функций.
Идиомы Erlang в LFE [ править ]
Этот раздел не представляет собой полного сравнения Erlang и LFE, но должен дать представление.
Сопоставление с образцом [ править ]
Эрланг:
1 > { Len , Status , Msg } = { 8 , ok , "Trillian" }. { 8 , хорошо , "Триллиан" } 2 > Msg . "Триллиан"
LFE:
> ( set ( tuple len status msg ) # ( 8 ok "Trillian" )) # ( 8 ok "Trillian" ) > msg "Trillian"
Составьте список [ править ]
Эрланг:
1 > [ trunc ( math : 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 )
Или идиоматический функциональный стиль:
> ( списки: map ( lambda ( x ) ( trunc ( math: pow 3 x ))) ' ( 0 1 2 3 )) ( 1 3 9 27 )
Охранники [ править ]
Эрланг:
right_number ( X ), когда X == 42 ; X == 276709 -> верно ; right_number (_) -> ложь .
LFE:
( defun right-number? (( x ) ( when ( orelse ( == x 42 ) ( == x 276709 ))) 'истина ) (( _ ) ' ложь ))
в заголовках функций [ править ]
Эрланг:
сумма ( L ) -> сумма ( L , 0 ). сумма ([], Итого ) -> Итого ; sum ([ H | T ], Total ) -> sum ( T , H + Total ).
LFE:
( defun sum ( l ) ( sum l 0 )) ( defun sum (( ' () total ) total ) ((( cons h t ) total ) ( sum t ( + h total ))))
или используя литерал cons вместо формы конструктора:
( defun sum ( l ) ( sum l 0 )) ( defun sum (( ' () total ) total ) (( ` ( , h . , t ) total ) ( sum t ( + h total )))))
Соответствующие записи в заголовках функций [ править ]
Эрланг:
handle_info ( ping , #state { remote_pid = undefined } = State ) -> gen_server : cast ( self (), ping ), { noreply , State }; handle_info ( ping , State ) -> { noreply , State };
LFE:
( defun handle_info (( 'ping ( = ( match-state remote-pid ' undefined ) state )) ( gen_server: cast ( self ) 'ping ) `# ( noreply , state )) (( ' ping state ) ` # ( noreply , состояние )))
Получение сообщений [ править ]
Эрланг:
universal_server () -> получить { стать , Func } -> Func () end .
LFE:
( DEFUN универсальный-сервер () ( получить (( кортеж «стать Func ) ( FUNCALL Func ))))
или же:
( defun universal-server () ( receive ( `# ( стать , func ) ( funcall func ))))
Примеры [ править ]
Совместимость с Erlang [ править ]
Вызов функций Erlang принимает форму (<модуль>: <функция> <аргумент1> ... <аргумент>) :
( io: формат «Hello, World!» )
Функциональная парадигма [ править ]
Использование рекурсии для определения функции Аккермана :
( defun ackermann (( 0 n ) ( + n 1 )) (( m 0 ) ( ackermann ( - m 1 ) 1 )) (( m n ) ( ackermann ( - m 1 ) ( ackermann m ( - n 1 )) )))
Составные функции:
( defun compose ( f g ) ( lambda ( x ) ( funcall f ( funcall g x ))))( defun check () ( let * (( sin-asin ( compose # ' sin / 1 #' asin / 1 )) ( ожидается ( sin ( asin 0.5 ))) ( compose-result ( funcall sin-asin 0.5 ))) ( io: формат «Ожидаемый ответ: ~ p ~ n» ( ожидаемый список )) ( io: формат «Ответ с составлением: ~ p ~ n» ( список -результат составления ))))
Параллелизм [ править ]
Передача сообщений с помощью легких «процессов» Erlang:
( defmodule messenger-back ( экспорт ( результат печати 0 ) ( отправка сообщения 2 )))( defun print-result () ( receive (( tuple pid msg ) ( io: format "Полученное сообщение: '~ s' ~ n" ( list msg )) ( io: format "Отправка сообщения для обработки ~ p ... ~ n " ( идентификатор списка )) ( ! pid ( сообщение кортежа )) ( результат печати )))) ( defun send-message ( вызывающий-pid msg ) ( let (( spawned-pid ( spawn 'messenger-back ' print-result ()))) ( ! spawned-pid ( кортеж, вызывающий-pid msg ))))
Несколько одновременных HTTP-запросов:
( defun parse-args ( flag ) «Учитывая один или несколько аргументов командной строки, извлеките переданные значения. Например, если через командную строку было передано следующее: $ erl -my-flag мое-значение-1 -my-flag мое-значение-2 Затем его можно было извлечь в программе LFE, вызвав эту функцию: (let ((args (parse-args 'my-flag))) ... ) В этом примере значение, присвоенное переменной arg, будет списком, содержащим значения my-value-1 и my-value-2. " ( let (( ` # ( ok , data ) ( init: get_argument flag ))) ( списки: объединить данные )))( defun get-pages () «Без аргумента, предположим, что 'параметр url был передан через командную строку.» ( let (( urls ( parse-args ' url ))) ( URL get-pages )))( 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 () ) ( параметры-запроса ' ( # ( синхронизация ложь )))) ( httpc: метод запроса данные - запросы http-параметры-параметры- запроса ) ( получить ( `# ( http # (,идентификатор-запроса # ( ошибка , причина ))) ( io: format "Ошибка: ~ p ~ n" ` ( , причина ))) ( ` # ( http # (, идентификатор-запроса , результат )) ( io: формат " Результат: ~ p ~ n " ` ( , результат ))))))
Ссылки [ править ]
- ^ Вирдинг, Роберт. "Эрланг, приправленный Лиспом" (PDF) . Фабрика Эрланг . Проверено 17 января 2014 .
- ^ a b c "История LFE в списке рассылки Erlang, приправленного Lisp" . Проверено 28 мая 2014 .
- ^ "Объявление LFE в списке рассылки вопросов Erlang" . Проверено 17 января 2014 .
- ^ а б Армстронг, Джо; Вирдинг, Роберт (30 декабря 2013). «Оборудование, используемое при разработке Erlang и LFE» (обмен электронной почтой). Беседовал Дункан МакГреггор . Проверено 17 января 2014 .
- ^ "Продолжение объявления LFE в списке рассылки вопросов Erlang" . Проверено 17 января 2014 .
Внешние ссылки [ править ]
- Официальный веб-сайт
- LFE на GitHub
- LFE Быстрый старт
- Руководство пользователя LFE
- LFE по Rosetta Code