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 55 languages:
24 * ES6 (ECMAScript 6 / ECMAScript 2015)
35 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
42 * [miniMAL](https://github.com/kanaka/miniMAL)
68 Mal is a learning tool. See the [make-a-lisp process
69 guide](process/guide.md). Each implementation of mal is separated into
70 11 incremental, self-contained (and testable) steps that demonstrate
71 core concepts of Lisp. The last step is capable of self-hosting
72 (running the mal implementation of mal).
74 The mal (make a lisp) steps are:
76 * [step0_repl](process/guide.md#step0)
77 * [step1_read_print](process/guide.md#step1)
78 * [step2_eval](process/guide.md#step2)
79 * [step3_env](process/guide.md#step3)
80 * [step4_if_fn_do](process/guide.md#step4)
81 * [step5_tco](process/guide.md#step5)
82 * [step6_file](process/guide.md#step6)
83 * [step7_quote](process/guide.md#step7)
84 * [step8_macros](process/guide.md#step8)
85 * [step9_try](process/guide.md#step9)
86 * [stepA_mal](process/guide.md#stepA)
89 Mal was presented publicly for the first time in a lightning talk at
90 Clojure West 2014 (unfortunately there is no video). See
91 examples/clojurewest2014.mal for the presentation that was given at the
92 conference (yes the presentation is a mal program). At Midwest.io
93 2015, Joel Martin gave a presentation on Mal titled "Achievement
94 Unlocked: A Better Path to Language Learning".
95 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
96 [Slides](http://kanaka.github.io/midwest.io.mal/).
98 If you are interesting in creating a mal implementation (or just
99 interested in using mal for something), please drop by the #mal
100 channel on freenode. In addition to the [make-a-lisp process
101 guide](process/guide.md) there is also a [mal/make-a-lisp
102 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
104 ## Building/running implementations
106 The simplest way to run any given implementation is to use docker.
107 Every implementation has a docker image pre-built with language
108 dependencies installed. You can launch the REPL using a convenience
109 target in the top level Makefile (where IMPL is the implementation
110 directory name and stepX is the step to run):
113 make DOCKERIZE=1 "repl^IMPL^stepX"
114 # OR stepA is the default step:
115 make DOCKERIZE=1 "repl^IMPL"
121 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
123 The Ada implementation was developed with GNAT 4.9 on debian. It also
124 compiles unchanged on windows if you have windows versions of git,
125 GNAT and (optionally) make. There are no external dependencies
126 (readline not implemented).
136 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
138 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
142 gawk -O -f stepX_YYY.awk
154 The C implementation of mal requires the following libraries (lib and
155 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
166 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
168 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
169 a readline compatible library to build. See the `cpp/README.md` for
183 The C# implementation of mal has been tested on Linux using the Mono
184 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
185 required to build and run the C# implementation.
196 For the most part the Clojure implementation requires Clojure 1.5,
197 however, to pass all tests, Clojure 1.8.0-RC4 is required.
201 lein with-profile +stepX trampoline run
207 sudo npm install -g coffee-script
214 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
216 The Crystal implementation of mal has been tested with Crystal 0.17.4.
220 crystal run ./stepX_YYY.cr
222 make # needed to run tests
228 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
230 The D implementation of mal was tested with GDC 4.8. It requires the GNU
241 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
243 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
244 and 24.5. While there is very basic readline editing (`<backspace>`
245 and `C-d` work, `C-c` cancels the process), it is recommended to use
250 emacs -Q --batch --load stepX_YYY.el
251 # with full readline support
252 rlwrap emacs -Q --batch --load stepX_YYY.el
257 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
259 The Elixir implementation of mal has been tested with Elixir 1.0.5.
264 # Or with readline/line editing functionality:
270 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
272 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
273 and [rebar](https://github.com/rebar/rebar) to build.
279 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
283 ### ES6 (ECMAScript 6 / ECMAScript 2015)
285 The ES6 implementation uses the [babel](https://babeljs.io) compiler
286 to generate ES5 compatible JavaScript. The generated code has been
287 tested with Node 0.12.4.
292 node build/stepX_YYY.js
298 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
300 The F# implementation of mal has been tested on Linux using the Mono
301 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
302 compiler (mcs) is also necessary to compile the readline dependency. All are
303 required to build and run the F# implementation.
313 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
315 The Factor implementation of mal has been tested with Factor 0.97
316 ([factorcode.org](http://factorcode.org)).
320 FACTOR_ROOTS=. factor -run=stepX_YYY
325 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
334 The Go implementation of mal requires that go is installed on on the
335 path. The implementation has been tested with Go 1.3.1.
346 The Groovy implementation of mal requires Groovy to run and has been
347 tested with Groovy 1.8.6.
352 groovy ./stepX_YYY.groovy
357 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
361 guile -L ./ stepX_YYY.scm
366 Install the Haskell compiler (ghc/ghci), the Haskell platform and
367 either the editline package (BSD) or the readline package (GPL). On
368 Ubuntu these packages are: ghc, haskell-platform,
369 libghc-readline-dev/libghc-editline-dev
379 The Haxe implementation of mal requires Haxe version 3.2 to compile.
380 Four different Haxe targets are supported: Neko, Python, C++, and
390 python3 ./stepX_YYY.py
401 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
403 The Io implementation of mal has been tested with Io version 20110905.
412 The Java implementation of mal requires maven2 to build.
417 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
419 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
432 The Julia implementation of mal requires Julia 0.4.
441 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
443 The Kotlin implementation of mal has been tested with Kotlin 1.0.
448 java -jar stepX_YYY.jar
453 Running the Lua implementation of mal requires lua 5.1 or later,
454 luarocks and the lua-rex-pcre library installed.
458 make # to build and link linenoise.so
464 Running the mal implementation of mal involves running stepA of one of
465 the other implementations and passing the mal step to run as a command
470 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
483 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
485 Running the Nim implementation of mal requires Nim 0.11.0 or later.
497 The Object Pascal implementation of mal has been built and tested on
498 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
508 The Objective C implementation of mal has been built and tested on
509 Linux using clang/LLVM 3.6. It has also been built and tested on OS
520 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
530 The MATLAB implementation of mal has been tested with MATLAB version
531 R2014a on Linux. Note that MATLAB is a commercial product. It should
532 be fairly simple to support GNU Octave once it support classdef object
538 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
539 # OR with command line arguments
540 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
545 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
546 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
547 implementation of mal you need to download/install the miniMAL
548 interpreter (which requires Node.js).
551 # Download miniMAL and dependencies
553 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
554 # Now run mal implementation in miniMAL
560 For readline line editing support, install Term::ReadLine::Perl or
561 Term::ReadLine::Gnu from CPAN.
570 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
572 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
581 The PHP implementation of mal requires the php command line interface
589 ### Postscript Level 2/3
591 The Postscript implementation of mal requires ghostscript to run. It
592 has been tested with ghostscript 9.10.
596 gs -q -dNODISPLAY -I./ stepX_YYY.ps
599 ### PL/pgSQL (Postgres SQL Procedural Language)
601 The PL/pgSQL implementation of mal requires a running Postgres server
602 (the "kanaka/mal-test-plpgsql" docker image automatically starts
603 a Postgres server). The implementation connects to the Postgres server
604 and create a database named "mal" to store tables and stored
605 procedures. The wrapper script uses the psql command to connect to the
606 server and defaults to the user "postgres" but this can be overridden
607 with the PSQL_USER environment variable. A password can be specified
608 using the PGPASSWORD environment variable. The implementation has been
609 tested with Postgres 9.4.
613 ./wrap.sh stepX_YYY.sql
615 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
618 ### PL/SQL (Oracle SQL Procedural Language)
620 The PL/pgSQL implementation of mal requires a running Oracle DB
621 server (the "kanaka/mal-test-plsql" docker image automatically
622 starts an Oracle Express server). The implementation connects to the
623 Oracle server to create types, tables and stored procedures. The
624 default SQL*Plus logon value (username/password@connect_identifier) is
625 "system/oracle" but this can be overridden with the ORACLE_LOGON
626 environment variable. The implementation has been tested with Oracle
627 Express Edition 11g Release 2. Note that any SQL*Plus connection
628 warnings (user password expiration, etc) will interfere with the
629 ability of the wrapper script to communicate with the DB.
633 ./wrap.sh stepX_YYY.sql
635 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
638 ### Python (2.X or 3.X)
647 You must have [rpython](https://rpython.readthedocs.org/) on your path
648 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
652 make # this takes a very long time
658 The R implementation of mal requires R (r-base-core) to run.
662 make libs # to download and build rdyncall
668 The Racket implementation of mal requires the Racket
669 compiler/interpreter to run.
683 ### Rust (1.0.0 nightly)
685 The rust implementation of mal requires the rust compiler and build
686 tool (cargo) to build.
690 cargo run --release --bin stepX_YYY
695 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
699 sbt 'run-main stepX_YYY'
702 scala -classpath target/scala*/classes stepX_YYY
707 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
709 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
710 7.0) to build. Older versions will not work due to changes in the
711 language and standard library.
721 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
722 has been tested with the development version of the Swift 3 from
733 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
735 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
736 editing support, install tclreadline.
740 tclsh ./stepX_YYY.tcl
745 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
747 The VHDL implementation of mal has been tested with GHDL 0.29.
752 ./run_vhdl.sh ./stepX_YYY
757 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
759 The Vimscript implementation of mal requires Vim to run. It has been tested
764 ./run_vimscript.sh ./stepX_YYY.vim
767 ### Visual Basic.NET ###
769 The VB.NET implementation of mal has been tested on Linux using the Mono
770 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
771 required to build and run the VB.NET implementation.
785 The are over 600 generic functional tests (for all implementations)
786 in the `tests/` directory. Each step has a corresponding test file
787 containing tests specific to that step. The `runtest.py` test harness
788 launches a Mal step implementation and then feeds the tests one at
789 a time to the implementation and compares the output/return value to
790 the expected output/return value.
792 To simplify the process of running tests, a top level Makefile is
793 provided with convenient test targets.
795 * To run all the tests across all implementations (be prepared to wait):
801 * To run all tests against a single implementation:
811 * To run tests for a single step against all implementations:
821 * To run tests for a specific step against a single implementation:
824 make "test^IMPL^stepX"
827 make "test^ruby^step3"
831 ### Self-hosted functional tests
833 * To run the functional tests in self-hosted mode, you specify `mal`
834 as the test implementation and use the `MAL_IMPL` make variable
835 to change the underlying host language (default is JavaScript):
837 make MAL_IMPL=IMPL "test^mal^step2"
840 make "test^mal^step2" # js is default
841 make MAL_IMPL=ruby "test^mal^step2"
842 make MAL_IMPL=python "test^mal^step2"
845 ### Starting the REPL
847 * To start the REPL of an implementation in a specific step:
850 make "repl^IMPL^stepX"
853 make "repl^ruby^step3"
857 * If you omit the step, then `stepA` is used:
867 * To start the REPL of the self-hosted implementation, specify `mal` as the
868 REPL implementation and use the `MAL_IMPL` make variable to change the
869 underlying host language (default is JavaScript):
871 make MAL_IMPL=IMPL "repl^mal^stepX"
874 make "repl^mal^step2" # js is default
875 make MAL_IMPL=ruby "repl^mal^step2"
876 make MAL_IMPL=python "repl^mal"
879 ### Performance tests
881 Warning: These performance tests are neither statistically valid nor
882 comprehensive; runtime performance is a not a primary goal of mal. If
883 you draw any serious conclusions from these performance tests, then
884 please contact me about some amazing oceanfront property in Kansas
885 that I'm willing to sell you for cheap.
887 * To run performance tests against a single implementation:
895 * To run performance tests against all implementations:
900 ### Generating language statistics
902 * To report line and byte statistics for a single implementation:
910 * To report line and bytes statistics for general Lisp code (env, core
913 make "stats-lisp^IMPL"
919 ## Dockerized testing
921 Every implementation directory contains a Dockerfile to create
922 a docker image containing all the dependencies for that
923 implementation. In addition, the top-level Makefile contains support
924 for running the tests target (and perf, stats, repl, etc) within
925 a docker container for that implementation by passing *"DOCKERIZE=1"*
926 on the make command line. For example:
929 make DOCKERIZE=1 "test^js^step3"
932 Existing implementations already have docker images built and pushed
933 to the docker registry. However, if
934 you wish to build or rebuild a docker image locally, the toplevel
935 Makefile provides a rule for building docker images:
938 make "docker-build^IMPL"
943 * Docker images are named *"kanaka/mal-test-IMPL"*
944 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
945 you will probably need to run these implementations once manually
946 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
947 runtime dependencies need to be downloaded to avoid the tests timing
948 out. These dependencies are download to dot-files in the /mal
949 directory so they will persist between runs.
954 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
955 License 2.0). See LICENSE.txt for more details.