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 73 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)
86 Mal is a learning tool. See the [make-a-lisp process
87 guide](process/guide.md). Each implementation of mal is separated into
88 11 incremental, self-contained (and testable) steps that demonstrate
89 core concepts of Lisp. The last step is capable of self-hosting
90 (running the mal implementation of mal).
92 The mal (make a lisp) steps are:
94 * [step0_repl](process/guide.md#step0)
95 * [step1_read_print](process/guide.md#step1)
96 * [step2_eval](process/guide.md#step2)
97 * [step3_env](process/guide.md#step3)
98 * [step4_if_fn_do](process/guide.md#step4)
99 * [step5_tco](process/guide.md#step5)
100 * [step6_file](process/guide.md#step6)
101 * [step7_quote](process/guide.md#step7)
102 * [step8_macros](process/guide.md#step8)
103 * [step9_try](process/guide.md#step9)
104 * [stepA_mal](process/guide.md#stepA)
107 Mal was presented publicly for the first time in a lightning talk at
108 Clojure West 2014 (unfortunately there is no video). See
109 examples/clojurewest2014.mal for the presentation that was given at the
110 conference (yes the presentation is a mal program). At Midwest.io
111 2015, Joel Martin gave a presentation on Mal titled "Achievement
112 Unlocked: A Better Path to Language Learning".
113 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
114 [Slides](http://kanaka.github.io/midwest.io.mal/). More recently
115 Joel gave a presentation on "Make Your Own Lisp Interpreter in
116 10 Incremental Steps" at LambdaConf 2016: [Part
117 1](https://www.youtube.com/watch?v=jVhupfthTEk), [Part
118 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
119 [Slides](http://kanaka.github.io/lambdaconf/).
121 If you are interesting in creating a mal implementation (or just
122 interested in using mal for something), please drop by the #mal
123 channel on freenode. In addition to the [make-a-lisp process
124 guide](process/guide.md) there is also a [mal/make-a-lisp
125 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
127 ## Building/running implementations
129 The simplest way to run any given implementation is to use docker.
130 Every implementation has a docker image pre-built with language
131 dependencies installed. You can launch the REPL using a convenience
132 target in the top level Makefile (where IMPL is the implementation
133 directory name and stepX is the step to run):
136 make DOCKERIZE=1 "repl^IMPL^stepX"
137 # OR stepA is the default step:
138 make DOCKERIZE=1 "repl^IMPL"
144 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
146 The Ada implementation was developed with GNAT 4.9 on debian. It also
147 compiles unchanged on windows if you have windows versions of git,
148 GNAT and (optionally) make. There are no external dependencies
149 (readline not implemented).
159 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
161 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
165 gawk -O -f stepX_YYY.awk
175 ### BASIC (C64 and QBasic)
177 The BASIC implementation uses a preprocessor that can generate BASIC
178 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
179 C64 mode has been tested with
180 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
181 currently required to fix issues with line input) and the QBasic mode
182 has been tested with [qb64](http://www.qb64.net/).
184 Generate C64 code and run it using cbmbasic:
192 Generate QBasic code and load it into qb64:
196 make MODE=qbasic stepX_YYY.bas
200 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
201 inspiration for this implementation.
206 The C implementation of mal requires the following libraries (lib and
207 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
218 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
220 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
221 a readline compatible library to build. See the `cpp/README.md` for
235 The C# implementation of mal has been tested on Linux using the Mono
236 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
237 required to build and run the C# implementation.
247 *The ChucK implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
249 The ChucK implementation has been tested with ChucK 1.3.5.2.
258 *The Common Lisp implementation was created by [Iqbal Ansari](https://github.com/iqbalansari)*
260 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
261 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
262 the [README](common-lisp/README.org) for more details. Provided you have the
263 dependencies mentioned installed, do the following to run the implementation
273 For the most part the Clojure implementation requires Clojure 1.5,
274 however, to pass all tests, Clojure 1.8.0-RC4 is required.
278 lein with-profile +stepX trampoline run
284 sudo npm install -g coffee-script
291 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
293 The Crystal implementation of mal has been tested with Crystal 0.18.4.
297 crystal run ./stepX_YYY.cr
299 make # needed to run tests
305 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
307 The D implementation of mal was tested with GDC 4.8. It requires the GNU
318 *The Dart implementation was created by [Harry Terkelsen](https://github.com/hterkelsen)*
320 The Dart implementation has been tested with Dart 1.20.
329 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
331 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
332 and 24.5. While there is very basic readline editing (`<backspace>`
333 and `C-d` work, `C-c` cancels the process), it is recommended to use
338 emacs -Q --batch --load stepX_YYY.el
339 # with full readline support
340 rlwrap emacs -Q --batch --load stepX_YYY.el
345 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
347 The Elixir implementation of mal has been tested with Elixir 1.0.5.
352 # Or with readline/line editing functionality:
358 *The Elm implementation was created by [Jos van Bakel](https://github.com/c0deaddict)*
360 The Elm implementation of mal has been tested with Elm 0.18.0
370 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
372 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
373 and [rebar](https://github.com/rebar/rebar) to build.
379 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
383 ### ES6 (ECMAScript 6 / ECMAScript 2015)
385 The ES6 implementation uses the [babel](https://babeljs.io) compiler
386 to generate ES5 compatible JavaScript. The generated code has been
387 tested with Node 0.12.4.
392 node build/stepX_YYY.js
398 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
400 The F# implementation of mal has been tested on Linux using the Mono
401 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
402 compiler (mcs) is also necessary to compile the readline dependency. All are
403 required to build and run the F# implementation.
413 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
415 The Factor implementation of mal has been tested with Factor 0.97
416 ([factorcode.org](http://factorcode.org)).
420 FACTOR_ROOTS=. factor -run=stepX_YYY
425 *The Fantom implementation was created by [Dov Murik](https://github.com/dubek)*
427 The Fantom implementation of mal has been tested with Fantom 1.0.70.
431 make lib/fan/stepX_YYY.pod
437 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
446 The Go implementation of mal requires that go is installed on on the
447 path. The implementation has been tested with Go 1.3.1.
458 The Groovy implementation of mal requires Groovy to run and has been
459 tested with Groovy 1.8.6.
464 groovy ./stepX_YYY.groovy
469 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
473 guile -L ./ stepX_YYY.scm
478 *The Smalltalk implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
480 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
489 The Haskell implementation requires the ghc compiler version 7.10.1 or
490 later and also the Haskell parsec and readline (or editline) packages.
498 ### Haxe (Neko, Python, C++ and JavaScript)
500 The Haxe implementation of mal requires Haxe version 3.2 to compile.
501 Four different Haxe targets are supported: Neko, Python, C++, and
511 python3 ./stepX_YYY.py
522 The Hy implementation of mal has been tested with Hy 0.13.0.
531 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
533 The Io implementation of mal has been tested with Io version 20110905.
542 The Java implementation of mal requires maven2 to build.
547 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
549 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
562 The Julia implementation of mal requires Julia 0.4.
571 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
573 The Kotlin implementation of mal has been tested with Kotlin 1.0.
578 java -jar stepX_YYY.jar
583 *The LiveScript implementation was created by [Jos van Bakel](https://github.com/c0deaddict)*
585 The LiveScript implementation of mal has been tested with LiveScript 1.5.
590 node_modules/.bin/lsc stepX_YYY.ls
595 *The Logo implementation was created by [Dov Murik](https://github.com/dubek)*
597 The Logo implementation of mal has been tested with UCBLogo 6.0.
606 Running the Lua implementation of mal requires lua 5.1 or later,
607 luarocks and the lua-rex-pcre library installed.
611 make # to build and link linenoise.so
617 Running the mal implementation of mal involves running stepA of one of
618 the other implementations and passing the mal step to run as a command
623 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
636 *The NASM implementation was created by [Ben Dudson](https://github.com/bendudson)*
638 The NASM implementation of mal is written for x86-64 Linux, and has been tested
639 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
649 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
651 The Nim implementation of mal has been tested with Nim 0.17.0.
663 The Object Pascal implementation of mal has been built and tested on
664 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
674 The Objective C implementation of mal has been built and tested on
675 Linux using clang/LLVM 3.6. It has also been built and tested on OS
686 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
694 ### MatLab (GNU Octave and MATLAB)
696 The MatLab implementation has been tested with GNU Octave 4.2.1.
697 It has also been tested with MATLAB version R2014a on Linux. Note that
698 MATLAB is a commercial product.
703 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
704 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
705 # OR with command line arguments
706 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
707 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
712 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
713 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
714 implementation of mal you need to download/install the miniMAL
715 interpreter (which requires Node.js).
718 # Download miniMAL and dependencies
720 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
721 # Now run mal implementation in miniMAL
727 For readline line editing support, install Term::ReadLine::Perl or
728 Term::ReadLine::Gnu from CPAN.
737 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
739 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
748 The PHP implementation of mal requires the php command line interface
758 *The Picolisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
760 The Picolisp implementation requires libreadline and Picolisp 3.1.11
768 ### PL/pgSQL (Postgres SQL Procedural Language)
770 The PL/pgSQL implementation of mal requires a running Postgres server
771 (the "kanaka/mal-test-plpgsql" docker image automatically starts
772 a Postgres server). The implementation connects to the Postgres server
773 and create a database named "mal" to store tables and stored
774 procedures. The wrapper script uses the psql command to connect to the
775 server and defaults to the user "postgres" but this can be overridden
776 with the PSQL_USER environment variable. A password can be specified
777 using the PGPASSWORD environment variable. The implementation has been
778 tested with Postgres 9.4.
782 ./wrap.sh stepX_YYY.sql
784 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
787 ### PL/SQL (Oracle SQL Procedural Language)
789 The PL/pgSQL implementation of mal requires a running Oracle DB
790 server (the "kanaka/mal-test-plsql" docker image automatically
791 starts an Oracle Express server). The implementation connects to the
792 Oracle server to create types, tables and stored procedures. The
793 default SQL*Plus logon value (username/password@connect_identifier) is
794 "system/oracle" but this can be overridden with the ORACLE_LOGON
795 environment variable. The implementation has been tested with Oracle
796 Express Edition 11g Release 2. Note that any SQL*Plus connection
797 warnings (user password expiration, etc) will interfere with the
798 ability of the wrapper script to communicate with the DB.
802 ./wrap.sh stepX_YYY.sql
804 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
807 ### Postscript Level 2/3
809 The Postscript implementation of mal requires ghostscript to run. It
810 has been tested with ghostscript 9.10.
814 gs -q -dNODISPLAY -I./ stepX_YYY.ps
819 The PowerShell implementation of mal requires the PowerShell script
820 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
824 powershell ./stepX_YYY.ps1
827 ### Python (2.X and 3.X)
836 You must have [rpython](https://rpython.readthedocs.org/) on your path
837 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
841 make # this takes a very long time
847 The R implementation of mal requires R (r-base-core) to run.
851 make libs # to download and build rdyncall
857 The Racket implementation of mal requires the Racket
858 compiler/interpreter to run.
867 *The Rexx implementation was created by [Dov Murik](https://github.com/dubek)*
869 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
874 rexx -a ./stepX_YYY.rexxpp
884 ### Rust (1.0.0 nightly)
886 The rust implementation of mal requires the rust compiler and build
887 tool (cargo) to build.
891 cargo run --release --bin stepX_YYY
896 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
900 sbt 'run-main stepX_YYY'
903 scala -classpath target/scala*/classes stepX_YYY
906 ### Scheme (R7RS) ###
908 *The Scheme implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
910 The Scheme implementation of mal has been tested with Chibi-Scheme
911 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
912 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
913 be able to get it running on other conforming R7RS implementations
914 after figuring out how libraries are loaded and adjusting the
915 `Makefile` and `run` script accordingly.
921 scheme_MODE=chibi ./run
924 scheme_MODE=kawa ./run
926 scheme_MODE=gauche ./run
929 scheme_MODE=chicken ./run
931 scheme_MODE=sagittarius ./run
934 scheme_MODE=cyclone ./run
936 scheme_MODE=foment ./run
941 *The Skew implementation was created by [Dov Murik](https://github.com/dubek)*
943 The Skew implementation of mal has been tested with Skew 0.7.42.
954 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
956 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
957 7.0) to build. Older versions will not work due to changes in the
958 language and standard library.
968 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
969 has been tested with Swift 3 Preview 3.
979 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
981 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
982 editing support, install tclreadline.
986 tclsh ./stepX_YYY.tcl
991 *The TypeScript implementation was created by [vvakame](https://github.com/vvakame)*
993 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
994 It has been tested with Node.js v6.
1004 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
1006 The VHDL implementation of mal has been tested with GHDL 0.29.
1011 ./run_vhdl.sh ./stepX_YYY
1016 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
1018 The Vimscript implementation of mal requires Vim 8.0 to run.
1022 ./run_vimscript.sh ./stepX_YYY.vim
1025 ### Visual Basic.NET ###
1027 The VB.NET implementation of mal has been tested on Linux using the Mono
1028 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1029 required to build and run the VB.NET implementation.
1034 mono ./stepX_YYY.exe
1039 *The Yorick implementation was created by [Dov Murik](https://github.com/dubek)*
1041 The Yorick implementation of mal was tested on Yorick 2.2.04.
1045 yorick -batch ./stepX_YYY.i
1052 ### Functional tests
1054 The are over 600 generic functional tests (for all implementations)
1055 in the `tests/` directory. Each step has a corresponding test file
1056 containing tests specific to that step. The `runtest.py` test harness
1057 launches a Mal step implementation and then feeds the tests one at
1058 a time to the implementation and compares the output/return value to
1059 the expected output/return value.
1061 To simplify the process of running tests, a top level Makefile is
1062 provided with convenient test targets.
1064 * To run all the tests across all implementations (be prepared to wait):
1070 * To run all tests against a single implementation:
1080 * To run tests for a single step against all implementations:
1090 * To run tests for a specific step against a single implementation:
1093 make "test^IMPL^stepX"
1096 make "test^ruby^step3"
1097 make "test^ps^step4"
1100 ### Self-hosted functional tests
1102 * To run the functional tests in self-hosted mode, you specify `mal`
1103 as the test implementation and use the `MAL_IMPL` make variable
1104 to change the underlying host language (default is JavaScript):
1106 make MAL_IMPL=IMPL "test^mal^step2"
1109 make "test^mal^step2" # js is default
1110 make MAL_IMPL=ruby "test^mal^step2"
1111 make MAL_IMPL=python "test^mal^step2"
1114 ### Starting the REPL
1116 * To start the REPL of an implementation in a specific step:
1119 make "repl^IMPL^stepX"
1122 make "repl^ruby^step3"
1123 make "repl^ps^step4"
1126 * If you omit the step, then `stepA` is used:
1136 * To start the REPL of the self-hosted implementation, specify `mal` as the
1137 REPL implementation and use the `MAL_IMPL` make variable to change the
1138 underlying host language (default is JavaScript):
1140 make MAL_IMPL=IMPL "repl^mal^stepX"
1143 make "repl^mal^step2" # js is default
1144 make MAL_IMPL=ruby "repl^mal^step2"
1145 make MAL_IMPL=python "repl^mal"
1148 ### Performance tests
1150 Warning: These performance tests are neither statistically valid nor
1151 comprehensive; runtime performance is a not a primary goal of mal. If
1152 you draw any serious conclusions from these performance tests, then
1153 please contact me about some amazing oceanfront property in Kansas
1154 that I'm willing to sell you for cheap.
1156 * To run performance tests against a single implementation:
1164 * To run performance tests against all implementations:
1169 ### Generating language statistics
1171 * To report line and byte statistics for a single implementation:
1179 * To report line and bytes statistics for general Lisp code (env, core
1182 make "stats-lisp^IMPL"
1185 make "stats-lisp^js"
1188 ## Dockerized testing
1190 Every implementation directory contains a Dockerfile to create
1191 a docker image containing all the dependencies for that
1192 implementation. In addition, the top-level Makefile contains support
1193 for running the tests target (and perf, stats, repl, etc) within
1194 a docker container for that implementation by passing *"DOCKERIZE=1"*
1195 on the make command line. For example:
1198 make DOCKERIZE=1 "test^js^step3"
1201 Existing implementations already have docker images built and pushed
1202 to the docker registry. However, if
1203 you wish to build or rebuild a docker image locally, the toplevel
1204 Makefile provides a rule for building docker images:
1207 make "docker-build^IMPL"
1212 * Docker images are named *"kanaka/mal-test-IMPL"*
1213 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1214 you will probably need to run these implementations once manually
1215 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
1216 runtime dependencies need to be downloaded to avoid the tests timing
1217 out. These dependencies are download to dot-files in the /mal
1218 directory so they will persist between runs.
1220 ## Projects using mal
1222 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
1223 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
1227 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1228 License 2.0). See LICENSE.txt for more details.