Creating a New Project

2 The LFE REPL

Did you just say "REPL"? What's a "REPL"?

"REPL" is short for "read-eval-print loop", what other languages sometimes call the "interactive interpreter." Lisp had a REPL (and interpreter) back in the 60s, when the designers of many of today's languages were still in diapers (or hadn't yet arrived on-planet).

The REPL lets you type LFE code and execute it on the spot -- no files, instant feedback.

Wanna give it a try?

2.1 Starting the LFE REPL

If you chose the Docker adventure, then you will already be sitting in the REPL. If you built from source, you can catch up with the following:

$ ./bin/lfe
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async...

   ..-~.~_~---..
  (      \\     )    |   A Lisp-2+ on the Erlang VM
  |`-.._/_\\_.-';    |   Type (help) for usage info.
  |         g (_ \   |
  |        n    | |  |   Docs: http://docs.lfe.io/
  (       a    / /   |   Source: http://github.com/rvirding/lfe
   \     l    (_/    |
    \   r     /      |   LFE v1.0 (abort with ^G)
     `-E___.-'

>

2.2 Interactive LFE Code

Now we're all on the same page: setting in our LFE REPLs. Let's have some fun. How about some math? Let's make LFE display The Answer:

> (* 2 21)
42

Here's LFE's "Hello, World!":

> (io:format "Hello, World!~n")
Hello, World!
ok

Here's how you set a variable in the REPL ... and call the seq function in the Erlang standard library's lists module:

> (set my-list (lists:seq 1 6))
(1 2 3 4 5 6)

We just created a sequence of numbers and assigned it to the my-list variable. Let's sum that list using another function in the lists module:

> (* 2 (lists:sum my-list))
42

Wanna get functional? Here's an anonymous function, an accumulator, and a left fold (known as a "reduce" in some languages):

> (* 2 (lists:foldl (lambda (n acc) (+ n acc)) 0 my-list))
42

We can even define functions and macros in the REPL (which you can't actually do in the Erlang shell!). Let's turn the code above into an easy-to-use function:

> (defun my-sum (start stop)
    (let ((my-list (lists:seq start stop)))
      (* 2 (lists:foldl
             (lambda (n acc)
               (+ n acc))
             0 my-list))))
my-sum

And try it out!

> (my-sum 1 6)
42

We're going to skip macros for now ... ;-)

2.3 Exploring the REPL

There are many other things you can do in the LFE REPL. You may have noticed the (help) command in the LFE banner when you started it up -- this is a great place to start:

> (help)

LFE shell built-in functions

(c file)    -- compile and load code in <file>
(cd dir)    -- change working directory to <dir>
(ec file)   -- compile and load code in erlang <file>
(exit)      -- quit - an alias for (q)
(help)      -- help info
(i)         -- information about the system
(l module)  -- load or reload <module>
(ls)        -- list files in the current directory
(clear)     -- clear the the REPL output
(ls dir)    -- list files in directory <dir>
(m)         -- which modules are loaded
(m mod)     -- information about module <mod>
(pid x y z) -- convert <x>, <y> and <z> to a pid
(pwd)       -- print working directory
(q)         -- quit - shorthand for init:stop/0
(flush)     -- flushes all messages sent to the shell
(regs)      -- information about registered processes

LFE shell built-in commands

(reset-environment)             -- resets the environment to its initial state
(set pattern expr)
(set pattern (when guard) expr) -- evaluate <expr> and match the result with
                                   pattern binding
(slurp file)                    -- slurp in a LFE source <file> and makes
                                   everything available in the shell
(unslurp)                       -- revert back to the state before the last
                                   slurp
(run file)                      -- execute all the shell commands in a <file>

LFE shell built-in variables

+/++/+++      -- the tree previous expressions
*/**/***      -- the values of the previous expressions
-             -- the current expression output
$ENV          -- the current LFE environment

ok

Try a couple of these out:

> (pwd)
/home/oubiwann/lab/lfe/lfe
ok
> (ls)
.dockerignore             .git                      .gitignore                
.rebar                    .travis.yml               Dockerfile                
Emakefile                 LICENSE                   Makefile                  
README.md                 VERSION                   _build                    
bin                       c_src                     doc                       
ebin                      emacs                     examples                  
get_maps_opts.escript     include                   maps.mk                   
maps_opts.mk              priv                      rebar.config              
rebar.config.script       rebar.lock                src                       
test                      
ok

Next Stop

You can taste it, can't you? That LFE flavor coming your way? Yup, you're right. You're going to be looking at LFE modules next ...