1 Introduction

1.7 Setting up a Development Environment

The last thing we need to do before you're off and running is to discuss a good standard process for setting up a development environment. There are several key aspects to this:

  • Intent
    • exploring LFE and LFE examples
    • creating an LFE library
    • creating an LFE service/daemon/application
    • hacking on LFE itself
  • Tools
    • kerl
    • rebar
    • testing
    • IDEs

This section takes a pragmatic approach of getting started as quickly as possible, so we will not cover these in great detail. However, we will provide useful links and additional references so that you can explore at your own leisure.

1.7.1 Starting from Scratch

In the LFE Quick Start, you saw how to get up and running, and we're going to repeat some of that here. However, we do this for the sake of completeness and having all the information in one easy-to-access reference.

1.7.2 Dependencies

kerl

First and foremost, you're going to need Erlang. In the course of your experiments with LFE, you may want to try out different versions of Erlang, so we'll start off right: using kerl. We have another section dedicated entirely to kerl, so we'll skip the details, refer tou to that page, and assume that you've followed those instructions for getting it set up.

rebar

No matter what your intent with LFE, you're going to need rebar :-) The installation instructions are given in the first few sub-sections of the section dedicated to rebar. Be sure you follow those, and you will have a working rebar installation. Though you can build LFE without rebar, creating projects will be very cumbersome unless you have it installed and are using it.

1.7.3 Getting and Building LFE

With the dependencies install, getting and building is short and sweet:

$ git clone git://github.com/rvirding/lfe.git
$ cd ./lfe
$ rebar compile

That should take nor more than 5-10 seconds to build.

1.7.4 Installing LFE

We don't actually recommend installing LFE system-wide. When using rebar, you can set LFE as a dependency and it will be automatically downloaded for your project (and for anyone who has your project as a dependency).

However, if for some reason you do want to install LFE system-wide, here's how you do it (from the working LFE directory):

$ export ERL_LIBS=/usr/local/lib/erlang/lib
$ make install

1.7.5 A Test Drive with the REPL

With LFE built, you're ready to play :-) Try this out:

$ ./bin/lfe -pa ./ebin

This will put you in the REPL, and from there you can Lisp it up:

> (* 6 7)
42
> (cons 6 7)
(6 . 7)
> (cons (list 6 7) (list 40 2))
((6 7) 40 2)
>

1.7.6 Running Some Examples

While in the REPL, you can run some examples by slurping them in:

> (slurp '"./examples/internal-state.lfe")
#(ok internal-state)
> (set account (new-account '"Alice" 100.00 0.06))
#Fun<lfe_eval.10.6046715>
> (name account)
"Alice"
> (balance account)
100.0
>

And another one:

> (slurp '"./examples/church.lfe")
#(ok church)
> (church->int1 (three))
3
>

To quit out of the REPL, hit ^g and then q<ENTER>.

1.7.7 An Example IDE: Sublime Text 2

First off: our definition of "IDE" is text editor + REPL + terminal. So there you have it.

As we are sure is obvious, you can use any text editor you want with LFE. If you're a Lisper, Emacs might be a natural choice. Vim, quite honestly, can work just as well.

For this example, though, we will be using Sublime Text 2 as the example editor. To use LFE effectively with Sublime, we recommend the following plugins:

  • Package Control

  • Bracket Highlighter

  • Lisp Indent

  • Trailing Spaces

  • LFE

  • Theme - Vim Blackboard (for those who like dark editors and a classic terminal syntax highlight look)

Instructions for installing Package Control are here.

After the restart, you're ready to go. For each package you want to install, do the following:

  1. Go to Sublime Text 2 -> Preferences -> Package Control

  2. Type "Package Control: Install Package"

  3. Wait for the text entry box to display (available packages are loading)

  4. Enter the name of the package you want to install and hit <ENTER>

After you have done that for each packge, you will need to restart. Many of the packages will then have their own entries under Sublime Text 2 -> Preferences -> Package Settings where you can copy the default settings and paste them into your own ("User") settings, modifying as you see fit.

To configure the dark theme, you'll want to visit see the project README.

The LFE plugin doesn't need any configuration. Once you restart Sublime, it should recognize your LFE files by the file extension.

For the Lispindent plugin you will need to add some configuration. Go to Sublime Text 2 -> Preferences -> Package Settings -> Lispindent and click on "Settings - User". In the new file that pops up, paste the following:

{
    "languages": {
        "LFE": {
            "detect": ".*\\.(lfe)$",
            "syntax": "LFE.tmLanguage",
            "default_indent": "function",
            "regex":
            ["(ns|fn|def[^\\s]*|bound-fn|if|if-not|case|condp|when|while|",
             "when-not|when-first|do|future|comment|doto|locking|proxy|",
             "with-open|with-precision|with-local-vars|reify|deftype|",
             "defrecord|defprotocol|extend|extend-protocol|extend-type|",
             "try|catch|finally|let|letfn|binding|loop|for|doseq|dotimes|",
             "when-let|if-let|defstruct|struct-map|assoc|defmethod|testing|",
             "deftest|use-fixtures|handler-case|handle|dotrace|deftrace|",
             "begin|case|delay|do|define|lambda|let|let\\*|letrec|",
             "let-values|let\\*-values|sequence|let-syntax|letrec-syntax|",
             "syntax-rules|syntax-case|call-with-input-file|",
             "with-input-from-file|with-input-from-port|",
             "call-with-output-file|with-output-to-file|",
             "with-output-to-port|call-with-values|dynamic-wind|catch|",
             "defvar|defclass|defconstant|defcustom|defparameter|defconst|",
             "define-condition|define-modify-macro|defsetf|defun|",
             "defgeneric|define-setf-method|define-self-expander|",
             "defmacro|defsubst|deftype|defmethod|defpackage|defstruct|",
             "dolist|dotimes|lambda|let|let\\*|prog1|prog2|unless|when)$"]
        }
    }
}

Your text editor is now ready to rock out some LFE!

1.7.8 A Quick Note on Writing Tests

We've covered getting LFE running, using the REPL, and operating your text editor in an LFE-friendly manner. The next of the essentils we need to look at is unit tests. This will be covered in much more detail in the TDD section of the Checks and Testing chapter.

For now, though, let's give you a quick test.. and some caveats. In fact, let's do the caveats first.

Ideally, LFE would use eunit, like it does with most other libraries. Unfortunately, there are some quirky edge cases in LFE's Erlang macro handling that prevent correct usage of eunit. As such, an interim solution was created. Once the macro issue in LFE is addressed for eunit (and progress is being made!), we will be able to abandon lfeunit (or make it a thin wrapper).

A quick and dirty intro to using lfeunit follows:

  1. Create a test directory in your project, if one doesn't already exist.

  2. Create a <module-name>_tests.lfe file.

  3. Ensure that your module name matches in the file:

   (defmodule <module-name>_tests ...)
  1. Update the import statement to include the unit test functions you need, e.g.:
   (import
     ...
     (from lfeunit
      (assert 1)
      (assert-not 1)
      (assert-equal 2)
      (assert-not-equal 2)
      (assert-exception 3)
      (assert-error 2)
      (assert-throw 2)
      (assert-exit 2))
      ...)
  1. Create test functions of the form <some-name>_test, with some asserts added, e.g.:
   (defun my-function_test ()
     (assert-true 42 (my-function 1 2 3)))
  1. Run make check to verify your tests. Do this for every commit.

1.7.9 Toolchain