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