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 56 languages:
24 * ES6 (ECMAScript 6 / ECMAScript 2015)
35 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
43 * [miniMAL](https://github.com/kanaka/miniMAL)
69 Mal is a learning tool. See the [make-a-lisp process
70 guide](process/guide.md). Each implementation of mal is separated into
71 11 incremental, self-contained (and testable) steps that demonstrate
72 core concepts of Lisp. The last step is capable of self-hosting
73 (running the mal implementation of mal).
75 The mal (make a lisp) steps are:
77 * [step0_repl](process/guide.md#step0)
78 * [step1_read_print](process/guide.md#step1)
79 * [step2_eval](process/guide.md#step2)
80 * [step3_env](process/guide.md#step3)
81 * [step4_if_fn_do](process/guide.md#step4)
82 * [step5_tco](process/guide.md#step5)
83 * [step6_file](process/guide.md#step6)
84 * [step7_quote](process/guide.md#step7)
85 * [step8_macros](process/guide.md#step8)
86 * [step9_try](process/guide.md#step9)
87 * [stepA_mal](process/guide.md#stepA)
90 Mal was presented publicly for the first time in a lightning talk at
91 Clojure West 2014 (unfortunately there is no video). See
92 examples/clojurewest2014.mal for the presentation that was given at the
93 conference (yes the presentation is a mal program). At Midwest.io
94 2015, Joel Martin gave a presentation on Mal titled "Achievement
95 Unlocked: A Better Path to Language Learning".
96 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
97 [Slides](http://kanaka.github.io/midwest.io.mal/).
99 If you are interesting in creating a mal implementation (or just
100 interested in using mal for something), please drop by the #mal
101 channel on freenode. In addition to the [make-a-lisp process
102 guide](process/guide.md) there is also a [mal/make-a-lisp
103 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
105 ## Building/running implementations
107 The simplest way to run any given implementation is to use docker.
108 Every implementation has a docker image pre-built with language
109 dependencies installed. You can launch the REPL using a convenience
110 target in the top level Makefile (where IMPL is the implementation
111 directory name and stepX is the step to run):
114 make DOCKERIZE=1 "repl^IMPL^stepX"
115 # OR stepA is the default step:
116 make DOCKERIZE=1 "repl^IMPL"
122 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
124 The Ada implementation was developed with GNAT 4.9 on debian. It also
125 compiles unchanged on windows if you have windows versions of git,
126 GNAT and (optionally) make. There are no external dependencies
127 (readline not implemented).
137 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
139 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
143 gawk -O -f stepX_YYY.awk
155 The C implementation of mal requires the following libraries (lib and
156 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
167 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
169 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
170 a readline compatible library to build. See the `cpp/README.md` for
184 The C# implementation of mal has been tested on Linux using the Mono
185 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
186 required to build and run the C# implementation.
197 For the most part the Clojure implementation requires Clojure 1.5,
198 however, to pass all tests, Clojure 1.8.0-RC4 is required.
202 lein with-profile +stepX trampoline run
208 sudo npm install -g coffee-script
215 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
217 The Crystal implementation of mal has been tested with Crystal 0.18.4.
221 crystal run ./stepX_YYY.cr
223 make # needed to run tests
229 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
231 The D implementation of mal was tested with GDC 4.8. It requires the GNU
242 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
244 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
245 and 24.5. While there is very basic readline editing (`<backspace>`
246 and `C-d` work, `C-c` cancels the process), it is recommended to use
251 emacs -Q --batch --load stepX_YYY.el
252 # with full readline support
253 rlwrap emacs -Q --batch --load stepX_YYY.el
258 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
260 The Elixir implementation of mal has been tested with Elixir 1.0.5.
265 # Or with readline/line editing functionality:
271 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
273 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
274 and [rebar](https://github.com/rebar/rebar) to build.
280 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
284 ### ES6 (ECMAScript 6 / ECMAScript 2015)
286 The ES6 implementation uses the [babel](https://babeljs.io) compiler
287 to generate ES5 compatible JavaScript. The generated code has been
288 tested with Node 0.12.4.
293 node build/stepX_YYY.js
299 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
301 The F# implementation of mal has been tested on Linux using the Mono
302 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
303 compiler (mcs) is also necessary to compile the readline dependency. All are
304 required to build and run the F# implementation.
314 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
316 The Factor implementation of mal has been tested with Factor 0.97
317 ([factorcode.org](http://factorcode.org)).
321 FACTOR_ROOTS=. factor -run=stepX_YYY
326 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
335 The Go implementation of mal requires that go is installed on on the
336 path. The implementation has been tested with Go 1.3.1.
347 The Groovy implementation of mal requires Groovy to run and has been
348 tested with Groovy 1.8.6.
353 groovy ./stepX_YYY.groovy
358 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
362 guile -L ./ stepX_YYY.scm
367 Install the Haskell compiler (ghc/ghci), the Haskell platform and
368 either the editline package (BSD) or the readline package (GPL). On
369 Ubuntu these packages are: ghc, haskell-platform,
370 libghc-readline-dev/libghc-editline-dev
380 The Haxe implementation of mal requires Haxe version 3.2 to compile.
381 Four different Haxe targets are supported: Neko, Python, C++, and
391 python3 ./stepX_YYY.py
402 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
404 The Io implementation of mal has been tested with Io version 20110905.
413 The Java implementation of mal requires maven2 to build.
418 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
420 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
433 The Julia implementation of mal requires Julia 0.4.
442 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
444 The Kotlin implementation of mal has been tested with Kotlin 1.0.
449 java -jar stepX_YYY.jar
454 *The Logo implementation was created by [Dov Murik](https://github.com/dubek)*
456 The Logo implementation of mal has been tested with UCBLogo 6.0.
465 Running the Lua implementation of mal requires lua 5.1 or later,
466 luarocks and the lua-rex-pcre library installed.
470 make # to build and link linenoise.so
476 Running the mal implementation of mal involves running stepA of one of
477 the other implementations and passing the mal step to run as a command
482 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
495 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
497 Running the Nim implementation of mal requires Nim 0.11.0 or later.
509 The Object Pascal implementation of mal has been built and tested on
510 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
520 The Objective C implementation of mal has been built and tested on
521 Linux using clang/LLVM 3.6. It has also been built and tested on OS
532 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
542 The MATLAB implementation of mal has been tested with MATLAB version
543 R2014a on Linux. Note that MATLAB is a commercial product. It should
544 be fairly simple to support GNU Octave once it support classdef object
550 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
551 # OR with command line arguments
552 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
557 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
558 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
559 implementation of mal you need to download/install the miniMAL
560 interpreter (which requires Node.js).
563 # Download miniMAL and dependencies
565 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
566 # Now run mal implementation in miniMAL
572 For readline line editing support, install Term::ReadLine::Perl or
573 Term::ReadLine::Gnu from CPAN.
582 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
584 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
593 The PHP implementation of mal requires the php command line interface
601 ### Postscript Level 2/3
603 The Postscript implementation of mal requires ghostscript to run. It
604 has been tested with ghostscript 9.10.
608 gs -q -dNODISPLAY -I./ stepX_YYY.ps
611 ### PL/pgSQL (Postgres SQL Procedural Language)
613 The PL/pgSQL implementation of mal requires a running Postgres server
614 (the "kanaka/mal-test-plpgsql" docker image automatically starts
615 a Postgres server). The implementation connects to the Postgres server
616 and create a database named "mal" to store tables and stored
617 procedures. The wrapper script uses the psql command to connect to the
618 server and defaults to the user "postgres" but this can be overridden
619 with the PSQL_USER environment variable. A password can be specified
620 using the PGPASSWORD environment variable. The implementation has been
621 tested with Postgres 9.4.
625 ./wrap.sh stepX_YYY.sql
627 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
630 ### PL/SQL (Oracle SQL Procedural Language)
632 The PL/pgSQL implementation of mal requires a running Oracle DB
633 server (the "kanaka/mal-test-plsql" docker image automatically
634 starts an Oracle Express server). The implementation connects to the
635 Oracle server to create types, tables and stored procedures. The
636 default SQL*Plus logon value (username/password@connect_identifier) is
637 "system/oracle" but this can be overridden with the ORACLE_LOGON
638 environment variable. The implementation has been tested with Oracle
639 Express Edition 11g Release 2. Note that any SQL*Plus connection
640 warnings (user password expiration, etc) will interfere with the
641 ability of the wrapper script to communicate with the DB.
645 ./wrap.sh stepX_YYY.sql
647 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
650 ### Python (2.X or 3.X)
659 You must have [rpython](https://rpython.readthedocs.org/) on your path
660 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
664 make # this takes a very long time
670 The R implementation of mal requires R (r-base-core) to run.
674 make libs # to download and build rdyncall
680 The Racket implementation of mal requires the Racket
681 compiler/interpreter to run.
695 ### Rust (1.0.0 nightly)
697 The rust implementation of mal requires the rust compiler and build
698 tool (cargo) to build.
702 cargo run --release --bin stepX_YYY
707 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
711 sbt 'run-main stepX_YYY'
714 scala -classpath target/scala*/classes stepX_YYY
719 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
721 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
722 7.0) to build. Older versions will not work due to changes in the
723 language and standard library.
733 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
734 has been tested with Swift 3 Preview 3.
744 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
746 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
747 editing support, install tclreadline.
751 tclsh ./stepX_YYY.tcl
756 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
758 The VHDL implementation of mal has been tested with GHDL 0.29.
763 ./run_vhdl.sh ./stepX_YYY
768 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
770 The Vimscript implementation of mal requires Vim to run. It has been tested
775 ./run_vimscript.sh ./stepX_YYY.vim
778 ### Visual Basic.NET ###
780 The VB.NET implementation of mal has been tested on Linux using the Mono
781 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
782 required to build and run the VB.NET implementation.
796 The are over 600 generic functional tests (for all implementations)
797 in the `tests/` directory. Each step has a corresponding test file
798 containing tests specific to that step. The `runtest.py` test harness
799 launches a Mal step implementation and then feeds the tests one at
800 a time to the implementation and compares the output/return value to
801 the expected output/return value.
803 To simplify the process of running tests, a top level Makefile is
804 provided with convenient test targets.
806 * To run all the tests across all implementations (be prepared to wait):
812 * To run all tests against a single implementation:
822 * To run tests for a single step against all implementations:
832 * To run tests for a specific step against a single implementation:
835 make "test^IMPL^stepX"
838 make "test^ruby^step3"
842 ### Self-hosted functional tests
844 * To run the functional tests in self-hosted mode, you specify `mal`
845 as the test implementation and use the `MAL_IMPL` make variable
846 to change the underlying host language (default is JavaScript):
848 make MAL_IMPL=IMPL "test^mal^step2"
851 make "test^mal^step2" # js is default
852 make MAL_IMPL=ruby "test^mal^step2"
853 make MAL_IMPL=python "test^mal^step2"
856 ### Starting the REPL
858 * To start the REPL of an implementation in a specific step:
861 make "repl^IMPL^stepX"
864 make "repl^ruby^step3"
868 * If you omit the step, then `stepA` is used:
878 * To start the REPL of the self-hosted implementation, specify `mal` as the
879 REPL implementation and use the `MAL_IMPL` make variable to change the
880 underlying host language (default is JavaScript):
882 make MAL_IMPL=IMPL "repl^mal^stepX"
885 make "repl^mal^step2" # js is default
886 make MAL_IMPL=ruby "repl^mal^step2"
887 make MAL_IMPL=python "repl^mal"
890 ### Performance tests
892 Warning: These performance tests are neither statistically valid nor
893 comprehensive; runtime performance is a not a primary goal of mal. If
894 you draw any serious conclusions from these performance tests, then
895 please contact me about some amazing oceanfront property in Kansas
896 that I'm willing to sell you for cheap.
898 * To run performance tests against a single implementation:
906 * To run performance tests against all implementations:
911 ### Generating language statistics
913 * To report line and byte statistics for a single implementation:
921 * To report line and bytes statistics for general Lisp code (env, core
924 make "stats-lisp^IMPL"
930 ## Dockerized testing
932 Every implementation directory contains a Dockerfile to create
933 a docker image containing all the dependencies for that
934 implementation. In addition, the top-level Makefile contains support
935 for running the tests target (and perf, stats, repl, etc) within
936 a docker container for that implementation by passing *"DOCKERIZE=1"*
937 on the make command line. For example:
940 make DOCKERIZE=1 "test^js^step3"
943 Existing implementations already have docker images built and pushed
944 to the docker registry. However, if
945 you wish to build or rebuild a docker image locally, the toplevel
946 Makefile provides a rule for building docker images:
949 make "docker-build^IMPL"
954 * Docker images are named *"kanaka/mal-test-IMPL"*
955 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
956 you will probably need to run these implementations once manually
957 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
958 runtime dependencies need to be downloaded to avoid the tests timing
959 out. These dependencies are download to dot-files in the /mal
960 directory so they will persist between runs.
965 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
966 License 2.0). See LICENSE.txt for more details.