Sample Code
Well, you've already seen some! But here is the full, if minimal, module generated by the LFE rebar3 plugin:
(defmodule my-test-lib
(export (my-fun 0)))
;;; -----------
;;; library API
;;; -----------
(defun my-fun ()
'hello-world)
You'll note that the function we define has been exported via the export
form in the module definition. The number after the function is the arity
of that function (Erlang views functions of the same name but different
arity as different functions, and LFE does the same).
In the REPL you will have access to this module and its one function. Try it out:
lfe> (my-test-lib:my-fun)
hello-world
Let's add to this module our new my-sum
function from the REPL jam session
in the previous section. In another terminal window (or text editor pane) open up the
src/my-test-lib.lfe
file and paste the my-sum
function at the bottom. Afterwards,
add (my-sum 2)
to the export
section of defmodule
at the top.
When you're done, the entire file should look like this:
(defmodule my-test-lib
(export (my-fun 0)
(my-sum 2)))
;;; -----------
;;; library API
;;; -----------
(defun my-fun ()
'hello-world)
(defun my-sum (start stop)
(let ((my-list (lists:seq start stop)))
(* 2 (lists:foldl
(lambda (n acc)
(+ n acc))
0 my-list))))
Then come back to the REPL sessions and compile the module with its new addition:
> (c "src/my-test-lib.lfe")
#(module my-test-lib)
And call the module functions:
> (my-test-lib:my-sum 1 6)
42
> (my-test-lib:my-sum 1 60)
3660
>
Here's something a little more involved you may enjoy, from the examples in the LFE source code:
(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 'my-test-lib 'print-result ())))
(! spawned-pid (tuple calling-pid msg))))
That bit of code demonstrates one of Erlang's core features in lovely Lisp syntax: message passing. When loaded into the REPL, that code can demonstrate bidirectional message passing between the LFE shell and a spawned process.
Want to give it a try? Add those two new functions to your module, and don't forget to update
the export
section, too! (note that one function has an arity
of 0
and the other and arity of 2
).
When you're done, your project module should look like this:
(defmodule my-test-lib
(export (my-fun 0)
(my-sum 2)
(print-result 0)
(send-message 2)))
;;; -----------
;;; library API
;;; -----------
(defun my-fun ()
'hello-world)
(defun my-sum (start stop)
(let ((my-list (lists:seq start stop)))
(* 2 (lists:foldl
(lambda (n acc)
(+ n acc))
0 my-list))))
(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 'my-test-lib 'print-result ())))
(! spawned-pid (tuple calling-pid msg))))