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