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

LFE
LFE (Erlang со вкусом Lisp) Logo.png
ПарадигмаМультипарадигма: одновременный, функциональный
СемьяErlang, Лисп
РазработаноРоберт Вирдинг
РазработчикРоберт Вирдинг
Впервые появился2008; 12 лет назад (2008)
Стабильный выпуск
1.3 / 4 июня 2017; 3 года назад (2017-06-04)
Печатная дисциплинадинамичный, сильный
Язык реализацииErlang
ПлатформаIA-32, x86-64
Операционные системыКроссплатформенность
ЛицензияApache 2.0
Расширения имени файла.lfe .hrl
Интернет сайтlfe.io
Под влиянием
Erlang, Common Lisp, Маклисп, Схема, Эликсир, Clojure, Hy
Под влиянием
Joxa, параллельный разработчик

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

История

изначальный выпуск

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

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

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

Мотивы

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

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

Функции

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

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

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

Списки

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

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

Операторы

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

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

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

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

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

Идиомы Erlang в LFE

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

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

Эрланг:

      1> {Лен,Положение дел,Msg} = {8,Ok,"Триллиан"}.      {8,Ok,"Триллиан"}      2> Msg.      "Триллиан"

LFE:

      > (набор (кортеж len положение дел сообщение) #(8 Ok "Триллиан"))      #(8 Ok "Триллиан")      > сообщение      "Триллиан"

Составьте список

Эрланг:

      1> [усечение(математика:пау(3,Икс)) || Икс <- [0,1,2,3]].      [1,3,9,27]

LFE:

      > (список          ((<- Икс '(0 1 2 3)))          (усечение (математика: pow 3 Икс)))      (1 3 9 27)

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

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

Охранники

Эрланг:

      right_number(Икс) когда Икс == 42; Икс == 276709 ->      истинный;      right_number(_) ->      ложный.

LFE:

      (defun правильный номер?        ((Икс) (когда (Орлсе (== Икс 42) (== Икс 276709)))          'истинный)        ((_) 'ложный))

в главах функций

Эрланг:

      сумма(L) -> сумма(L,0).      сумма([], Общий) -> Общий;      сумма([ЧАС|Т], Общий) -> сумма(Т, ЧАС+Общий).

LFE:

      (defun сумма (л) (сумма л 0))      (defun сумма        (('() общий) общий)        (((минусы час т) общий) (сумма т (+ час общий))))

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

      (defun сумма (л) (сумма л 0))      (defun сумма        (('() общий) общий)        ((`(,час . ,т) общий) (сумма т (+ час общий))))

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

Эрланг:

handle_info(пинг, #государственный {remote_pid = неопределенный} = Состояние) ->    gen_server:В ролях(себя(), пинг),    {без ответа, Состояние};handle_info(пинг, Состояние) ->    {без ответа, Состояние};

LFE:

(defun handle_info  (('пинг (= (состояние совпадения удаленный pid 'неопределенный) государственный))    (gen_server: cast (себя) 'пинг)    `#(без ответа ,государственный))  (('пинг государственный)   `#(без ответа ,государственный)))

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

Эрланг:

      универсальный_сервер() ->          получить              {становиться, Func} ->                  Func()          конец.

LFE:

      (defun универсальный сервер ()        (получить          ((кортеж 'становиться func)           (веселье func))))

или же:

      (defun универсальный сервер ()        (получить          (`#(становиться ,func)            (веселье func))))

Примеры

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

Вызов функций Erlang принимает форму (<модуль>: <функция> <аргумент1> ... <аргумент>):

(io: формат "Привет, мир!")

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

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

(defun Акерманн  ((0 п) (+ п 1))  ((м 0) (Акерманн (- м 1) 1))  ((м п) (Акерманн (- м 1) (Акерманн м (- п 1)))))

Составные функции:

(defun сочинять (ж грамм)  (лямбда (Икс)   (веселье ж     (веселье грамм Икс))))(defun проверить ()  (позволять* ((греховный (сочинять #'грех / 1 #'asin / 1))         (ожидал (грех (как в 0.5)))         (составить результат (веселье греховный 0.5)))    (io: формат «Ожидаемый ответ: ~ p ~ n» (список ожидал))    (io: формат "Ответьте, написав: ~ p ~ n" (список составить результат))))

Параллелизм

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

(defmodule посыльный (экспорт (результат печати 0) (Отправить сообщение 2)))(defun результат печати ()  (получить    ((кортеж пид сообщение)      (io: формат "Полученное сообщение: '~ s' ~ n" (список сообщение))      (io: формат "Отправка сообщения процессу ~ p ... ~ n" (список пид))      (! пид (кортеж сообщение))      (результат печати))))(defun Отправить сообщение (телефонный пид сообщение)  (позволять ((порожденный пид (порождать посыльный результат печати ())))    (! порожденный пид (кортеж телефонный пид сообщение))))

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

(defun parse-args (флаг)  "Получив один или несколько аргументов командной строки, извлеките переданные значения.  Например, если через командную строку было передано следующее:    $ erl -my-flag мое-значение-1 -my-flag мое-значение-2  Затем его можно было извлечь в программе LFE, вызвав эту функцию:    (пусть ((args (parse-args 'мой-флаг)))      ...      )  В этом примере значение, присвоенное переменной arg, будет списком  содержащий значения my-value-1 и my-value-2. "  (позволять ((`#(Ok ,данные) (инициализация: get_argument флаг)))    (списки: объединить данные)))(defun Get-Pages ()  «Без аргументов, предположим, что параметр url был передан через командную строку».  (позволять ((URL (parse-args 'url)))    (Get-Pages URL)))(defun Get-Pages (URL)  «Запустите сети и сделайте (потенциально много) HTTP-запросов».  (inets: start)  (plists: карта    (лямбда (Икс)      (получить страницу Икс)) URL))(defun получить страницу (url)  «Сделайте один HTTP-запрос».  (позволять* ((метод 'получать)         (заголовки '())         (данные запроса `#(,url ,заголовки))         (http-параметры ())         (параметры запроса '(#(синхронизировать ложный))))    (httpc: запрос метод данные запроса http-параметры параметры запроса)    (получить      (`#(http #(,идентификатор запроса #(ошибка ,причина)))       (io: формат "Ошибка: ~ p ~ n" `(,причина)))      (`#(http #(,идентификатор запроса ,результат))       (io: формат "Результат: ~ p ~ n" `(,результат))))))

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

  1. ^ Вирдинг, Роберт. "Эрланг, приправленный Лиспом" (PDF). Фабрика Эрланг. Получено 2014-01-17.
  2. ^ а б c "История LFE в списке рассылки Erlang, приправленного Lisp". Получено 2014-05-28.
  3. ^ "Объявление LFE в списке рассылки вопросов Erlang". Получено 2014-01-17.
  4. ^ а б Армстронг, Джо; Вирдинг, Роберт (30 декабря 2013). «Оборудование, использованное при разработке Erlang и LFE» (Обмен электронной почтой). Беседовал Дункан МакГреггор. Получено 2014-01-17.
  5. ^ «Продолжение объявления LFE в списке рассылки вопросов Erlang». Получено 2014-01-17.

внешняя ссылка