5 Mal is a Clojure inspired Lisp interpreter.
7 Mal is implemented in 29 different languages:
19 * Javascript ([Online Demo](http://kanaka.github.io/mal))
24 * [miniMAL](https://github.com/kanaka/miniMAL)
40 Mal is a learning tool. See the [make-a-lisp process
41 guide](process/guide.md). Each implementation of mal is separated into
42 11 incremental, self-contained (and testable) steps that demonstrate
43 core concepts of Lisp. The last step is capable of self-hosting
44 (running the mal implementation of mal).
46 The mal (make a lisp) steps are:
48 * [step0_repl](process/guide.md#step0)
49 * [step1_read_print](process/guide.md#step1)
50 * [step2_eval](process/guide.md#step2)
51 * [step3_env](process/guide.md#step3)
52 * [step4_if_fn_do](process/guide.md#step4)
53 * [step5_tco](process/guide.md#step5)
54 * [step6_file](process/guide.md#step6)
55 * [step7_quote](process/guide.md#step7)
56 * [step8_macros](process/guide.md#step8)
57 * [step9_try](process/guide.md#step9)
58 * [stepA_mal](process/guide.md#stepA)
61 Mal was presented publicly for the first time in a lightning talk at
62 Clojure West 2014 (unfortunately there is no video). See
63 mal/clojurewest2014.mal for the presentation that was given at the
64 conference (yes the presentation is a mal program).
66 If you are interesting in creating a mal implementation (or just
67 interested in using mal for something), please drop by the #mal
68 channel on freenode. In addition to the [make-a-lisp process
69 guide](process/guide.md) there is also a [mal/make-a-lisp
70 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
72 ## Building/running implementations
83 The C implementation of mal requires the following libraries (lib and
84 header packages): glib, libffi6 and either the libedit or GNU readline library.
94 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
95 a readline compatible library to build. See the `cpp/README.md` for
109 The C# implementation of mal has been tested on Linux using the Mono
110 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
111 required to build and run the C# implementation.
124 lein with-profile +stepX trampoline run
130 sudo npm install -g coffee-script
144 You Go implementation of mal requires that go is installed on on the
145 path. The implementation has been tested with Go 1.3.1.
156 Install the Haskell compiler (ghc/ghci), the Haskell platform and
157 either the editline package (BSD) or the readline package (GPL). On
158 Ubuntu these packages are: ghc, haskell-platform,
159 libghc-readline-dev/libghc-editline-dev
170 The Java implementation of mal requires maven2 to build.
175 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
177 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
190 Running the Lua implementation of mal requires lua 5.1 or later,
191 luarocks and the lua-rex-pcre library installed.
195 make # to build and link linenoise.so
201 Running the mal implementation of mal involves running stepA of one of
202 the other implementations and passing the mal step to run as a command
207 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
220 Running the Nim implementation of mal requires Nim's current devel branch
221 (0.10.3) or later, and the nre library installed.
241 The MATLAB implementation of mal has been tested with MATLAB version
242 R2014a on Linux. Note that MATLAB is a commercial product. It should
243 be fairly simple to support GNU Octave once it support classdef object
249 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
250 # OR with command line arguments
251 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
256 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
257 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
258 implementation of mal you need to download/install the miniMAL
259 interpreter (which requires Node.js).
262 # Download miniMAL and dependencies
264 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
265 # Now run mal implementation in miniMAL
271 For readline line editing support, install Term::ReadLine::Perl or
272 Term::ReadLine::Gnu from CPAN.
282 The PHP implementation of mal requires the php command line interface
290 ### Postscript Level 2/3
292 The Postscript implementation of mal requires ghostscript to run. It
293 has been tested with ghostscript 9.10.
297 gs -q -dNODISPLAY -I./ stepX_YYY.ps
309 The R implementation of mal requires R (r-base-core) to run.
313 make libs # to download and build rdyncall
319 The Racket implementation of mal requires the Racket
320 compiler/interpreter to run.
334 ### Rust (1.0.0 nightly)
336 The rust implementation of mal requires the rust compiler and build
337 tool (cargo) to build.
341 cargo run --release --bin stepX_YYY
346 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
350 sbt 'run-main stepX_YYY'
353 scala -classpath target/scala*/classes stepX_YYY
358 The Swift implemenation of mal requires the Swift compiler (XCode) to
367 ### Visual Basic.NET ###
369 The VB.NET implementation of mal has been tested on Linux using the Mono
370 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
371 required to build and run the VB.NET implementation.
385 The are nearly 500 generic functional tests (for all implementations)
386 in the `tests/` directory. Each step has a corresponding test file
387 containing tests specific to that step. The `runtest.py` test harness
388 launches a Mal step implementation and then feeds the tests one at
389 a time to the implementation and compares the output/return value to
390 the expected output/return value.
392 To simplify the process of running tests, a top level Makefile is
393 provided with convenient test targets.
395 * To run all the tests across all implementations (be prepared to wait):
401 * To run all tests against a single implementation:
411 * To run tests for a single step against all implementations:
421 * To run tests for a specifc step against a single implementation:
431 ### Self-hosted functional tests
433 * To run the functional tests in self-hosted mode, you specify `mal`
434 as the test implementation and use the `MAL_IMPL` make variable
435 to change the underlying host language (default is JavaScript):
437 make MAL_IMPL=IMPL test^mal^step2
440 make test^mal^step2 # js is default
441 make MAL_IMPL=ruby test^mal^step2
442 make MAL_IMPL=python test^mal^step2
446 ### Performance tests
448 Warning: These performance tests are neither statistically valid nor
449 comprehensive; runtime performance is a not a primary goal of mal. If
450 you draw any serious conclusions from these performance tests, then
451 please contact me about some amazing oceanfront property in Kansas
452 that I'm willing to sell you for cheap.
454 * To run performance tests against a single implementation:
462 * To run performance tests against all implementations:
467 ### Generating language statistics
469 * To report line and byte stastics for a single implementation:
477 * To report line and bytes stastics for general Lisp code (env, core
486 ## Docker test environment
488 There is a Dockerfile included in the `tests/docker` directory that
489 builds a docker image based on Ubuntu Utopic that contains everything
490 needed to run tests against all the implementations (except for MATLAB
491 which is proprietary/licensed).
493 Build the the docker image using a provided script. WARNING: this will
494 likely take over an hour to build from scratch and use more 3 GB of disk:
496 ./tests/docker-build.sh
499 Launch a docker container from that image built above. This will
500 volume mount the mal directory to `/mal` and then give you a bash
501 prompt in the container. You can then run individual mal
502 implementations and tests:
504 ./tests/docker-run.sh
507 You can also specify a command to run within the container. For
508 example, to run step2 tests for every implementation (except MATLAB):
510 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
514 * JVM-based language implementations (Java, Clojure, Scala): you will
515 need to run these implementations once manually first before you can
516 run tests because runtime dependencies need to be downloaded to
517 avoid the tests timing out. These dependencies are download to
518 dot-files in the /mal directory so they will persist between runs.
519 * Compiled languages: if your host system is different enough from
520 Ubuntu Utopic then you may need to re-compile your compiled
521 languages from within the container to avoid linker version
527 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
528 License 2.0). See LICENSE.txt for more details.