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.17.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 the development version of the Swift 3 from
745 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
747 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
748 editing support, install tclreadline.
752 tclsh ./stepX_YYY.tcl
757 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
759 The VHDL implementation of mal has been tested with GHDL 0.29.
764 ./run_vhdl.sh ./stepX_YYY
769 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
771 The Vimscript implementation of mal requires Vim to run. It has been tested
776 ./run_vimscript.sh ./stepX_YYY.vim
779 ### Visual Basic.NET ###
781 The VB.NET implementation of mal has been tested on Linux using the Mono
782 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
783 required to build and run the VB.NET implementation.
797 The are over 600 generic functional tests (for all implementations)
798 in the `tests/` directory. Each step has a corresponding test file
799 containing tests specific to that step. The `runtest.py` test harness
800 launches a Mal step implementation and then feeds the tests one at
801 a time to the implementation and compares the output/return value to
802 the expected output/return value.
804 To simplify the process of running tests, a top level Makefile is
805 provided with convenient test targets.
807 * To run all the tests across all implementations (be prepared to wait):
813 * To run all tests against a single implementation:
823 * To run tests for a single step against all implementations:
833 * To run tests for a specific step against a single implementation:
836 make "test^IMPL^stepX"
839 make "test^ruby^step3"
843 ### Self-hosted functional tests
845 * To run the functional tests in self-hosted mode, you specify `mal`
846 as the test implementation and use the `MAL_IMPL` make variable
847 to change the underlying host language (default is JavaScript):
849 make MAL_IMPL=IMPL "test^mal^step2"
852 make "test^mal^step2" # js is default
853 make MAL_IMPL=ruby "test^mal^step2"
854 make MAL_IMPL=python "test^mal^step2"
857 ### Starting the REPL
859 * To start the REPL of an implementation in a specific step:
862 make "repl^IMPL^stepX"
865 make "repl^ruby^step3"
869 * If you omit the step, then `stepA` is used:
879 * To start the REPL of the self-hosted implementation, specify `mal` as the
880 REPL implementation and use the `MAL_IMPL` make variable to change the
881 underlying host language (default is JavaScript):
883 make MAL_IMPL=IMPL "repl^mal^stepX"
886 make "repl^mal^step2" # js is default
887 make MAL_IMPL=ruby "repl^mal^step2"
888 make MAL_IMPL=python "repl^mal"
891 ### Performance tests
893 Warning: These performance tests are neither statistically valid nor
894 comprehensive; runtime performance is a not a primary goal of mal. If
895 you draw any serious conclusions from these performance tests, then
896 please contact me about some amazing oceanfront property in Kansas
897 that I'm willing to sell you for cheap.
899 * To run performance tests against a single implementation:
907 * To run performance tests against all implementations:
912 ### Generating language statistics
914 * To report line and byte statistics for a single implementation:
922 * To report line and bytes statistics for general Lisp code (env, core
925 make "stats-lisp^IMPL"
931 ## Dockerized testing
933 Every implementation directory contains a Dockerfile to create
934 a docker image containing all the dependencies for that
935 implementation. In addition, the top-level Makefile contains support
936 for running the tests target (and perf, stats, repl, etc) within
937 a docker container for that implementation by passing *"DOCKERIZE=1"*
938 on the make command line. For example:
941 make DOCKERIZE=1 "test^js^step3"
944 Existing implementations already have docker images built and pushed
945 to the docker registry. However, if
946 you wish to build or rebuild a docker image locally, the toplevel
947 Makefile provides a rule for building docker images:
950 make "docker-build^IMPL"
955 * Docker images are named *"kanaka/mal-test-IMPL"*
956 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
957 you will probably need to run these implementations once manually
958 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
959 runtime dependencies need to be downloaded to avoid the tests timing
960 out. These dependencies are download to dot-files in the /mal
961 directory so they will persist between runs.
966 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
967 License 2.0). See LICENSE.txt for more details.