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