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