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 74 languages:
14 * BASIC (C64 and QBasic)
20 * Clojure (Clojure and ClojureScript)
29 * ES6 (ECMAScript 6 / ECMAScript 2015)
39 * Haxe (Neko, Python, C++ and JavaScript)
43 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
51 * Matlab (GNU Octave and MATLAB)
52 * [miniMAL](https://github.com/kanaka/miniMAL)
66 * Python (2.X and 3.X)
87 Mal is a learning tool. See the [make-a-lisp process
88 guide](process/guide.md). Each implementation of mal is separated into
89 11 incremental, self-contained (and testable) steps that demonstrate
90 core concepts of Lisp. The last step is capable of self-hosting
91 (running the mal implementation of mal).
93 The mal (make a lisp) steps are:
95 * [step0_repl](process/guide.md#step0)
96 * [step1_read_print](process/guide.md#step1)
97 * [step2_eval](process/guide.md#step2)
98 * [step3_env](process/guide.md#step3)
99 * [step4_if_fn_do](process/guide.md#step4)
100 * [step5_tco](process/guide.md#step5)
101 * [step6_file](process/guide.md#step6)
102 * [step7_quote](process/guide.md#step7)
103 * [step8_macros](process/guide.md#step8)
104 * [step9_try](process/guide.md#step9)
105 * [stepA_mal](process/guide.md#stepA)
108 Mal was presented publicly for the first time in a lightning talk at
109 Clojure West 2014 (unfortunately there is no video). See
110 examples/clojurewest2014.mal for the presentation that was given at the
111 conference (yes the presentation is a mal program). At Midwest.io
112 2015, Joel Martin gave a presentation on Mal titled "Achievement
113 Unlocked: A Better Path to Language Learning".
114 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
115 [Slides](http://kanaka.github.io/midwest.io.mal/). More recently
116 Joel gave a presentation on "Make Your Own Lisp Interpreter in
117 10 Incremental Steps" at LambdaConf 2016: [Part
118 1](https://www.youtube.com/watch?v=jVhupfthTEk), [Part
119 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
120 [Slides](http://kanaka.github.io/lambdaconf/).
122 If you are interesting in creating a mal implementation (or just
123 interested in using mal for something), please drop by the #mal
124 channel on freenode. In addition to the [make-a-lisp process
125 guide](process/guide.md) there is also a [mal/make-a-lisp
126 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
128 ## Building/running implementations
130 The simplest way to run any given implementation is to use docker.
131 Every implementation has a docker image pre-built with language
132 dependencies installed. You can launch the REPL using a convenience
133 target in the top level Makefile (where IMPL is the implementation
134 directory name and stepX is the step to run):
137 make DOCKERIZE=1 "repl^IMPL^stepX"
138 # OR stepA is the default step:
139 make DOCKERIZE=1 "repl^IMPL"
145 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
147 The Ada implementation was developed with GNAT 4.9 on debian. It also
148 compiles unchanged on windows if you have windows versions of git,
149 GNAT and (optionally) make. There are no external dependencies
150 (readline not implemented).
160 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
162 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
166 gawk -O -f stepX_YYY.awk
176 ### BASIC (C64 and QBasic)
178 The BASIC implementation uses a preprocessor that can generate BASIC
179 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
180 C64 mode has been tested with
181 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
182 currently required to fix issues with line input) and the QBasic mode
183 has been tested with [qb64](http://www.qb64.net/).
185 Generate C64 code and run it using cbmbasic:
193 Generate QBasic code and load it into qb64:
197 make MODE=qbasic stepX_YYY.bas
201 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
202 inspiration for this implementation.
207 The C implementation of mal requires the following libraries (lib and
208 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
219 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
221 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
222 a readline compatible library to build. See the `cpp/README.md` for
236 The C# implementation of mal has been tested on Linux using the Mono
237 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
238 required to build and run the C# implementation.
248 *The ChucK implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
250 The ChucK implementation has been tested with ChucK 1.3.5.2.
259 *The Common Lisp implementation was created by [Iqbal Ansari](https://github.com/iqbalansari)*
261 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
262 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
263 the [README](common-lisp/README.org) for more details. Provided you have the
264 dependencies mentioned installed, do the following to run the implementation
274 For the most part the Clojure implementation requires Clojure 1.5,
275 however, to pass all tests, Clojure 1.8.0-RC4 is required.
279 lein with-profile +stepX trampoline run
285 sudo npm install -g coffee-script
292 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
294 The Crystal implementation of mal has been tested with Crystal 0.26.1.
298 crystal run ./stepX_YYY.cr
300 make # needed to run tests
306 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
308 The D implementation of mal was tested with GDC 4.8. It requires the GNU
319 *The Dart implementation was created by [Harry Terkelsen](https://github.com/hterkelsen)*
321 The Dart implementation has been tested with Dart 1.20.
330 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
332 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
333 and 24.5. While there is very basic readline editing (`<backspace>`
334 and `C-d` work, `C-c` cancels the process), it is recommended to use
339 emacs -Q --batch --load stepX_YYY.el
340 # with full readline support
341 rlwrap emacs -Q --batch --load stepX_YYY.el
346 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
348 The Elixir implementation of mal has been tested with Elixir 1.0.5.
353 # Or with readline/line editing functionality:
359 *The Elm implementation was created by [Jos van Bakel](https://github.com/c0deaddict)*
361 The Elm implementation of mal has been tested with Elm 0.18.0
371 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
373 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
374 and [rebar](https://github.com/rebar/rebar) to build.
380 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
384 ### ES6 (ECMAScript 6 / ECMAScript 2015)
386 The ES6 implementation uses the [babel](https://babeljs.io) compiler
387 to generate ES5 compatible JavaScript. The generated code has been
388 tested with Node 0.12.4.
393 node build/stepX_YYY.js
399 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
401 The F# implementation of mal has been tested on Linux using the Mono
402 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
403 compiler (mcs) is also necessary to compile the readline dependency. All are
404 required to build and run the F# implementation.
414 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
416 The Factor implementation of mal has been tested with Factor 0.97
417 ([factorcode.org](http://factorcode.org)).
421 FACTOR_ROOTS=. factor -run=stepX_YYY
426 *The Fantom implementation was created by [Dov Murik](https://github.com/dubek)*
428 The Fantom implementation of mal has been tested with Fantom 1.0.70.
432 make lib/fan/stepX_YYY.pod
438 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
447 The Go implementation of mal requires that go is installed on on the
448 path. The implementation has been tested with Go 1.3.1.
459 The Groovy implementation of mal requires Groovy to run and has been
460 tested with Groovy 1.8.6.
465 groovy ./stepX_YYY.groovy
470 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
474 guile -L ./ stepX_YYY.scm
479 *The Smalltalk implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
481 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
490 The Haskell implementation requires the ghc compiler version 7.10.1 or
491 later and also the Haskell parsec and readline (or editline) packages.
499 ### Haxe (Neko, Python, C++ and JavaScript)
501 The Haxe implementation of mal requires Haxe version 3.2 to compile.
502 Four different Haxe targets are supported: Neko, Python, C++, and
512 python3 ./stepX_YYY.py
523 The Hy implementation of mal has been tested with Hy 0.13.0.
532 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
534 The Io implementation of mal has been tested with Io version 20110905.
543 The Java implementation of mal requires maven2 to build.
548 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
550 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
563 The Julia implementation of mal requires Julia 0.4.
572 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
574 The Kotlin implementation of mal has been tested with Kotlin 1.0.
579 java -jar stepX_YYY.jar
584 *The LiveScript implementation was created by [Jos van Bakel](https://github.com/c0deaddict)*
586 The LiveScript implementation of mal has been tested with LiveScript 1.5.
591 node_modules/.bin/lsc stepX_YYY.ls
596 *The Logo implementation was created by [Dov Murik](https://github.com/dubek)*
598 The Logo implementation of mal has been tested with UCBLogo 6.0.
607 Running the Lua implementation of mal requires lua 5.1 or later,
608 luarocks and the lua-rex-pcre library installed.
612 make # to build and link linenoise.so
618 Running the mal implementation of mal involves running stepA of one of
619 the other implementations and passing the mal step to run as a command
624 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
637 *The NASM implementation was created by [Ben Dudson](https://github.com/bendudson)*
639 The NASM implementation of mal is written for x86-64 Linux, and has been tested
640 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
650 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
652 The Nim implementation of mal has been tested with Nim 0.17.0.
664 The Object Pascal implementation of mal has been built and tested on
665 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
675 The Objective C implementation of mal has been built and tested on
676 Linux using clang/LLVM 3.6. It has also been built and tested on OS
687 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
695 ### MatLab (GNU Octave and MATLAB)
697 The MatLab implementation has been tested with GNU Octave 4.2.1.
698 It has also been tested with MATLAB version R2014a on Linux. Note that
699 MATLAB is a commercial product.
704 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
705 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
706 # OR with command line arguments
707 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
708 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
713 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
714 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
715 implementation of mal you need to download/install the miniMAL
716 interpreter (which requires Node.js).
719 # Download miniMAL and dependencies
721 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
722 # Now run mal implementation in miniMAL
728 For readline line editing support, install Term::ReadLine::Perl or
729 Term::ReadLine::Gnu from CPAN.
738 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
740 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
749 The PHP implementation of mal requires the php command line interface
759 *The Picolisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
761 The Picolisp implementation requires libreadline and Picolisp 3.1.11
769 ### PL/pgSQL (Postgres SQL Procedural Language)
771 The PL/pgSQL implementation of mal requires a running Postgres server
772 (the "kanaka/mal-test-plpgsql" docker image automatically starts
773 a Postgres server). The implementation connects to the Postgres server
774 and create a database named "mal" to store tables and stored
775 procedures. The wrapper script uses the psql command to connect to the
776 server and defaults to the user "postgres" but this can be overridden
777 with the PSQL_USER environment variable. A password can be specified
778 using the PGPASSWORD environment variable. The implementation has been
779 tested with Postgres 9.4.
783 ./wrap.sh stepX_YYY.sql
785 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
788 ### PL/SQL (Oracle SQL Procedural Language)
790 The PL/pgSQL implementation of mal requires a running Oracle DB
791 server (the "kanaka/mal-test-plsql" docker image automatically
792 starts an Oracle Express server). The implementation connects to the
793 Oracle server to create types, tables and stored procedures. The
794 default SQL*Plus logon value (username/password@connect_identifier) is
795 "system/oracle" but this can be overridden with the ORACLE_LOGON
796 environment variable. The implementation has been tested with Oracle
797 Express Edition 11g Release 2. Note that any SQL*Plus connection
798 warnings (user password expiration, etc) will interfere with the
799 ability of the wrapper script to communicate with the DB.
803 ./wrap.sh stepX_YYY.sql
805 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
808 ### Postscript Level 2/3
810 The Postscript implementation of mal requires ghostscript to run. It
811 has been tested with ghostscript 9.10.
815 gs -q -dNODISPLAY -I./ stepX_YYY.ps
820 The PowerShell implementation of mal requires the PowerShell script
821 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
825 powershell ./stepX_YYY.ps1
828 ### Python (2.X and 3.X)
837 You must have [rpython](https://rpython.readthedocs.org/) on your path
838 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
842 make # this takes a very long time
848 The R implementation of mal requires R (r-base-core) to run.
852 make libs # to download and build rdyncall
858 The Racket implementation of mal requires the Racket
859 compiler/interpreter to run.
868 *The Rexx implementation was created by [Dov Murik](https://github.com/dubek)*
870 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
875 rexx -a ./stepX_YYY.rexxpp
885 ### Rust (1.0.0 nightly)
887 The rust implementation of mal requires the rust compiler and build
888 tool (cargo) to build.
892 cargo run --release --bin stepX_YYY
895 Alternative out-of-tee Rust implementations:
897 * [by Tim Morgan](https://github.com/seven1m/mal-rust).
898 * [by vi](https://github.com/vi/mal-rust-vi) - using [Pest](https://pest.rs/) grammar, not using typical Mal infrastructure (cargo-ized steps and built-in converted tests).
902 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
906 sbt 'run-main stepX_YYY'
909 scala -classpath target/scala*/classes stepX_YYY
912 ### Scheme (R7RS) ###
914 *The Scheme implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
916 The Scheme implementation of mal has been tested with Chibi-Scheme
917 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
918 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
919 be able to get it running on other conforming R7RS implementations
920 after figuring out how libraries are loaded and adjusting the
921 `Makefile` and `run` script accordingly.
927 scheme_MODE=chibi ./run
930 scheme_MODE=kawa ./run
932 scheme_MODE=gauche ./run
935 scheme_MODE=chicken ./run
937 scheme_MODE=sagittarius ./run
940 scheme_MODE=cyclone ./run
942 scheme_MODE=foment ./run
947 *The Skew implementation was created by [Dov Murik](https://github.com/dubek)*
949 The Skew implementation of mal has been tested with Skew 0.7.42.
960 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
962 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
963 7.0) to build. Older versions will not work due to changes in the
964 language and standard library.
974 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
975 has been tested with Swift 3 Preview 3.
985 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
987 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
988 editing support, install tclreadline.
992 tclsh ./stepX_YYY.tcl
997 *The TypeScript implementation was created by [vvakame](https://github.com/vvakame)*
999 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1000 It has been tested with Node.js v6.
1010 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
1012 The VHDL implementation of mal has been tested with GHDL 0.29.
1017 ./run_vhdl.sh ./stepX_YYY
1022 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
1024 The Vimscript implementation of mal requires Vim 8.0 to run.
1028 ./run_vimscript.sh ./stepX_YYY.vim
1031 ### Visual Basic.NET ###
1033 The VB.NET implementation of mal has been tested on Linux using the Mono
1034 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1035 required to build and run the VB.NET implementation.
1040 mono ./stepX_YYY.exe
1043 ### WebAssembly (wasm) ###
1045 The WebAssembly implementation has been written in
1046 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1047 runs under the [wac/wace](https://github.com/kanaka/wac) WebAssembly
1053 wace ./stepX_YYY.wasm
1058 *The Yorick implementation was created by [Dov Murik](https://github.com/dubek)*
1060 The Yorick implementation of mal was tested on Yorick 2.2.04.
1064 yorick -batch ./stepX_YYY.i
1071 ### Functional tests
1073 The are over 600 generic functional tests (for all implementations)
1074 in the `tests/` directory. Each step has a corresponding test file
1075 containing tests specific to that step. The `runtest.py` test harness
1076 launches a Mal step implementation and then feeds the tests one at
1077 a time to the implementation and compares the output/return value to
1078 the expected output/return value.
1080 To simplify the process of running tests, a top level Makefile is
1081 provided with convenient test targets.
1083 * To run all the tests across all implementations (be prepared to wait):
1089 * To run all tests against a single implementation:
1099 * To run tests for a single step against all implementations:
1109 * To run tests for a specific step against a single implementation:
1112 make "test^IMPL^stepX"
1115 make "test^ruby^step3"
1116 make "test^ps^step4"
1119 ### Self-hosted functional tests
1121 * To run the functional tests in self-hosted mode, you specify `mal`
1122 as the test implementation and use the `MAL_IMPL` make variable
1123 to change the underlying host language (default is JavaScript):
1125 make MAL_IMPL=IMPL "test^mal^step2"
1128 make "test^mal^step2" # js is default
1129 make MAL_IMPL=ruby "test^mal^step2"
1130 make MAL_IMPL=python "test^mal^step2"
1133 ### Starting the REPL
1135 * To start the REPL of an implementation in a specific step:
1138 make "repl^IMPL^stepX"
1141 make "repl^ruby^step3"
1142 make "repl^ps^step4"
1145 * If you omit the step, then `stepA` is used:
1155 * To start the REPL of the self-hosted implementation, specify `mal` as the
1156 REPL implementation and use the `MAL_IMPL` make variable to change the
1157 underlying host language (default is JavaScript):
1159 make MAL_IMPL=IMPL "repl^mal^stepX"
1162 make "repl^mal^step2" # js is default
1163 make MAL_IMPL=ruby "repl^mal^step2"
1164 make MAL_IMPL=python "repl^mal"
1167 ### Performance tests
1169 Warning: These performance tests are neither statistically valid nor
1170 comprehensive; runtime performance is a not a primary goal of mal. If
1171 you draw any serious conclusions from these performance tests, then
1172 please contact me about some amazing oceanfront property in Kansas
1173 that I'm willing to sell you for cheap.
1175 * To run performance tests against a single implementation:
1183 * To run performance tests against all implementations:
1188 ### Generating language statistics
1190 * To report line and byte statistics for a single implementation:
1198 * To report line and bytes statistics for general Lisp code (env, core
1201 make "stats-lisp^IMPL"
1204 make "stats-lisp^js"
1207 ## Dockerized testing
1209 Every implementation directory contains a Dockerfile to create
1210 a docker image containing all the dependencies for that
1211 implementation. In addition, the top-level Makefile contains support
1212 for running the tests target (and perf, stats, repl, etc) within
1213 a docker container for that implementation by passing *"DOCKERIZE=1"*
1214 on the make command line. For example:
1217 make DOCKERIZE=1 "test^js^step3"
1220 Existing implementations already have docker images built and pushed
1221 to the docker registry. However, if
1222 you wish to build or rebuild a docker image locally, the toplevel
1223 Makefile provides a rule for building docker images:
1226 make "docker-build^IMPL"
1231 * Docker images are named *"kanaka/mal-test-IMPL"*
1232 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1233 you will probably need to run these implementations once manually
1234 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
1235 runtime dependencies need to be downloaded to avoid the tests timing
1236 out. These dependencies are download to dot-files in the /mal
1237 directory so they will persist between runs.
1239 ## Projects using mal
1241 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
1242 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
1246 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1247 License 2.0). See LICENSE.txt for more details.