Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 History  



1.1  Initial release  





1.2  Motives  







2 Features  





3 Syntax and semantics  



3.1  Symbolic expressions (S-expressions)  





3.2  Lists  





3.3  Operators  





3.4  Lambda expressions and function definition  







4 Erlang idioms in LFE  



4.1  Pattern matching  





4.2  List comprehensions  





4.3  Guards  





4.4  cons'ing in function heads  





4.5  Matching records in function heads  





4.6  Receiving messages  







5 Examples  



5.1  Erlang interoperability  





5.2  Functional paradigm  





5.3  Concurrency  







6 References  





7 External links  














LFE (programming language)






עברית
 

Edit links
 









Article
Talk
 

















Read
Edit
View history
 








Tools
   


Actions  



Read
Edit
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Cite this page
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 






From Wikipedia, the free encyclopedia
 


LFE
ParadigmMulti-paradigm: concurrent, functional
FamilyErlang, Lisp
Designed byRobert Virding
DeveloperRobert Virding
First appeared2008; 16 years ago (2008)
Stable release

2.1.1 / 6 January 2023; 18 months ago (2023-01-06)

Typing disciplinedynamic, strong
Implementation languageErlang
OSCross-platform
LicenseApache 2.0
Filename extensions.lfe .hrl
Websitelfe.io
Influenced by
Erlang, Common Lisp, Maclisp, Scheme, Elixir, Clojure, Hy
Influenced
Joxa, Concurrent Schemer

Lisp Flavored Erlang (LFE) is a functional, concurrent, garbage collected, general-purpose programming language and Lisp dialect built on Core Erlang and the Erlang virtual machine (BEAM). LFE builds on Erlang to provide a Lisp syntax for writing distributed, fault-tolerant, soft real-time, non-stop applications. LFE also extends Erlang to support metaprogramming with Lisp macros and an improved developer experience with a feature-rich read–eval–print loop (REPL).[1] LFE is actively supported on all recent releases of Erlang; the oldest version of Erlang supported is R14.

History[edit]

Robert Virding

Initial release[edit]

Initial work on LFE began in 2007, when Robert Virding started creating a prototype of Lisp running on Erlang.[2] This work was focused primarily on parsing and exploring what an implementation might look like. No version control system was being used at the time, so tracking exact initial dates is somewhat problematic.[2]

Virding announced the first release of LFE on the Erlang Questions mail list in March 2008.[3] This release of LFE was very limited: it did not handle recursive letrecs, binarys, receive, or try; it also did not support a Lisp shell.[4]

Initial development of LFE was done with version R12B-0 of Erlang[5] on a Dell XPS laptop.[4]

  • e
  • 1958 1960 1965 1970 1975 1980 1985 1990 1995 2000 2005 2010 2015 2020
     LISP 1, 1.5, LISP 2(abandoned)
     Maclisp
     Interlisp
     MDL
     Lisp Machine Lisp
     Scheme  R5RS  R6RS  R7RS small
     NIL
     ZIL (Zork Implementation Language)
     Franz Lisp
     Common Lisp  ANSI standard
     Le Lisp
     MIT Scheme
     XLISP
     T
     Chez Scheme
     Emacs Lisp
     AutoLISP
     PicoLisp
     Gambit
     EuLisp
     ISLISP
     OpenLisp
     PLT Scheme  Racket
     newLISP
     GNU Guile
     Visual LISP
     Clojure
     Arc
     LFE
     Hy
     Chialisp

    Motives[edit]

    Robert Virding has stated that there were several reasons why he started the LFE programming language:[2]

    Features[edit]

    Syntax and semantics[edit]

    Symbolic expressions (S-expressions)[edit]

    Like Lisp, LFE is an expression-oriented language. Unlike non-homoiconic programming languages, Lisps make no or little syntactic distinction between expressions and statements: all code and data are written as expressions. LFE brought homoiconicity to the Erlang VM.

    Lists[edit]

    In LFE, the list data type is written with its elements separated by whitespace, and surrounded by parentheses. For example, (list 1 2 'foo) is a list whose elements are the integers 1 and 2, and the atom [[foo|foo]]. These values are implicitly typed: they are respectively two integers and a Lisp-specific data type called a symbolic atom, and need not be declared as such.

    As seen in the example above, LFE expressions are written as lists, using prefix notation. The first element in the list is the name of a form, i.e., a function, operator, or macro. The remainder of the list are the arguments.

    Operators[edit]

    The LFE-Erlang operators are used in the same way. The expression

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

    evaluates to 42. Unlike functions in Erlang and LFE, arithmetic operators in Lisp are variadic (orn-ary), able to take any number of arguments.

    Lambda expressions and function definition[edit]

    LFE has lambda, just like Common Lisp. It also, however, has lambda-match to account for Erlang's pattern-matching abilities in anonymous function calls.

    Erlang idioms in LFE[edit]

    This section does not represent a complete comparison between Erlang and LFE, but should give a taste.

    Pattern matching[edit]

    Erlang:

          1> {Len,Status,Msg} = {8,ok,"Trillian"}.
          {8,ok,"Trillian"}
          2> Msg.
          "Trillian"
    

    LFE:

          lfe> (set (tuple len status msg) #(8 ok "Trillian"))
          lfe> ;; or with LFE literal tuple syntax:
          lfe> (set `#(,len ,status ,msg) #(8 ok "Trillian"))
          #(8 ok "Trillian")
          lfe> msg
          "Trillian"
    

    List comprehensions[edit]

    Erlang:

          1> [trunc(math:pow(3,X)) || X <- [0,1,2,3]].
          [1,3,9,27]
    

    LFE:

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

    Or idiomatic functional style:

          lfe> (lists:map
                 (lambda (x) (trunc (math:pow 3 x)))
                 '(0 1 2 3))
          (1 3 9 27)
    

    Guards[edit]

    Erlang:

          right_number(X) when X == 42; X == 276709 ->
            true;
          right_number(_) ->
            false.
    

    LFE:

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

    cons'ing in function heads[edit]

    Erlang:

          sum(L) -> sum(L,0).
          sum([], Total) -> Total;
          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))))
    

    or using a ``cons`` literal instead of the constructor form:

          (defun sum (l) (sum l 0))
          (defun sum
            (('() total) total)
            ((`(,h . ,t) total) (sum t (+ h total))))
    

    Matching records in function heads[edit]

    Erlang:

    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 ,state)))
    

    Receiving messages[edit]

    Erlang:

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

    LFE:

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

    or:

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

    Examples[edit]

    Erlang interoperability[edit]

    Calls to Erlang functions take the form (<module>:<function> <arg1> ... <argn>):

    (io:format "Hello, World!")
    

    Functional paradigm[edit]

    Using recursion to define the Ackermann function:

    (defun ackermann
      ((0 n) (+ n 1))
      ((m 0) (ackermann (- m 1) 1))
      ((m n) (ackermann (- m 1) (ackermann m (- n 1)))))
    

    Composing functions:

    (defun compose (f g)
      (lambda (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 "Expected answer: ~p~n" (list expected))
        (io:format "Answer with compose: ~p~n" (list compose-result))))
    

    Concurrency[edit]

    Message-passing with Erlang's light-weight "processes":

    (defmodule messenger-back
     (export (print-result 0) (send-message 2)))
    
    (defun print-result ()
      (receive
        ((tuple pid msg)
          (io:format "Received message: '~s'~n" (list msg))
          (io:format "Sending message to process ~p ...~n" (list pid))
          (! pid (tuple msg))
          (print-result))))
    
    (defun send-message (calling-pid msg)
      (let ((spawned-pid (spawn 'messenger-back 'print-result ())))
        (! spawned-pid (tuple calling-pid msg))))
    

    Multiple simultaneous HTTP requests:

    (defun parse-args (flag)
      "Given one or more command-line arguments, extract the passed values.
    
      For example, if the following was passed via the command line:
    
        $ erl -my-flag my-value-1 -my-flag my-value-2
    
      One could then extract it in an LFE program by calling this function:
    
        (let ((args (parse-args 'my-flag)))
          ...
          )
      In this example, the value assigned to the arg variable would be a list
      containing the values my-value-1 and my-value-2."
      (let ((`#(ok ,data) (init:get_argument flag)))
        (lists:merge data)))
    
    (defun get-pages ()
      "With no argument, assume 'url parameter was passed via command line."
      (let ((urls (parse-args 'url)))
        (get-pages urls)))
    
    (defun get-pages (urls)
      "Start inets and make (potentially many) HTTP requests."
      (inets:start)
      (plists:map
        (lambda (x)
          (get-page x)) urls))
    
    (defun get-page (url)
      "Make a single HTTP request."
      (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 "Error: ~p~n" `(,reason)))
          (`#(http #(,request-id ,result))
           (io:format "Result: ~p~n" `(,result))))))
    

    References[edit]

    1. ^ Virding, Robert. "Lisp Flavored Erlang" (PDF). Erlang Factory. Retrieved 2014-01-17.
  • ^ a b c "LFE History on the Lisp Flavored Erlang mail list". Retrieved 2014-05-28.
  • ^ "LFE announcement on Erlang Questions mail list". Retrieved 2014-01-17.
  • ^ a b Armstrong, Joe; Virding, Robert (2013-12-30). "Hardware used in the development of Erlang and LFE" (Email exchange). Interviewed by Duncan McGreggor. Retrieved 2014-01-17.
  • ^ "Follow-up to LFE announcement on Erlang Questions mail list". Retrieved 2014-01-17.
  • External links[edit]


    Retrieved from "https://en.wikipedia.org/w/index.php?title=LFE_(programming_language)&oldid=1165968745"

    Categories: 
    Programming languages
    Pattern matching programming languages
    Lisp programming language family
    Hidden categories: 
    Articles lacking reliable references from August 2020
    All articles lacking reliable references
    Articles with example Lisp (programming language) code
    Official website different in Wikidata and Wikipedia
     



    This page was last edited on 18 July 2023, at 15:21 (UTC).

    Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



    Privacy policy

    About Wikipedia

    Disclaimers

    Contact Wikipedia

    Code of Conduct

    Developers

    Statistics

    Cookie statement

    Mobile view



    Wikimedia Foundation
    Powered by MediaWiki