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 60 languages:
26 * ES6 (ECMAScript 6 / ECMAScript 2015)
37 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
45 * [miniMAL](https://github.com/kanaka/miniMAL)
73 Mal is a learning tool. See the [make-a-lisp process
74 guide](process/guide.md). Each implementation of mal is separated into
75 11 incremental, self-contained (and testable) steps that demonstrate
76 core concepts of Lisp. The last step is capable of self-hosting
77 (running the mal implementation of mal).
79 The mal (make a lisp) steps are:
81 * [step0_repl](process/guide.md#step0)
82 * [step1_read_print](process/guide.md#step1)
83 * [step2_eval](process/guide.md#step2)
84 * [step3_env](process/guide.md#step3)
85 * [step4_if_fn_do](process/guide.md#step4)
86 * [step5_tco](process/guide.md#step5)
87 * [step6_file](process/guide.md#step6)
88 * [step7_quote](process/guide.md#step7)
89 * [step8_macros](process/guide.md#step8)
90 * [step9_try](process/guide.md#step9)
91 * [stepA_mal](process/guide.md#stepA)
94 Mal was presented publicly for the first time in a lightning talk at
95 Clojure West 2014 (unfortunately there is no video). See
96 examples/clojurewest2014.mal for the presentation that was given at the
97 conference (yes the presentation is a mal program). At Midwest.io
98 2015, Joel Martin gave a presentation on Mal titled "Achievement
99 Unlocked: A Better Path to Language Learning".
100 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
101 [Slides](http://kanaka.github.io/midwest.io.mal/).
103 If you are interesting in creating a mal implementation (or just
104 interested in using mal for something), please drop by the #mal
105 channel on freenode. In addition to the [make-a-lisp process
106 guide](process/guide.md) there is also a [mal/make-a-lisp
107 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
109 ## Building/running implementations
111 The simplest way to run any given implementation is to use docker.
112 Every implementation has a docker image pre-built with language
113 dependencies installed. You can launch the REPL using a convenience
114 target in the top level Makefile (where IMPL is the implementation
115 directory name and stepX is the step to run):
118 make DOCKERIZE=1 "repl^IMPL^stepX"
119 # OR stepA is the default step:
120 make DOCKERIZE=1 "repl^IMPL"
126 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
128 The Ada implementation was developed with GNAT 4.9 on debian. It also
129 compiles unchanged on windows if you have windows versions of git,
130 GNAT and (optionally) make. There are no external dependencies
131 (readline not implemented).
141 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
143 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
147 gawk -O -f stepX_YYY.awk
159 The C implementation of mal requires the following libraries (lib and
160 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
171 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
173 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
174 a readline compatible library to build. See the `cpp/README.md` for
188 The C# implementation of mal has been tested on Linux using the Mono
189 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
190 required to build and run the C# implementation.
200 *The ChucK implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
202 The ChucK implementation has been tested with ChucK 1.3.5.2 on Arch
212 *The GNU CLISP implementation was created by [Iqbal Ansari](https://github.com/iqbalansari)*
214 The implementation has been tested with GNU CLISP v2.49 on Ubuntu 16.04, 14.04 and 12.04
224 For the most part the Clojure implementation requires Clojure 1.5,
225 however, to pass all tests, Clojure 1.8.0-RC4 is required.
229 lein with-profile +stepX trampoline run
235 sudo npm install -g coffee-script
242 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
244 The Crystal implementation of mal has been tested with Crystal 0.18.4.
248 crystal run ./stepX_YYY.cr
250 make # needed to run tests
256 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
258 The D implementation of mal was tested with GDC 4.8. It requires the GNU
269 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
271 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
272 and 24.5. While there is very basic readline editing (`<backspace>`
273 and `C-d` work, `C-c` cancels the process), it is recommended to use
278 emacs -Q --batch --load stepX_YYY.el
279 # with full readline support
280 rlwrap emacs -Q --batch --load stepX_YYY.el
285 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
287 The Elixir implementation of mal has been tested with Elixir 1.0.5.
292 # Or with readline/line editing functionality:
298 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
300 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
301 and [rebar](https://github.com/rebar/rebar) to build.
307 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
311 ### ES6 (ECMAScript 6 / ECMAScript 2015)
313 The ES6 implementation uses the [babel](https://babeljs.io) compiler
314 to generate ES5 compatible JavaScript. The generated code has been
315 tested with Node 0.12.4.
320 node build/stepX_YYY.js
326 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
328 The F# implementation of mal has been tested on Linux using the Mono
329 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
330 compiler (mcs) is also necessary to compile the readline dependency. All are
331 required to build and run the F# implementation.
341 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
343 The Factor implementation of mal has been tested with Factor 0.97
344 ([factorcode.org](http://factorcode.org)).
348 FACTOR_ROOTS=. factor -run=stepX_YYY
353 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
362 The Go implementation of mal requires that go is installed on on the
363 path. The implementation has been tested with Go 1.3.1.
374 The Groovy implementation of mal requires Groovy to run and has been
375 tested with Groovy 1.8.6.
380 groovy ./stepX_YYY.groovy
385 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
389 guile -L ./ stepX_YYY.scm
394 The Haskell implementation requires the ghc compiler version 7.10.1 or
395 later and also the Haskell parsec and readline (or editline) packages.
405 The Haxe implementation of mal requires Haxe version 3.2 to compile.
406 Four different Haxe targets are supported: Neko, Python, C++, and
416 python3 ./stepX_YYY.py
427 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
429 The Io implementation of mal has been tested with Io version 20110905.
438 The Java implementation of mal requires maven2 to build.
443 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
445 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
458 The Julia implementation of mal requires Julia 0.4.
467 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
469 The Kotlin implementation of mal has been tested with Kotlin 1.0.
474 java -jar stepX_YYY.jar
479 *The Logo implementation was created by [Dov Murik](https://github.com/dubek)*
481 The Logo implementation of mal has been tested with UCBLogo 6.0.
490 Running the Lua implementation of mal requires lua 5.1 or later,
491 luarocks and the lua-rex-pcre library installed.
495 make # to build and link linenoise.so
501 Running the mal implementation of mal involves running stepA of one of
502 the other implementations and passing the mal step to run as a command
507 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
520 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
522 Running the Nim implementation of mal requires Nim 0.11.0 or later.
534 The Object Pascal implementation of mal has been built and tested on
535 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
545 The Objective C implementation of mal has been built and tested on
546 Linux using clang/LLVM 3.6. It has also been built and tested on OS
557 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
567 The MATLAB implementation of mal has been tested with MATLAB version
568 R2014a on Linux. Note that MATLAB is a commercial product. It should
569 be fairly simple to support GNU Octave once it support classdef object
575 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
576 # OR with command line arguments
577 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
582 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
583 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
584 implementation of mal you need to download/install the miniMAL
585 interpreter (which requires Node.js).
588 # Download miniMAL and dependencies
590 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
591 # Now run mal implementation in miniMAL
597 For readline line editing support, install Term::ReadLine::Perl or
598 Term::ReadLine::Gnu from CPAN.
607 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
609 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
618 The PHP implementation of mal requires the php command line interface
628 *The Picolisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
630 The Picolisp implementation requires libreadline and Picolisp 3.1.11
638 ### PL/pgSQL (Postgres SQL Procedural Language)
640 The PL/pgSQL implementation of mal requires a running Postgres server
641 (the "kanaka/mal-test-plpgsql" docker image automatically starts
642 a Postgres server). The implementation connects to the Postgres server
643 and create a database named "mal" to store tables and stored
644 procedures. The wrapper script uses the psql command to connect to the
645 server and defaults to the user "postgres" but this can be overridden
646 with the PSQL_USER environment variable. A password can be specified
647 using the PGPASSWORD environment variable. The implementation has been
648 tested with Postgres 9.4.
652 ./wrap.sh stepX_YYY.sql
654 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
657 ### PL/SQL (Oracle SQL Procedural Language)
659 The PL/pgSQL implementation of mal requires a running Oracle DB
660 server (the "kanaka/mal-test-plsql" docker image automatically
661 starts an Oracle Express server). The implementation connects to the
662 Oracle server to create types, tables and stored procedures. The
663 default SQL*Plus logon value (username/password@connect_identifier) is
664 "system/oracle" but this can be overridden with the ORACLE_LOGON
665 environment variable. The implementation has been tested with Oracle
666 Express Edition 11g Release 2. Note that any SQL*Plus connection
667 warnings (user password expiration, etc) will interfere with the
668 ability of the wrapper script to communicate with the DB.
672 ./wrap.sh stepX_YYY.sql
674 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
677 ### Postscript Level 2/3
679 The Postscript implementation of mal requires ghostscript to run. It
680 has been tested with ghostscript 9.10.
684 gs -q -dNODISPLAY -I./ stepX_YYY.ps
689 The PowerShell implementation of mal requires the PowerShell script
690 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
694 powershell ./stepX_YYY.ps1
697 ### Python (2.X or 3.X)
706 You must have [rpython](https://rpython.readthedocs.org/) on your path
707 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
711 make # this takes a very long time
717 The R implementation of mal requires R (r-base-core) to run.
721 make libs # to download and build rdyncall
727 The Racket implementation of mal requires the Racket
728 compiler/interpreter to run.
742 ### Rust (1.0.0 nightly)
744 The rust implementation of mal requires the rust compiler and build
745 tool (cargo) to build.
749 cargo run --release --bin stepX_YYY
754 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
758 sbt 'run-main stepX_YYY'
761 scala -classpath target/scala*/classes stepX_YYY
766 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
768 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
769 7.0) to build. Older versions will not work due to changes in the
770 language and standard library.
780 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
781 has been tested with Swift 3 Preview 3.
791 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
793 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
794 editing support, install tclreadline.
798 tclsh ./stepX_YYY.tcl
803 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
805 The VHDL implementation of mal has been tested with GHDL 0.29.
810 ./run_vhdl.sh ./stepX_YYY
815 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
817 The Vimscript implementation of mal requires Vim to run. It has been tested
822 ./run_vimscript.sh ./stepX_YYY.vim
825 ### Visual Basic.NET ###
827 The VB.NET implementation of mal has been tested on Linux using the Mono
828 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
829 required to build and run the VB.NET implementation.
843 The are over 600 generic functional tests (for all implementations)
844 in the `tests/` directory. Each step has a corresponding test file
845 containing tests specific to that step. The `runtest.py` test harness
846 launches a Mal step implementation and then feeds the tests one at
847 a time to the implementation and compares the output/return value to
848 the expected output/return value.
850 To simplify the process of running tests, a top level Makefile is
851 provided with convenient test targets.
853 * To run all the tests across all implementations (be prepared to wait):
859 * To run all tests against a single implementation:
869 * To run tests for a single step against all implementations:
879 * To run tests for a specific step against a single implementation:
882 make "test^IMPL^stepX"
885 make "test^ruby^step3"
889 ### Self-hosted functional tests
891 * To run the functional tests in self-hosted mode, you specify `mal`
892 as the test implementation and use the `MAL_IMPL` make variable
893 to change the underlying host language (default is JavaScript):
895 make MAL_IMPL=IMPL "test^mal^step2"
898 make "test^mal^step2" # js is default
899 make MAL_IMPL=ruby "test^mal^step2"
900 make MAL_IMPL=python "test^mal^step2"
903 ### Starting the REPL
905 * To start the REPL of an implementation in a specific step:
908 make "repl^IMPL^stepX"
911 make "repl^ruby^step3"
915 * If you omit the step, then `stepA` is used:
925 * To start the REPL of the self-hosted implementation, specify `mal` as the
926 REPL implementation and use the `MAL_IMPL` make variable to change the
927 underlying host language (default is JavaScript):
929 make MAL_IMPL=IMPL "repl^mal^stepX"
932 make "repl^mal^step2" # js is default
933 make MAL_IMPL=ruby "repl^mal^step2"
934 make MAL_IMPL=python "repl^mal"
937 ### Performance tests
939 Warning: These performance tests are neither statistically valid nor
940 comprehensive; runtime performance is a not a primary goal of mal. If
941 you draw any serious conclusions from these performance tests, then
942 please contact me about some amazing oceanfront property in Kansas
943 that I'm willing to sell you for cheap.
945 * To run performance tests against a single implementation:
953 * To run performance tests against all implementations:
958 ### Generating language statistics
960 * To report line and byte statistics for a single implementation:
968 * To report line and bytes statistics for general Lisp code (env, core
971 make "stats-lisp^IMPL"
977 ## Dockerized testing
979 Every implementation directory contains a Dockerfile to create
980 a docker image containing all the dependencies for that
981 implementation. In addition, the top-level Makefile contains support
982 for running the tests target (and perf, stats, repl, etc) within
983 a docker container for that implementation by passing *"DOCKERIZE=1"*
984 on the make command line. For example:
987 make DOCKERIZE=1 "test^js^step3"
990 Existing implementations already have docker images built and pushed
991 to the docker registry. However, if
992 you wish to build or rebuild a docker image locally, the toplevel
993 Makefile provides a rule for building docker images:
996 make "docker-build^IMPL"
1001 * Docker images are named *"kanaka/mal-test-IMPL"*
1002 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1003 you will probably need to run these implementations once manually
1004 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
1005 runtime dependencies need to be downloaded to avoid the tests timing
1006 out. These dependencies are download to dot-files in the /mal
1007 directory so they will persist between runs.
1012 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1013 License 2.0). See LICENSE.txt for more details.