Lisp Flavored Erlang


LFE project maintained by Robert Virding Hosted on GitHub @ rvirding/lfe
LFE docs maintained by Duncan McGreggor Hosted on GitHub @ lfe/lfe.github.io

Nothing Quite Compares...

...To the taste of Erlang, aged in the oaken barrels of Lisp, served at a temperature of perfect hotness. New to LFE? Check out our Quick Start guide!

What Is This?

You are at the home page of LFE -- Lisp Flavoured Erlang -- a Lisp syntax front-end to the Erlang compiler. LFE is a Lisp-2, like Common Lisp, and comes with a REPL (shell) for use with interactive coding.

LFE coexists seamlessly with vanilla Erlang and OTP. As such, code written in LFE can freely be used together with modules written in vanilla Erlang and applications in Erlang/OTP.

Features

Below are a selection of code samples representing features available in LFE. There's much more to see, though -- so don't forget to visit the Docs page!

Records

Records are very simple in LFE. They are created with the defrecord form like so:

(defrecord person
  name
  address
  age)

For more information, see the tutorial on LFE records.

Pattern Matching

The power of Erlang's pattern matching is available in Lisp form:

(let (((tuple name place age) #("Ford Prefect" "Betelgeuse Seven" 234)))
  (list name place age))

For more information, see the User Guide as well as the tutorial on pattern matching.

Macros

Here are a couple example LFE macros:

(defmacro caar (x) `(car (car ,x)))
(defmacro list*
  ((list e) e)
  ((cons e es) `(cons ,e (list* . ,es)))
  (() ()))

Note that the functionality represented by the LFE code above was implemented internally in Erlang, not in LFE itself.

More Shiny!

For those that can't wait, here's an example client/server in action:

(defmodule ping_pong
  (export (start_link 0) (ping 0))
  (export (init 1) (handle_call 3) (handle_cast 2)
          (handle_info 2) (terminate 2) (code_change 3))
  (behaviour gen_server)) ;Just indicates intent

(defun start_link ()
  (: gen_server start_link
    (tuple 'local 'ping_pong) 'ping_pong (list) (list)))

;; Client API
(defun ping ()
  (: gen_server call 'ping_pong 'ping))

;; Gen_server callbacks
(defrecord state (pings 0))

(defun init (args)
  (tuple 'ok (make-state pings 0)))

(defun handle_call (req from state)
  (let* ((new-count (+ (state-pings state) 1))
         (new-state (set-state-pings state new-count)))
    (tuple 'reply
           (tuple 'pong new-count)
           new-state)))

(defun handle_cast (msg state)
  (tuple 'noreply state))

(defun handle_info (info state)
  (tuple 'noreply state))

(defun terminate (reason state)
  'ok)

(defun code_change (old-vers state extra)
  (tuple 'ok state))

Cool! How do I start?

LFE documentation is maintained in the source code in the doc directory. There is also a wiki with some excellent content presented there. However, the site you are currently reading is attempting to provide a gentler and more verbose introduction to Lisp Flavored Erlang. We aim to accomplish this in two important ways:

A final resource for the curious and motivated is available in the examples directory of the project repo. Each sample provides functioning code that shows how to use LFE in larger contexts.

Enjoy!