Merge branch 'wasamasa-elisp'
[jackhill/mal.git] / README.md
1 # mal - Make a Lisp
2
3 [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
4
5 ## Description
6
7 Mal is a Clojure inspired Lisp interpreter.
8
9 Mal is implemented in 47 languages:
10
11 * GNU awk
12 * Bash shell
13 * C
14 * C++
15 * C#
16 * Clojure
17 * CoffeeScript
18 * Crystal
19 * D
20 * Elixir
21 * Emacs Lisp
22 * Erlang
23 * ES6 (ECMAScript 6 / ECMAScript 2015)
24 * F#
25 * Factor
26 * Forth
27 * Go
28 * Groovy
29 * GNU Guile
30 * Haskell
31 * Haxe
32 * Java
33 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
34 * Julia
35 * Kotlin
36 * Lua
37 * GNU Make
38 * mal itself
39 * MATLAB
40 * [miniMAL](https://github.com/kanaka/miniMAL)
41 * Nim
42 * OCaml
43 * Perl
44 * PHP
45 * Postscript
46 * Python
47 * RPython
48 * R
49 * Racket
50 * Ruby
51 * Rust
52 * Scala
53 * Swift
54 * Swift 3
55 * Tcl
56 * Vimscript
57 * Visual Basic.NET
58
59
60 Mal is a learning tool. See the [make-a-lisp process
61 guide](process/guide.md). Each implementation of mal is separated into
62 11 incremental, self-contained (and testable) steps that demonstrate
63 core concepts of Lisp. The last step is capable of self-hosting
64 (running the mal implementation of mal).
65
66 The mal (make a lisp) steps are:
67
68 * [step0_repl](process/guide.md#step0)
69 * [step1_read_print](process/guide.md#step1)
70 * [step2_eval](process/guide.md#step2)
71 * [step3_env](process/guide.md#step3)
72 * [step4_if_fn_do](process/guide.md#step4)
73 * [step5_tco](process/guide.md#step5)
74 * [step6_file](process/guide.md#step6)
75 * [step7_quote](process/guide.md#step7)
76 * [step8_macros](process/guide.md#step8)
77 * [step9_try](process/guide.md#step9)
78 * [stepA_mal](process/guide.md#stepA)
79
80
81 Mal was presented publicly for the first time in a lightning talk at
82 Clojure West 2014 (unfortunately there is no video). See
83 mal/clojurewest2014.mal for the presentation that was given at the
84 conference (yes the presentation is a mal program).
85
86 If you are interesting in creating a mal implementation (or just
87 interested in using mal for something), please drop by the #mal
88 channel on freenode. In addition to the [make-a-lisp process
89 guide](process/guide.md) there is also a [mal/make-a-lisp
90 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
91
92 ## Building/running implementations
93
94 ### GNU awk
95
96 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
97
98 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
99
100 ```
101 cd gawk
102 gawk -O -f stepX_YYY.awk
103 ```
104
105 ### Bash 4
106
107 ```
108 cd bash
109 bash stepX_YYY.sh
110 ```
111
112 ### C
113
114 The C implementation of mal requires the following libraries (lib and
115 header packages): glib, libffi6 and either the libedit or GNU readline library.
116
117 ```
118 cd c
119 make
120 ./stepX_YYY
121 ```
122
123 ### C++
124
125 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
126
127 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
128 a readline compatible library to build. See the `cpp/README.md` for
129 more details:
130
131 ```
132 cd cpp
133 make
134 # OR
135 make CXX=clang++-3.5
136 ./stepX_YYY
137 ```
138
139
140 ### C# ###
141
142 The C# implementation of mal has been tested on Linux using the Mono
143 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
144 required to build and run the C# implementation.
145
146 ```
147 cd cs
148 make
149 mono ./stepX_YYY.exe
150 ```
151
152
153 ### Clojure
154
155 For the most part the Clojure implementation requires Clojure 1.5,
156 however, to pass all tests, Clojure 1.8.0-RC4 is required.
157
158 ```
159 cd clojure
160 lein with-profile +stepX trampoline run
161 ```
162
163 ### CoffeeScript
164
165 ```
166 sudo npm install -g coffee-script
167 cd coffee
168 coffee ./stepX_YYY
169 ```
170
171 ### Crystal
172
173 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
174
175 The Crystal implementation of mal has been tested with Crystal 0.10.0.
176
177 ```
178 cd crystal
179 crystal run ./stepX_YYY.cr
180 # OR
181 make # needed to run tests
182 ./stepX_YYY
183 ```
184
185 ### D
186
187 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
188
189 The D implementation of mal was tested with GDC 4.8. It requires the GNU
190 readline library.
191
192 ```
193 cd d
194 make
195 ./stepX_YYY
196 ```
197
198 ### Emacs Lisp
199
200 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
201
202 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
203 and 24.5. While there is very basic readline editing (`<backspace>`
204 and `C-d` work, `C-c` cancels the process), it is recommended to use
205 `rlwrap`.
206
207 ```
208 cd elisp
209 emacs -Q --batch --load stepX_YYY.el
210 # with full readline support
211 rlwrap emacs -Q --batch --load stepX_YYY.el
212 ```
213
214 ### Elixir
215
216 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
217
218 The Elixir implementation of mal has been tested with Elixir 1.0.5.
219
220 ```
221 cd elixir
222 mix stepX_YYY
223 # Or with readline/line editing functionality:
224 iex -S mix stepX_YYY
225 ```
226
227 ### Erlang
228
229 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
230
231 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
232 and [rebar](https://github.com/rebar/rebar) to build.
233
234 ```
235 cd erlang
236 make
237 # OR
238 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
239 ./stepX_YYY
240 ```
241
242 ### ES6 (ECMAScript 6 / ECMAScript 2015)
243
244 The ES6 implementation uses the [babel](https://babeljs.io) compiler
245 to generate ES5 compatible JavaScript. The generated code has been
246 tested with Node 0.12.4.
247
248 ```
249 cd es6
250 make
251 node build/stepX_YYY.js
252 ```
253
254
255 ### F# ###
256
257 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
258
259 The F# implementation of mal has been tested on Linux using the Mono
260 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
261 compiler (mcs) is also necessary to compile the readline dependency. All are
262 required to build and run the F# implementation.
263
264 ```
265 cd fsharp
266 make
267 mono ./stepX_YYY.exe
268 ```
269
270 ### Factor
271
272 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
273
274 The Factor implementation of mal has been tested with Factor 0.97
275 ([factorcode.org](factorcode.org)).
276
277 ```
278 cd factor
279 FACTOR_ROOTS=. factor -run=stepX_YYY
280 ```
281
282 ### Forth
283
284 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
285
286 ```
287 cd forth
288 gforth stepX_YYY.fs
289 ```
290
291 ### Go
292
293 The Go implementation of mal requires that go is installed on on the
294 path. The implementation has been tested with Go 1.3.1.
295
296 ```
297 cd go
298 make
299 ./stepX_YYY
300 ```
301
302
303 ### Groovy
304
305 The Groovy implementation of mal requires Groovy to run and has been
306 tested with Groovy 1.8.6.
307
308 ```
309 cd groovy
310 make
311 groovy ./stepX_YYY.groovy
312 ```
313
314 ### GNU Guile 2.1+
315
316 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
317
318 ```
319 cd guile
320 guile -L ./ stepX_YYY.scm
321 ```
322
323 ### Haskell
324
325 Install the Haskell compiler (ghc/ghci), the Haskell platform and
326 either the editline package (BSD) or the readline package (GPL). On
327 Ubuntu these packages are: ghc, haskell-platform,
328 libghc-readline-dev/libghc-editline-dev
329
330 ```
331 cd haskell
332 make
333 ./stepX_YYY
334 ```
335
336 ### Haxe
337
338 The Haxe implementation of mal requires Haxe version 3.2 to compile.
339 Four different Haxe targets are supported: Neko, Python, C++, and
340 JavaScript.
341
342 ```
343 cd haxe
344 # Neko
345 make all-neko
346 neko ./stepX_YYY.n
347 # Python
348 make all-python
349 python3 ./stepX_YYY.py
350 # C++
351 make all-cpp
352 ./cpp/stepX_YYY
353 # JavaScript
354 make all-js
355 node ./stepX_YYY.js
356 ```
357
358
359 ### Java 1.7
360
361 The Java implementation of mal requires maven2 to build.
362
363 ```
364 cd java
365 mvn compile
366 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
367 # OR
368 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
369 ```
370
371 ### JavaScript/Node
372
373 ```
374 cd js
375 npm update
376 node stepX_YYY.js
377 ```
378
379 ### Julia
380
381 The Julia implementation of mal requires Julia 0.4.
382
383 ```
384 cd julia
385 julia stepX_YYY.jl
386 ```
387
388 ### Kotlin
389
390 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
391
392 The Kotlin implementation of mal has been tested with Kotlin 1.0.
393
394 ```
395 cd kotlin
396 make
397 java -jar stepX_YYY.jar
398 ```
399
400 ### Lua
401
402 Running the Lua implementation of mal requires lua 5.1 or later,
403 luarocks and the lua-rex-pcre library installed.
404
405 ```
406 cd lua
407 make # to build and link linenoise.so
408 ./stepX_YYY.lua
409 ```
410
411 ### Mal
412
413 Running the mal implementation of mal involves running stepA of one of
414 the other implementations and passing the mal step to run as a command
415 line argument.
416
417 ```
418 cd IMPL
419 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
420
421 ```
422
423 ### GNU Make 3.81
424
425 ```
426 cd make
427 make -f stepX_YYY.mk
428 ```
429
430 ### Nim 0.11.0
431
432 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
433
434 Running the Nim implementation of mal requires Nim 0.11.0 or later.
435
436 ```
437 cd nim
438 make
439 # OR
440 nimble build
441 ./stepX_YYY
442 ```
443
444 ### OCaml 4.01.0
445
446 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
447
448 ```
449 cd ocaml
450 make
451 ./stepX_YYY
452 ```
453
454 ### MATLAB
455
456 The MATLAB implementation of mal has been tested with MATLAB version
457 R2014a on Linux. Note that MATLAB is a commercial product. It should
458 be fairly simple to support GNU Octave once it support classdef object
459 syntax.
460
461 ```
462 cd matlab
463 ./stepX_YYY
464 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
465 # OR with command line arguments
466 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
467 ```
468
469 ### miniMAL
470
471 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
472 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
473 implementation of mal you need to download/install the miniMAL
474 interpreter (which requires Node.js).
475 ```
476 cd miniMAL
477 # Download miniMAL and dependencies
478 npm install
479 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
480 # Now run mal implementation in miniMAL
481 miniMAL ./stepX_YYY
482 ```
483
484 ### Perl 5.8
485
486 For readline line editing support, install Term::ReadLine::Perl or
487 Term::ReadLine::Gnu from CPAN.
488
489 ```
490 cd perl
491 perl stepX_YYY.pl
492 ```
493
494
495 ### PHP 5.3
496
497 The PHP implementation of mal requires the php command line interface
498 to run.
499
500 ```
501 cd php
502 php stepX_YYY.php
503 ```
504
505 ### Postscript Level 2/3
506
507 The Postscript implementation of mal requires ghostscript to run. It
508 has been tested with ghostscript 9.10.
509
510 ```
511 cd ps
512 gs -q -dNODISPLAY -I./ stepX_YYY.ps
513 ```
514
515 ### Python (2.X or 3.X)
516
517 ```
518 cd python
519 python stepX_YYY.py
520 ```
521
522 ### RPython
523
524 You must have [rpython](https://rpython.readthedocs.org/) on your path
525 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
526
527 ```
528 cd rpython
529 make # this takes a very long time
530 ./stepX_YYY
531 ```
532
533 ### R
534
535 The R implementation of mal requires R (r-base-core) to run.
536
537 ```
538 cd r
539 make libs # to download and build rdyncall
540 Rscript stepX_YYY.r
541 ```
542
543 ### Racket (5.3)
544
545 The Racket implementation of mal requires the Racket
546 compiler/interpreter to run.
547
548 ```
549 cd racket
550 ./stepX_YYY.rkt
551 ```
552
553 ### Ruby (1.9+)
554
555 ```
556 cd ruby
557 ruby stepX_YYY.rb
558 ```
559
560 ### Rust (1.0.0 nightly)
561
562 The rust implementation of mal requires the rust compiler and build
563 tool (cargo) to build.
564
565 ```
566 cd rust
567 cargo run --release --bin stepX_YYY
568 ```
569
570 ### Scala ###
571
572 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
573
574 ```
575 cd scala
576 sbt 'run-main stepX_YYY'
577 # OR
578 sbt compile
579 scala -classpath target/scala*/classes stepX_YYY
580 ```
581
582 ### Swift
583
584 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
585
586 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
587 7.0) to build. Older versions will not work due to changes in the
588 language and standard library.
589
590 ```
591 cd swift
592 make
593 ./stepX_YYY
594 ```
595
596 ### Swift 3
597
598 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
599 has been tested with the development version of the Swift 3 from
600 2016-02-08.
601
602 ```
603 cd swift3
604 make
605 ./stepX_YYY
606 ```
607
608 ### Tcl 8.6
609
610 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
611
612 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
613 editing support, install tclreadline.
614
615 ```
616 cd tcl
617 tclsh ./stepX_YYY.tcl
618 ```
619
620 ### Vimscript
621
622 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
623
624 The Vimscript implementation of mal requires Vim to run. It has been tested
625 with Vim 7.4.
626
627 ```
628 cd vimscript
629 ./run_vimscript.sh ./stepX_YYY.vim
630 ```
631
632 ### Visual Basic.NET ###
633
634 The VB.NET implementation of mal has been tested on Linux using the Mono
635 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
636 required to build and run the VB.NET implementation.
637
638 ```
639 cd vb
640 make
641 mono ./stepX_YYY.exe
642 ```
643
644
645
646 ## Running tests
647
648 ### Functional tests
649
650 The are nearly 500 generic functional tests (for all implementations)
651 in the `tests/` directory. Each step has a corresponding test file
652 containing tests specific to that step. The `runtest.py` test harness
653 launches a Mal step implementation and then feeds the tests one at
654 a time to the implementation and compares the output/return value to
655 the expected output/return value.
656
657 To simplify the process of running tests, a top level Makefile is
658 provided with convenient test targets.
659
660 * To run all the tests across all implementations (be prepared to wait):
661
662 ```
663 make test
664 ```
665
666 * To run all tests against a single implementation:
667
668 ```
669 make "test^IMPL"
670
671 # e.g.
672 make "test^clojure"
673 make "test^js"
674 ```
675
676 * To run tests for a single step against all implementations:
677
678 ```
679 make "test^stepX"
680
681 # e.g.
682 make "test^step2"
683 make "test^step7"
684 ```
685
686 * To run tests for a specific step against a single implementation:
687
688 ```
689 make "test^IMPL^stepX"
690
691 # e.g
692 make "test^ruby^step3"
693 make "test^ps^step4"
694 ```
695
696 ### Self-hosted functional tests
697
698 * To run the functional tests in self-hosted mode, you specify `mal`
699 as the test implementation and use the `MAL_IMPL` make variable
700 to change the underlying host language (default is JavaScript):
701 ```
702 make MAL_IMPL=IMPL "test^mal^step2"
703
704 # e.g.
705 make "test^mal^step2" # js is default
706 make MAL_IMPL=ruby "test^mal^step2"
707 make MAL_IMPL=python "test^mal^step2"
708 ```
709
710 ### Starting the REPL
711
712 * To start the REPL of an implementation in a specific step:
713
714 ```
715 make "repl^IMPL^stepX"
716
717 # e.g
718 make "repl^ruby^step3"
719 make "repl^ps^step4"
720 ```
721
722 * If you omit the step, then `stepA` is used:
723
724 ```
725 make "repl^IMPL"
726
727 # e.g
728 make "repl^ruby"
729 make "repl^ps"
730 ```
731
732 * To start the REPL of the self-hosted implementation, specify `mal` as the
733 REPL implementation and use the `MAL_IMPL` make variable to change the
734 underlying host language (default is JavaScript):
735 ```
736 make MAL_IMPL=IMPL "repl^mal^stepX"
737
738 # e.g.
739 make "repl^mal^step2" # js is default
740 make MAL_IMPL=ruby "repl^mal^step2"
741 make MAL_IMPL=python "repl^mal"
742 ```
743
744 ### Performance tests
745
746 Warning: These performance tests are neither statistically valid nor
747 comprehensive; runtime performance is a not a primary goal of mal. If
748 you draw any serious conclusions from these performance tests, then
749 please contact me about some amazing oceanfront property in Kansas
750 that I'm willing to sell you for cheap.
751
752 * To run performance tests against a single implementation:
753 ```
754 make "perf^IMPL"
755
756 # e.g.
757 make "perf^js"
758 ```
759
760 * To run performance tests against all implementations:
761 ```
762 make "perf"
763 ```
764
765 ### Generating language statistics
766
767 * To report line and byte statistics for a single implementation:
768 ```
769 make "stats^IMPL"
770
771 # e.g.
772 make "stats^js"
773 ```
774
775 * To report line and bytes statistics for general Lisp code (env, core
776 and stepA):
777 ```
778 make "stats-lisp^IMPL"
779
780 # e.g.
781 make "stats-lisp^js"
782 ```
783
784 ## Docker test environment
785
786 There is a Dockerfile included in the `tests/docker` directory that
787 builds a docker image based on Ubuntu Utopic that contains everything
788 needed to run tests against all the implementations (except for MATLAB
789 which is proprietary/licensed).
790
791 Build the docker image using a provided script. WARNING: this will
792 likely take over an hour to build from scratch and use more 3 GB of disk:
793 ```bash
794 ./tests/docker-build.sh
795 ```
796
797 Launch a docker container from that image built above. This will
798 volume mount the mal directory to `/mal` and then give you a bash
799 prompt in the container. You can then run individual mal
800 implementations and tests:
801 ```bash
802 ./tests/docker-run.sh
803 ```
804
805 You can also specify a command to run within the container. For
806 example, to run step2 tests for every implementation (except MATLAB):
807 ```bash
808 ./tests/docker-run.sh make SKIP_IMPLS="matlab" "test^step2"
809 ```
810
811 **Notes**:
812 * JVM-based language implementations (Java, Clojure, Scala): you will
813 need to run these implementations once manually first before you can
814 run tests because runtime dependencies need to be downloaded to
815 avoid the tests timing out. These dependencies are download to
816 dot-files in the /mal directory so they will persist between runs.
817 * Compiled languages: if your host system is different enough from
818 Ubuntu Utopic then you may need to re-compile your compiled
819 languages from within the container to avoid linker version
820 mismatches.
821
822
823 ## License
824
825 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
826 License 2.0). See LICENSE.txt for more details.