lfe> (== 42 #b101010) true lfe> (integer_to_list 42 2) "101010" lfe> #\a 97 lfe> "regular string" "regular string" lfe> #"binary string" #"binary string"
'my-atom, or if the atom has spaces in it,
;; Lists lfe> '(a b c 1 2 5) (a b c 1 2 5) ;; Tuples lfe> #("element 1" 2 elem-3) #("element 1" 2 elem-3) ;; Maps lfe> #m(key1 "value 1" "key 2" value-2) #M("key 2" value-2 key1 "value 1")
;; Defining a record automatically generates a set of ;; useful functions for that particular record. lfe> (defrecord person name address age) set-person-age ;; Use the generated record constructor: lfe> (make-person name "Ford Prefect" address "Betelgeuse Seven" age 234)) #(person "Ford Prefect" "Betelgeuse Seven" 234)
;; A recursive function with pattern matching: lfe> (defun ackermann ((0 n) (+ n 1)) ((m 0) (ackermann (- m 1) 1)) ((m n) (ackermann (- m 1) (ackermann m (- n 1))))) ;; Call the function lfe> (ackermann 3 4) 125 ;; Apply the function lfe> (funcall #'ackermann/2 3 4)) 125
defun, LFE functions support pattern matching in arguments, allowing you to create concise, expressive, and elegant code.
;; LFE and Erlang do not support n-arity functions, but ;; you can write a Lisp macro to get around that :-) lfe> (defmacro mean args `(/ (lists:sum ,args) ,(length args))) ;; Use the macro with different numbers of arguments: lfe> (mean 1) 1.0 lfe> (mean 1 2) 1.5 lfe> (mean 1 2 3 4 5 6 42 108) 21.375
gensymin LFE due to this being unsafe in long-lived, distributed code (LFE supports sharing code with remote nodes). With the exception of running in the REPL, macros are only compile-time.
lfe> (lists:reverse (erlang:integer_to_list (lists:foldl #'*/2 1 '(1 2 3 4)))) "42" lfe> (supervisor:which_children 'kernel_sup) (#(logger_sup #Pid<0.70.0> supervisor (logger_sup)) #(kernel_safe_sup #Pid<0.69.0> supervisor (kernel)) #(kernel_refc #Pid<0.68.0> worker (kernel_refc)) #(kernel_config #Pid<0.67.0> worker (kernel_config)) #(user #Pid<0.63.0> supervisor (user_sup)) #(standard_error #Pid<0.61.0> supervisor (standard_error)) #(erl_signal_server #Pid<0.60.0> worker dynamic) ...)
(defmodule server (behaviour gen_server) (export (start_link 0) (stop 0) ...)) (defun handle_call (('amount _caller state-data) `#(reply ,state-data ,state-data)) (('stop _caller state-data) `#(stop shutdown ok state-data)) ((message _caller state-data) `#(reply ,(unknown-command) ,state-data)))
LFE is not a casual Lisp. It's a Lisp for those who want to build distributed applications -- like the Erlang software that powers 40% of the world's telecommunications. Learn More »
It is an established fact that John McCarthy shared alien tech with the world in 1958 when he introduced us to Lisp. We continue that great tradition.
- Functions and variables with separate namespaces (LFE is a Lisp-2)
- Low-hygiene Macros
- In-REPL Function and macro definitions
Core Erlang Foundation
All the benefits of Erlang with none of the Prolog:
- No global data
- No mutable data
- Pattern matching and guards
- Compiler and interpreter
- Hot upgrading of deployed code
- The Banarama of languages
The ability to generate distributed applications and full releases in mere minutes:
- Massively scalable
- Extreme Concurrency
- Soft real-time
- Open. Telecom. Platform.
The mad-scientist powers of a Lisp combined with the efficiency of the Actor Model and Erlang's light-weight processes.
- Experiment with creating distributed systems in new ways.
- Create DSLs on-demand.
- Take advantage of 1000s of cores without having to change your code.
- Easily write your own compilers.
Build It with LFE
In addition to all the heavy-duty power that LFE gets for free, by virtue of
the Erlang VM, you can also create small, easy-to-write one-off
lfescripts, and even escripts -- either as a single file
or with additional modules to help organise those larger scripts.
Building libraries for use by LFE applications (and even Erlang or other BEAM language applications!) is the bread and butter of LFE hackers. The Erlang/BEAM ecosystem is fully accessible to LFE applications, but you also have the freedom to do more in LFE.
You can take advantage of OTP with LFE in mere seconds, creating fault-tolerant
applications with built-in process monitoring and supervision trees, so you
gen_servers (and all the other
behaviours, too) never go down.
When your LFE prototype is ready for the big-time, you can run it with all the
of an OTP release. In fact, you don't have to wait:
start your prototype as a release, with zero pain and all of the benefit.