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