racket: fix apply/vector
[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
a2cd0a3a 7Mal is implemented in 27 different languages:
bcddc3e4 8
edc3b064 9* Bash shell
bcddc3e4 10* C
edc3b064
JM
11* C#
12* Clojure
891c3f3b 13* CoffeeScript
96032890 14* Forth
1771ab50 15* Go
b76aa73b 16* Haskell
bcddc3e4 17* Java
d32f9b87 18* Javascript ([Online Demo](http://kanaka.github.io/mal))
9d42904e 19* Lua
bcddc3e4
JM
20* GNU Make
21* mal itself
8a9d0a8a 22* MATLAB
1218ce98 23* [miniMAL](https://github.com/kanaka/miniMAL)
a2cd0a3a 24* Nim
bc6448bc 25* OCaml
6301e0b6 26* Perl
edc3b064
JM
27* PHP
28* Postscript
29* Python
9b3362e8 30* R
f5223195 31* Racket
8adb0827 32* Ruby
abdd56eb 33* Rust
821930db 34* Scala
ee7cd585 35* Visual Basic.NET
bcddc3e4
JM
36
37
bd08422d
JM
38Mal is a learning tool. See the [make-a-lisp process
39guide](process/guide.md). Each implementation of mal is separated into
4011 incremental, self-contained (and testable) steps that demonstrate
41core concepts of Lisp. The last step is capable of self-hosting
42(running the mal implementation of mal).
bcddc3e4
JM
43
44The mal (make a lisp) steps are:
45
0f4ca9d1
JM
46* [step0_repl](process/guide.md#step0)
47* [step1_read_print](process/guide.md#step1)
48* [step2_eval](process/guide.md#step2)
49* [step3_env](process/guide.md#step3)
50* [step4_if_fn_do](process/guide.md#step4)
51* [step5_tco](process/guide.md#step5)
52* [step6_file](process/guide.md#step6)
53* [step7_quote](process/guide.md#step7)
54* [step8_macros](process/guide.md#step8)
55* [step9_try](process/guide.md#step9)
90f618cb 56* [stepA_mal](process/guide.md#stepA)
bcddc3e4
JM
57
58
59Mal was presented publicly for the first time in a lightning talk at
60Clojure West 2014 (unfortunately there is no video). See
61mal/clojurewest2014.mal for the presentation that was given at the
62conference (yes the presentation is a mal program).
60154d24 63
144f2b6a
JM
64If you are interesting in creating a mal implementation (or just
65interested in using mal for something), please stop by the #mal
66channel on freenode. In addition to the [make-a-lisp process
67guide](process/guide.md) there is also a [mal/make-a-lisp
68FAQ](docs/FAQ.md) where I attempt to answer some common questions.
69
60154d24
JM
70## Building/running implementations
71
bcddc3e4 72### Bash 4
60154d24
JM
73
74```
75cd bash
76bash stepX_YYY.sh
77```
78
bcddc3e4 79### C
60154d24 80
01c97316
JM
81The C implementation of mal requires the following libraries (lib and
82header packages): glib, libffi6 and either the libedit or GNU readline library.
54c75382 83
60154d24
JM
84```
85cd c
86make
87./stepX_YYY
88```
89
9b1563a3 90### C# ###
edc3b064
JM
91
92The C# implementation of mal has been tested on Linux using the Mono
93C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
94required to build and run the C# implementation.
95
96```
97cd cs
98make
ee7cd585 99mono ./stepX_YYY.exe
edc3b064
JM
100```
101
102
bcddc3e4 103### Clojure
60154d24
JM
104
105```
106cd clojure
107lein with-profile +stepX trampoline run
108```
109
891c3f3b
JM
110### CoffeeScript
111
112```
113sudo npm install -g coffee-script
114cd coffee
115coffee ./stepX_YYY
116```
117
96032890
C
118### Forth
119
120```
121cd forth
122gforth stepX_YYY.fs
123```
124
1771ab50
JM
125### Go
126
fd888612
JM
127You Go implementation of mal requires that go is installed on on the
128path. The implementation has been tested with Go 1.3.1.
129
1771ab50
JM
130```
131cd go
132make
133./stepX_YYY
134```
135
136
b76aa73b
JM
137### Haskell
138
2988d38e 139Install the Haskell compiler (ghc/ghci), the Haskell platform and
5400d4bf
JM
140either the editline package (BSD) or the readline package (GPL). On
141Ubuntu these packages are: ghc, haskell-platform,
142libghc-readline-dev/libghc-editline-dev
b76aa73b
JM
143
144```
145cd haskell
146make
147./stepX_YYY
148```
149
150
bcddc3e4 151### Java 1.7
60154d24 152
01c97316
JM
153The Java implementation of mal requires maven2 to build.
154
60154d24
JM
155```
156cd java
157mvn compile
158mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
159 # OR
160mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
161```
162
bcddc3e4 163### Javascript/Node
60154d24
JM
164
165```
166cd js
54c75382 167npm update
60154d24
JM
168node stepX_YYY.js
169```
170
9d42904e
JM
171### Lua
172
8a9d0a8a 173Running the Lua implementation of mal requires lua 5.1 or later,
9d42904e
JM
174luarocks and the lua-rex-pcre library installed.
175
176```
177cd lua
178make # to build and link linenoise.so
179./stepX_YYY.lua
180```
181
bcddc3e4 182### Mal
60154d24
JM
183
184Running the mal implementation of mal involves running stepA of one of
185the other implementations and passing the mal step to run as a command
5d446bd8 186line argument.
60154d24
JM
187
188```
189cd IMPL
190IMPL_STEPA_CMD ../mal/stepX_YYY.mal
191
192```
193
bcddc3e4 194### GNU Make 3.81
60154d24
JM
195
196```
197cd make
198make -f stepX_YYY.mk
199```
200
a2cd0a3a 201### Nim 0.10.3
202
203Running the Nim implementation of mal requires Nim's current devel branch
204(0.10.3) or later, and the nre library installed.
205
206```
207cd nim
208make
209 # OR
210nimble build
211./stepX_YYY
212```
213
bc6448bc
C
214### OCaml 4.01.0
215
216```
217cd ocaml
218make
219./stepX_YYY
220```
221
8a9d0a8a
JM
222### MATLAB
223
224The MATLAB implementation of mal has been tested with MATLAB version
225R2014a on Linux. Note that MATLAB is a commercial product. It should
226be fairly simple to support GNU Octave once it support classdef object
227syntax.
228
229```
230cd matlab
231./stepX_YYY
232matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
233 # OR with command line arguments
234matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
235```
236
1218ce98
JM
237### miniMAL
238
239[miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
240implemented in less than 1024 bytes of JavaScript. To run the miniMAL
241implementation of mal you need to download/install the miniMAL
242interpreter (which requires Node.js).
243```
1218ce98 244cd miniMAL
478fd9ce
JM
245# Download miniMAL and dependencies
246npm install
247export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
248# Now run mal implementation in miniMAL
1218ce98
JM
249miniMAL ./stepX_YYY
250```
251
9b1563a3 252### Perl 5.8
9e5b2151
JM
253
254For readline line editing support, install Term::ReadLine::Perl or
255Term::ReadLine::Gnu from CPAN.
256
257```
258cd perl
259perl stepX_YYY.pl
260```
261
262
bcddc3e4 263### PHP 5.3
60154d24 264
01c97316
JM
265The PHP implementation of mal requires the php command line interface
266to run.
267
60154d24
JM
268```
269cd php
270php stepX_YYY.php
271```
272
bcddc3e4 273### Postscript Level 2/3
60154d24 274
01c97316
JM
275The Postscript implementation of mal requires ghostscript to run. It
276has been tested with ghostscript 9.10.
277
60154d24
JM
278```
279cd ps
fa64b741 280gs -q -dNODISPLAY -I./ stepX_YYY.ps
60154d24
JM
281```
282
a05f7822 283### Python (2 or 3)
60154d24
JM
284
285```
286cd python
287python stepX_YYY.py
288```
8adb0827 289
9b3362e8
JM
290### R
291
292The R implementation of mal requires R (r-base-core) to run.
293
294```
295cd r
9d42904e 296make libs # to download and build rdyncall
f5223195
JM
297Rscript stepX_YYY.r
298```
299
300### Racket (5.3)
301
302The Racket implementation of mal requires the Racket
303compiler/interpreter to run.
304
305```
306cd racket
3796240a 307./stepX_YYY.rkt
9b3362e8
JM
308```
309
107d9694 310### Ruby (1.9+)
8adb0827
JM
311
312```
313cd ruby
314ruby stepX_YYY.rb
315```
592eb5cf 316
9106a221 317### Rust (1.0.0 nightly)
abdd56eb
JM
318
319The rust implementation of mal requires the rust compiler and build
320tool (cargo) to build.
321
322```
323cd rust
bbeb1b87 324cargo run --release --bin stepX_YYY
abdd56eb
JM
325```
326
821930db
JM
327### Scala ###
328
329Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
330
331```
332cd scala
333sbt 'run-main stepX_YYY'
334 # OR
335sbt compile
336scala -classpath target/scala*/classes stepX_YYY
337```
338
ee7cd585
JM
339### Visual Basic.NET ###
340
341The VB.NET implementation of mal has been tested on Linux using the Mono
342VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
343required to build and run the VB.NET implementation.
344
345```
346cd vb
347make
348mono ./stepX_YYY.exe
349```
350
351
352
592eb5cf
JM
353## Running tests
354
294aba2c
JM
355### Functional tests
356
357The are nearly 500 generic functional tests (for all implementations)
358in the `tests/` directory. Each step has a corresponding test file
359containing tests specific to that step. The `runtest.py` test harness
360uses pexpect to launch a Mal step implementation and then feeds the
361tests one at a time to the implementation and compares the
362output/return value to the expected output/return value.
592eb5cf
JM
363
364To simplify the process of running tests, a top level Makefile is
365provided with convenient test targets.
366
367* To run all the tests across all implementations (be prepared to wait):
368
369```
370make test
371```
372
373* To run all tests against a single implementation:
374
375```
376make test^IMPL
377
378# e.g.
379make test^clojure
380make test^js
381```
382
383* To run tests for a single step against all implementations:
384
385```
386make test^stepX
387
388# e.g.
389make test^step2
390make test^step7
391```
392
294aba2c 393* To run tests for a specifc step against a single implementation:
592eb5cf
JM
394
395```
396make test^IMPL^stepX
397
398# e.g
399make test^ruby^step3
400make test^ps^step4
401```
fd888612 402
294aba2c
JM
403### Self-hosted functional tests
404
405* To run the functional tests in self-hosted mode, you specify `mal`
406 as the test implementation and use the `MAL_IMPL` make variable
407 to change the underlying host language (default is JavaScript):
408```
409make MAL_IMPL=IMPL test^mal^step2
410
411# e.g.
412make test^mal^step2 # js is default
413make MAL_IMPL=ruby test^mal^step2
414make MAL_IMPL=python test^mal^step2
415```
416
417
418### Performance tests
419
8569b2af
JM
420Warning: These performance tests are neither statistically valid nor
421comprehensive; runtime performance is a not a primary goal of mal. If
422you draw any serious conclusions from these performance tests, then
423please contact me about some amazing oceanfront property in Kansas
424that I'm willing to sell you for cheap.
425
294aba2c
JM
426* To run performance tests against a single implementation:
427```
428make perf^IMPL
429
430# e.g.
431make perf^js
432```
433
434* To run performance tests against all implementations:
435```
436make perf
437```
438
439### Generating language statistics
440
441* To report line and byte stastics for a single implementation:
442```
443make stats^IMPL
444
445# e.g.
446make stats^js
447```
448
449* To report line and bytes stastics for general Lisp code (env, core
450 and stepA):
451```
452make stats-lisp^IMPL
453
454# e.g.
455make stats-lisp^js
456```
457
75363567
JM
458## Docker test environment
459
460There is a Dockerfile included in the `tests/docker` directory that
461builds a docker image based on Ubuntu Utopic that contains everything
462needed to run tests against all the implementations (except for MATLAB
463which is proprietary/licensed).
464
465Build the the docker image using a provided script. WARNING: this will
466likely take over an hour to build from scratch and use more 3 GB of disk:
467```bash
468./tests/docker-build.sh
469```
470
471Launch a docker container from that image built above. This will
472volume mount the mal directory to `/mal` and then give you a bash
473prompt in the container. You can then run individual mal
474implementations and tests:
475```bash
476./tests/docker-run.sh
477```
478
479You can also specify a command to run within the container. For
480example, to run step2 tests for every implementation (except MATLAB):
481```bash
482./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
483```
484
485**Notes**:
486* JVM-based language implementations (Java, Clojure, Scala): you will
487 need to run these implementations once manually first before you can
488 run tests because runtime dependencies need to be downloaded to
489 avoid the tests timing out. These dependencies are download to
490 dot-files in the /mal directory so they will persist between runs.
491* Compiled languages: if you host system is different enough from
492 Ubuntu Utopic then you may need to re-compile your compiled
493 languages from within the container to avoid linker version
494 mismatches.
495
294aba2c 496
fd888612
JM
497## License
498
499Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
500License 2.0). See LICENSE.txt for more details.
501