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 52 languages:
24 * ES6 (ECMAScript 6 / ECMAScript 2015)
35 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
42 * [miniMAL](https://github.com/kanaka/miniMAL)
65 Mal is a learning tool. See the [make-a-lisp process
66 guide](process/guide.md). Each implementation of mal is separated into
67 11 incremental, self-contained (and testable) steps that demonstrate
68 core concepts of Lisp. The last step is capable of self-hosting
69 (running the mal implementation of mal).
71 The mal (make a lisp) steps are:
73 * [step0_repl](process/guide.md#step0)
74 * [step1_read_print](process/guide.md#step1)
75 * [step2_eval](process/guide.md#step2)
76 * [step3_env](process/guide.md#step3)
77 * [step4_if_fn_do](process/guide.md#step4)
78 * [step5_tco](process/guide.md#step5)
79 * [step6_file](process/guide.md#step6)
80 * [step7_quote](process/guide.md#step7)
81 * [step8_macros](process/guide.md#step8)
82 * [step9_try](process/guide.md#step9)
83 * [stepA_mal](process/guide.md#stepA)
86 Mal was presented publicly for the first time in a lightning talk at
87 Clojure West 2014 (unfortunately there is no video). See
88 examples/clojurewest2014.mal for the presentation that was given at the
89 conference (yes the presentation is a mal program). At Midwest.io
90 2015, Joel Martin gave a presentation on Mal titled "Achievement
91 Unlocked: A Better Path to Language Learning".
92 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
93 [Slides](http://kanaka.github.io/midwest.io.mal/).
95 If you are interesting in creating a mal implementation (or just
96 interested in using mal for something), please drop by the #mal
97 channel on freenode. In addition to the [make-a-lisp process
98 guide](process/guide.md) there is also a [mal/make-a-lisp
99 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
101 ## Building/running implementations
103 The simplest way to run any given implementation is to use docker.
104 Every implementation has a docker image pre-built with language
105 dependencies installed. You can launch the REPL using a convenience
106 target in the top level Makefile (where IMPL is the implementation
107 directory name and stepX is the step to run):
110 make DOCKERIZE=1 "repl^IMPL^stepX"
111 # OR stepA is the default step:
112 make DOCKERIZE=1 "repl^IMPL"
118 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
120 The Ada implementation was developed with GNAT 4.9 on debian. It also
121 compiles unchanged on windows if you have windows versions of git,
122 GNAT and (optionally) make. There are no external dependencies
123 (readline not implemented).
133 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
135 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
139 gawk -O -f stepX_YYY.awk
151 The C implementation of mal requires the following libraries (lib and
152 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
163 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
165 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
166 a readline compatible library to build. See the `cpp/README.md` for
180 The C# implementation of mal has been tested on Linux using the Mono
181 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
182 required to build and run the C# implementation.
193 For the most part the Clojure implementation requires Clojure 1.5,
194 however, to pass all tests, Clojure 1.8.0-RC4 is required.
198 lein with-profile +stepX trampoline run
204 sudo npm install -g coffee-script
211 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
213 The Crystal implementation of mal has been tested with Crystal 0.10.0.
217 crystal run ./stepX_YYY.cr
219 make # needed to run tests
225 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
227 The D implementation of mal was tested with GDC 4.8. It requires the GNU
238 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
240 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
241 and 24.5. While there is very basic readline editing (`<backspace>`
242 and `C-d` work, `C-c` cancels the process), it is recommended to use
247 emacs -Q --batch --load stepX_YYY.el
248 # with full readline support
249 rlwrap emacs -Q --batch --load stepX_YYY.el
254 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
256 The Elixir implementation of mal has been tested with Elixir 1.0.5.
261 # Or with readline/line editing functionality:
267 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
269 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
270 and [rebar](https://github.com/rebar/rebar) to build.
276 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
280 ### ES6 (ECMAScript 6 / ECMAScript 2015)
282 The ES6 implementation uses the [babel](https://babeljs.io) compiler
283 to generate ES5 compatible JavaScript. The generated code has been
284 tested with Node 0.12.4.
289 node build/stepX_YYY.js
295 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
297 The F# implementation of mal has been tested on Linux using the Mono
298 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
299 compiler (mcs) is also necessary to compile the readline dependency. All are
300 required to build and run the F# implementation.
310 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
312 The Factor implementation of mal has been tested with Factor 0.97
313 ([factorcode.org](http://factorcode.org)).
317 FACTOR_ROOTS=. factor -run=stepX_YYY
322 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
331 The Go implementation of mal requires that go is installed on on the
332 path. The implementation has been tested with Go 1.3.1.
343 The Groovy implementation of mal requires Groovy to run and has been
344 tested with Groovy 1.8.6.
349 groovy ./stepX_YYY.groovy
354 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
358 guile -L ./ stepX_YYY.scm
363 Install the Haskell compiler (ghc/ghci), the Haskell platform and
364 either the editline package (BSD) or the readline package (GPL). On
365 Ubuntu these packages are: ghc, haskell-platform,
366 libghc-readline-dev/libghc-editline-dev
376 The Haxe implementation of mal requires Haxe version 3.2 to compile.
377 Four different Haxe targets are supported: Neko, Python, C++, and
387 python3 ./stepX_YYY.py
398 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
400 The Io implementation of mal has been tested with Io version 20110905.
409 The Java implementation of mal requires maven2 to build.
414 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
416 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
429 The Julia implementation of mal requires Julia 0.4.
438 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
440 The Kotlin implementation of mal has been tested with Kotlin 1.0.
445 java -jar stepX_YYY.jar
450 Running the Lua implementation of mal requires lua 5.1 or later,
451 luarocks and the lua-rex-pcre library installed.
455 make # to build and link linenoise.so
461 Running the mal implementation of mal involves running stepA of one of
462 the other implementations and passing the mal step to run as a command
467 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
480 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
482 Running the Nim implementation of mal requires Nim 0.11.0 or later.
494 The Object Pascal implementation of mal has been built and tested on
495 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
505 The Objective C implementation of mal has been built and tested on
506 Linux using clang/LLVM 3.6. It has also been built and tested on OS
517 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
527 The MATLAB implementation of mal has been tested with MATLAB version
528 R2014a on Linux. Note that MATLAB is a commercial product. It should
529 be fairly simple to support GNU Octave once it support classdef object
535 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
536 # OR with command line arguments
537 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
542 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
543 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
544 implementation of mal you need to download/install the miniMAL
545 interpreter (which requires Node.js).
548 # Download miniMAL and dependencies
550 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
551 # Now run mal implementation in miniMAL
557 For readline line editing support, install Term::ReadLine::Perl or
558 Term::ReadLine::Gnu from CPAN.
568 The PHP implementation of mal requires the php command line interface
576 ### Postscript Level 2/3
578 The Postscript implementation of mal requires ghostscript to run. It
579 has been tested with ghostscript 9.10.
583 gs -q -dNODISPLAY -I./ stepX_YYY.ps
586 ### PL/pgSQL (Postgres SQL Procedural Language)
588 The PL/pgSQL implementation of mal requires a running Postgres
589 server (the "kanaka/mal-test-plpgsql" docker image automatically
590 starts a Postgres server). The implementation connects to the Postgres
591 server and create a database named "mal" to store tables and stored
592 procedures. It has been tested with Postgres 9.4.
596 ./wrap.sh stepX_YYY.sql
599 ### Python (2.X or 3.X)
608 You must have [rpython](https://rpython.readthedocs.org/) on your path
609 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
613 make # this takes a very long time
619 The R implementation of mal requires R (r-base-core) to run.
623 make libs # to download and build rdyncall
629 The Racket implementation of mal requires the Racket
630 compiler/interpreter to run.
644 ### Rust (1.0.0 nightly)
646 The rust implementation of mal requires the rust compiler and build
647 tool (cargo) to build.
651 cargo run --release --bin stepX_YYY
656 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
660 sbt 'run-main stepX_YYY'
663 scala -classpath target/scala*/classes stepX_YYY
668 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
670 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
671 7.0) to build. Older versions will not work due to changes in the
672 language and standard library.
682 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
683 has been tested with the development version of the Swift 3 from
694 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
696 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
697 editing support, install tclreadline.
701 tclsh ./stepX_YYY.tcl
706 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
708 The Vimscript implementation of mal requires Vim to run. It has been tested
713 ./run_vimscript.sh ./stepX_YYY.vim
716 ### Visual Basic.NET ###
718 The VB.NET implementation of mal has been tested on Linux using the Mono
719 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
720 required to build and run the VB.NET implementation.
734 The are over 600 generic functional tests (for all implementations)
735 in the `tests/` directory. Each step has a corresponding test file
736 containing tests specific to that step. The `runtest.py` test harness
737 launches a Mal step implementation and then feeds the tests one at
738 a time to the implementation and compares the output/return value to
739 the expected output/return value.
741 To simplify the process of running tests, a top level Makefile is
742 provided with convenient test targets.
744 * To run all the tests across all implementations (be prepared to wait):
750 * To run all tests against a single implementation:
760 * To run tests for a single step against all implementations:
770 * To run tests for a specific step against a single implementation:
773 make "test^IMPL^stepX"
776 make "test^ruby^step3"
780 ### Self-hosted functional tests
782 * To run the functional tests in self-hosted mode, you specify `mal`
783 as the test implementation and use the `MAL_IMPL` make variable
784 to change the underlying host language (default is JavaScript):
786 make MAL_IMPL=IMPL "test^mal^step2"
789 make "test^mal^step2" # js is default
790 make MAL_IMPL=ruby "test^mal^step2"
791 make MAL_IMPL=python "test^mal^step2"
794 ### Starting the REPL
796 * To start the REPL of an implementation in a specific step:
799 make "repl^IMPL^stepX"
802 make "repl^ruby^step3"
806 * If you omit the step, then `stepA` is used:
816 * To start the REPL of the self-hosted implementation, specify `mal` as the
817 REPL implementation and use the `MAL_IMPL` make variable to change the
818 underlying host language (default is JavaScript):
820 make MAL_IMPL=IMPL "repl^mal^stepX"
823 make "repl^mal^step2" # js is default
824 make MAL_IMPL=ruby "repl^mal^step2"
825 make MAL_IMPL=python "repl^mal"
828 ### Performance tests
830 Warning: These performance tests are neither statistically valid nor
831 comprehensive; runtime performance is a not a primary goal of mal. If
832 you draw any serious conclusions from these performance tests, then
833 please contact me about some amazing oceanfront property in Kansas
834 that I'm willing to sell you for cheap.
836 * To run performance tests against a single implementation:
844 * To run performance tests against all implementations:
849 ### Generating language statistics
851 * To report line and byte statistics for a single implementation:
859 * To report line and bytes statistics for general Lisp code (env, core
862 make "stats-lisp^IMPL"
868 ## Dockerized testing
870 Every implementation directory contains a Dockerfile to create
871 a docker image containing all the dependencies for that
872 implementation. In addition, the top-level Makefile contains support
873 for running the tests target (and perf, stats, repl, etc) within
874 a docker container for that implementation by passing *"DOCKERIZE=1"*
875 on the make command line. For example:
878 make DOCKERIZE=1 "test^js^step3"
881 Existing implementations already have docker images built and pushed
882 to the docker registry. However, if
883 you wish to build or rebuild a docker image locally, the toplevel
884 Makefile provides a rule for building docker images:
887 make "docker-build^IMPL"
892 * Docker images are named *"kanaka/mal-test-IMPL"*
893 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
894 you will probably need to run these implementations once manually
895 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
896 runtime dependencies need to be downloaded to avoid the tests timing
897 out. These dependencies are download to dot-files in the /mal
898 directory so they will persist between runs.
903 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
904 License 2.0). See LICENSE.txt for more details.