3 [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
7 Mal is a Clojure inspired Lisp interpreter.
9 Mal is implemented in 51 languages:
24 * ES6 (ECMAScript 6 / ECMAScript 2015)
35 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
42 * [miniMAL](https://github.com/kanaka/miniMAL)
64 Mal is a learning tool. See the [make-a-lisp process
65 guide](process/guide.md). Each implementation of mal is separated into
66 11 incremental, self-contained (and testable) steps that demonstrate
67 core concepts of Lisp. The last step is capable of self-hosting
68 (running the mal implementation of mal).
70 The mal (make a lisp) steps are:
72 * [step0_repl](process/guide.md#step0)
73 * [step1_read_print](process/guide.md#step1)
74 * [step2_eval](process/guide.md#step2)
75 * [step3_env](process/guide.md#step3)
76 * [step4_if_fn_do](process/guide.md#step4)
77 * [step5_tco](process/guide.md#step5)
78 * [step6_file](process/guide.md#step6)
79 * [step7_quote](process/guide.md#step7)
80 * [step8_macros](process/guide.md#step8)
81 * [step9_try](process/guide.md#step9)
82 * [stepA_mal](process/guide.md#stepA)
85 Mal was presented publicly for the first time in a lightning talk at
86 Clojure West 2014 (unfortunately there is no video). See
87 mal/clojurewest2014.mal for the presentation that was given at the
88 conference (yes the presentation is a mal program).
90 If you are interesting in creating a mal implementation (or just
91 interested in using mal for something), please drop by the #mal
92 channel on freenode. In addition to the [make-a-lisp process
93 guide](process/guide.md) there is also a [mal/make-a-lisp
94 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
96 ## Building/running implementations
98 The simplest way to run any given implementation is to use docker.
99 Every implementation has a docker image pre-built with language
100 dependencies installed. You can launch the REPL using a convenience
101 target in the top level Makefile (where IMPL is the implementation
102 directory name and stepX is the step to run):
105 make DOCKERIZE=1 "repl^IMPL^stepX"
106 # OR stepA is the default step:
107 make DOCKERIZE=1 "repl^IMPL"
113 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
115 The Ada implementation was developed with GNAT 4.9 on debian. It also
116 compiles unchanged on windows if you have windows versions of git,
117 GNAT and (optionally) make. There are no external dependencies
118 (readline not implemented).
128 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
130 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
134 gawk -O -f stepX_YYY.awk
146 The C implementation of mal requires the following libraries (lib and
147 header packages): glib, libffi6 and either the libedit or GNU readline library.
157 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
159 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
160 a readline compatible library to build. See the `cpp/README.md` for
174 The C# implementation of mal has been tested on Linux using the Mono
175 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
176 required to build and run the C# implementation.
187 For the most part the Clojure implementation requires Clojure 1.5,
188 however, to pass all tests, Clojure 1.8.0-RC4 is required.
192 lein with-profile +stepX trampoline run
198 sudo npm install -g coffee-script
205 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
207 The Crystal implementation of mal has been tested with Crystal 0.10.0.
211 crystal run ./stepX_YYY.cr
213 make # needed to run tests
219 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
221 The D implementation of mal was tested with GDC 4.8. It requires the GNU
232 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
234 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
235 and 24.5. While there is very basic readline editing (`<backspace>`
236 and `C-d` work, `C-c` cancels the process), it is recommended to use
241 emacs -Q --batch --load stepX_YYY.el
242 # with full readline support
243 rlwrap emacs -Q --batch --load stepX_YYY.el
248 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
250 The Elixir implementation of mal has been tested with Elixir 1.0.5.
255 # Or with readline/line editing functionality:
261 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
263 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
264 and [rebar](https://github.com/rebar/rebar) to build.
270 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
274 ### ES6 (ECMAScript 6 / ECMAScript 2015)
276 The ES6 implementation uses the [babel](https://babeljs.io) compiler
277 to generate ES5 compatible JavaScript. The generated code has been
278 tested with Node 0.12.4.
283 node build/stepX_YYY.js
289 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
291 The F# implementation of mal has been tested on Linux using the Mono
292 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
293 compiler (mcs) is also necessary to compile the readline dependency. All are
294 required to build and run the F# implementation.
304 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
306 The Factor implementation of mal has been tested with Factor 0.97
307 ([factorcode.org](factorcode.org)).
311 FACTOR_ROOTS=. factor -run=stepX_YYY
316 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
325 The Go implementation of mal requires that go is installed on on the
326 path. The implementation has been tested with Go 1.3.1.
337 The Groovy implementation of mal requires Groovy to run and has been
338 tested with Groovy 1.8.6.
343 groovy ./stepX_YYY.groovy
348 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
352 guile -L ./ stepX_YYY.scm
357 Install the Haskell compiler (ghc/ghci), the Haskell platform and
358 either the editline package (BSD) or the readline package (GPL). On
359 Ubuntu these packages are: ghc, haskell-platform,
360 libghc-readline-dev/libghc-editline-dev
370 The Haxe implementation of mal requires Haxe version 3.2 to compile.
371 Four different Haxe targets are supported: Neko, Python, C++, and
381 python3 ./stepX_YYY.py
392 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
394 The Io implementation of mal has been tested with Io version 20110905.
403 The Java implementation of mal requires maven2 to build.
408 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
410 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
423 The Julia implementation of mal requires Julia 0.4.
432 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
434 The Kotlin implementation of mal has been tested with Kotlin 1.0.
439 java -jar stepX_YYY.jar
444 Running the Lua implementation of mal requires lua 5.1 or later,
445 luarocks and the lua-rex-pcre library installed.
449 make # to build and link linenoise.so
455 Running the mal implementation of mal involves running stepA of one of
456 the other implementations and passing the mal step to run as a command
461 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
474 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
476 Running the Nim implementation of mal requires Nim 0.11.0 or later.
488 The Object Pascal implementation of mal has been built and tested on
489 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
499 The Objective C implementation of mal has been built and tested on
500 Linux using clang/LLVM 3.6. It has also been built and tested on OS
511 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
521 The MATLAB implementation of mal has been tested with MATLAB version
522 R2014a on Linux. Note that MATLAB is a commercial product. It should
523 be fairly simple to support GNU Octave once it support classdef object
529 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
530 # OR with command line arguments
531 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
536 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
537 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
538 implementation of mal you need to download/install the miniMAL
539 interpreter (which requires Node.js).
542 # Download miniMAL and dependencies
544 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
545 # Now run mal implementation in miniMAL
551 For readline line editing support, install Term::ReadLine::Perl or
552 Term::ReadLine::Gnu from CPAN.
562 The PHP implementation of mal requires the php command line interface
570 ### Postscript Level 2/3
572 The Postscript implementation of mal requires ghostscript to run. It
573 has been tested with ghostscript 9.10.
577 gs -q -dNODISPLAY -I./ stepX_YYY.ps
580 ### Python (2.X or 3.X)
589 You must have [rpython](https://rpython.readthedocs.org/) on your path
590 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
594 make # this takes a very long time
600 The R implementation of mal requires R (r-base-core) to run.
604 make libs # to download and build rdyncall
610 The Racket implementation of mal requires the Racket
611 compiler/interpreter to run.
625 ### Rust (1.0.0 nightly)
627 The rust implementation of mal requires the rust compiler and build
628 tool (cargo) to build.
632 cargo run --release --bin stepX_YYY
637 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
641 sbt 'run-main stepX_YYY'
644 scala -classpath target/scala*/classes stepX_YYY
649 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
651 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
652 7.0) to build. Older versions will not work due to changes in the
653 language and standard library.
663 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
664 has been tested with the development version of the Swift 3 from
675 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
677 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
678 editing support, install tclreadline.
682 tclsh ./stepX_YYY.tcl
687 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
689 The Vimscript implementation of mal requires Vim to run. It has been tested
694 ./run_vimscript.sh ./stepX_YYY.vim
697 ### Visual Basic.NET ###
699 The VB.NET implementation of mal has been tested on Linux using the Mono
700 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
701 required to build and run the VB.NET implementation.
715 The are over 600 generic functional tests (for all implementations)
716 in the `tests/` directory. Each step has a corresponding test file
717 containing tests specific to that step. The `runtest.py` test harness
718 launches a Mal step implementation and then feeds the tests one at
719 a time to the implementation and compares the output/return value to
720 the expected output/return value.
722 To simplify the process of running tests, a top level Makefile is
723 provided with convenient test targets.
725 * To run all the tests across all implementations (be prepared to wait):
731 * To run all tests against a single implementation:
741 * To run tests for a single step against all implementations:
751 * To run tests for a specific step against a single implementation:
754 make "test^IMPL^stepX"
757 make "test^ruby^step3"
761 ### Self-hosted functional tests
763 * To run the functional tests in self-hosted mode, you specify `mal`
764 as the test implementation and use the `MAL_IMPL` make variable
765 to change the underlying host language (default is JavaScript):
767 make MAL_IMPL=IMPL "test^mal^step2"
770 make "test^mal^step2" # js is default
771 make MAL_IMPL=ruby "test^mal^step2"
772 make MAL_IMPL=python "test^mal^step2"
775 ### Starting the REPL
777 * To start the REPL of an implementation in a specific step:
780 make "repl^IMPL^stepX"
783 make "repl^ruby^step3"
787 * If you omit the step, then `stepA` is used:
797 * To start the REPL of the self-hosted implementation, specify `mal` as the
798 REPL implementation and use the `MAL_IMPL` make variable to change the
799 underlying host language (default is JavaScript):
801 make MAL_IMPL=IMPL "repl^mal^stepX"
804 make "repl^mal^step2" # js is default
805 make MAL_IMPL=ruby "repl^mal^step2"
806 make MAL_IMPL=python "repl^mal"
809 ### Performance tests
811 Warning: These performance tests are neither statistically valid nor
812 comprehensive; runtime performance is a not a primary goal of mal. If
813 you draw any serious conclusions from these performance tests, then
814 please contact me about some amazing oceanfront property in Kansas
815 that I'm willing to sell you for cheap.
817 * To run performance tests against a single implementation:
825 * To run performance tests against all implementations:
830 ### Generating language statistics
832 * To report line and byte statistics for a single implementation:
840 * To report line and bytes statistics for general Lisp code (env, core
843 make "stats-lisp^IMPL"
849 ## Dockerized testing
851 Every implementation directory contains a Dockerfile to create
852 a docker image containing all the dependencies for that
853 implementation. In addition, the top-level Makefile contains support
854 for running the tests target (and perf, stats, repl, etc) within
855 a docker container for that implementation by passing *"DOCKERIZE=1"*
856 on the make command line. For example:
859 make DOCKERIZE=1 "test^js^step3"
862 Existing implementations already have docker images built and pushed
863 to the docker registry. However, if
864 you wish to build or rebuild a docker image locally, the toplevel
865 Makefile provides a rule for building docker images:
868 make "docker-build^IMPL"
873 * Docker images are named *"kanaka/mal-test-IMPL"*
874 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
875 you will probably need to run these implementations once manually
876 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
877 runtime dependencies need to be downloaded to avoid the tests timing
878 out. These dependencies are download to dot-files in the /mal
879 directory so they will persist between runs.
884 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
885 License 2.0). See LICENSE.txt for more details.