Learn LFE

From first taste to deep mastery — follow your curiosity at the pace that suits you.

What does LFE look like?

You saw the basics on the home page — pattern matching, data types, macros. Here’s what those ideas look like when they start working together:

;; Erlang tuples + Lisp pattern matching = expressive dispatch
(defun handle
  ((`#(ok ,result))    (io:format "Success: ~p~n" `(,result)))
  ((`#(error ,reason)) (io:format "Failed: ~p~n" `(,reason)))
  ((‘shutdown)         (io:format "Shutting down.~n" ‘())))

lfe> (handle #(ok 42))
Success: 42
ok
lfe> (handle #(error "timeout"))
Failed: "timeout"
ok

Four lines of code, three clauses, zero conditionals. The shape of the data is the control flow.

Getting started

From zero to a running REPL in under five minutes.

lfe> (defun hello (name)
       (io:format "Hello, ~s!~n" `(,name)))
hello

lfe> (hello "world")
Hello, world!
ok

lfe> (lists:map #’hello/1 ‘("LFE" "Erlang" "OTP"))
Hello, LFE!
Hello, Erlang!
Hello, OTP!
(ok ok ok)

Pick the path that suits you:

The language

Types, records, and pattern matching aren’t isolated features — they compose.

(defrecord person name age role)

(defun greet
  (((match-person name n role ‘admin))
   (io:format "Welcome back, ~s (admin)~n" `(,n)))
  (((match-person name n))
   (io:format "Hello, ~s~n" `(,n))))

lfe> (greet (make-person name "Ford" age 234 role ‘admin))
Welcome back, Ford (admin)
ok

Records generate constructor and accessor functions. Pattern matching destructures them directly in function heads. No casting, no null checks.

OTP

This is what makes the Erlang VM worth the trip. Processes that supervise each other, restart on failure, and scale to millions of concurrent connections.

;; The gen_server from the home page, now in action:
lfe> (my-server:start_link)
#(ok <0.42.0>)

lfe> (my-server:get-amount)
0
lfe> (my-server:deposit 100)
ok
lfe> (my-server:get-amount)
100

Behind those four calls: a supervised process, a message queue, serialized state updates, and crash recovery. OTP gives you all of it.

The Erlang heritage

Going deeper

Macros, metaprogramming, the Lisp heritage that shaped LFE, and the operational wisdom to run it in production.

;; The home page showed a variadic `mean` macro.
;; Here’s one that writes a gen_server call wrapper:
(defmacro defcall
  ((name args body)
   `(defun ,name ,args
      (gen_server:call (whereis ‘my-server) ,body))))

;; One line generates a complete API function:
(defcall get-amount () ‘amount)
(defcall deposit (n) `#(add ,n))

Macros run at compile time — the generated code is exactly what you’d write by hand, with zero runtime overhead.

The Lisp heritage

LFE derives much of its character from Robert Virding’s experiences with Franz Lisp (which itself was based in large part upon MACLISP) at Stockholm University'a physics department and then again later at the Ericsson Computer Science Lab. Due to the MACLISP influence, The Moonual (David Moon’s MACLISP reference), the Chineual, and the Common Lisp HyperSpec remain constant companions in LFE’s development.

For more details on Lisp macros, be sure to check out the following:

Next steps

Ready to build something? The Use page has the reference materials and tooling you’ll need. And the community is always happy to help.