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