Add factor instructions to readme
[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 ### Factor
139
140 *The Nim implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
141
142 ```
143 cd factor
144 FACTOR_ROOTS=src factor -run=stepX_YYY
145 ```
146
147 ### Forth
148
149 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
150
151 ```
152 cd forth
153 gforth stepX_YYY.fs
154 ```
155
156 ### Go
157
158 You Go implementation of mal requires that go is installed on on the
159 path. The implementation has been tested with Go 1.3.1.
160
161 ```
162 cd go
163 make
164 ./stepX_YYY
165 ```
166
167
168 ### Haskell
169
170 Install the Haskell compiler (ghc/ghci), the Haskell platform and
171 either the editline package (BSD) or the readline package (GPL). On
172 Ubuntu these packages are: ghc, haskell-platform,
173 libghc-readline-dev/libghc-editline-dev
174
175 ```
176 cd haskell
177 make
178 ./stepX_YYY
179 ```
180
181
182 ### Java 1.7
183
184 The Java implementation of mal requires maven2 to build.
185
186 ```
187 cd java
188 mvn compile
189 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
190 # OR
191 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
192 ```
193
194 ### JavaScript/Node
195
196 ```
197 cd js
198 npm update
199 node stepX_YYY.js
200 ```
201
202 ### Julia
203
204 The Julia implementation of mal has been tested with Julia 0.3.7.
205
206 ```
207 cd julia
208 julia stepX_YYY.jl
209 ```
210
211 ### Lua
212
213 Running the Lua implementation of mal requires lua 5.1 or later,
214 luarocks and the lua-rex-pcre library installed.
215
216 ```
217 cd lua
218 make # to build and link linenoise.so
219 ./stepX_YYY.lua
220 ```
221
222 ### Mal
223
224 Running the mal implementation of mal involves running stepA of one of
225 the other implementations and passing the mal step to run as a command
226 line argument.
227
228 ```
229 cd IMPL
230 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
231
232 ```
233
234 ### GNU Make 3.81
235
236 ```
237 cd make
238 make -f stepX_YYY.mk
239 ```
240
241 ### Nim 0.10.3
242
243 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
244
245 Running the Nim implementation of mal requires Nim's current devel branch
246 (0.10.3) or later, and the nre library installed.
247
248 ```
249 cd nim
250 make
251 # OR
252 nimble build
253 ./stepX_YYY
254 ```
255
256 ### OCaml 4.01.0
257
258 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
259
260 ```
261 cd ocaml
262 make
263 ./stepX_YYY
264 ```
265
266 ### MATLAB
267
268 The MATLAB implementation of mal has been tested with MATLAB version
269 R2014a on Linux. Note that MATLAB is a commercial product. It should
270 be fairly simple to support GNU Octave once it support classdef object
271 syntax.
272
273 ```
274 cd matlab
275 ./stepX_YYY
276 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
277 # OR with command line arguments
278 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
279 ```
280
281 ### miniMAL
282
283 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
284 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
285 implementation of mal you need to download/install the miniMAL
286 interpreter (which requires Node.js).
287 ```
288 cd miniMAL
289 # Download miniMAL and dependencies
290 npm install
291 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
292 # Now run mal implementation in miniMAL
293 miniMAL ./stepX_YYY
294 ```
295
296 ### Perl 5.8
297
298 For readline line editing support, install Term::ReadLine::Perl or
299 Term::ReadLine::Gnu from CPAN.
300
301 ```
302 cd perl
303 perl stepX_YYY.pl
304 ```
305
306
307 ### PHP 5.3
308
309 The PHP implementation of mal requires the php command line interface
310 to run.
311
312 ```
313 cd php
314 php stepX_YYY.php
315 ```
316
317 ### Postscript Level 2/3
318
319 The Postscript implementation of mal requires ghostscript to run. It
320 has been tested with ghostscript 9.10.
321
322 ```
323 cd ps
324 gs -q -dNODISPLAY -I./ stepX_YYY.ps
325 ```
326
327 ### Python (2 or 3)
328
329 ```
330 cd python
331 python stepX_YYY.py
332 ```
333
334 ### R
335
336 The R implementation of mal requires R (r-base-core) to run.
337
338 ```
339 cd r
340 make libs # to download and build rdyncall
341 Rscript stepX_YYY.r
342 ```
343
344 ### Racket (5.3)
345
346 The Racket implementation of mal requires the Racket
347 compiler/interpreter to run.
348
349 ```
350 cd racket
351 ./stepX_YYY.rkt
352 ```
353
354 ### Ruby (1.9+)
355
356 ```
357 cd ruby
358 ruby stepX_YYY.rb
359 ```
360
361 ### Rust (1.0.0 nightly)
362
363 The rust implementation of mal requires the rust compiler and build
364 tool (cargo) to build.
365
366 ```
367 cd rust
368 cargo run --release --bin stepX_YYY
369 ```
370
371 ### Scala ###
372
373 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
374
375 ```
376 cd scala
377 sbt 'run-main stepX_YYY'
378 # OR
379 sbt compile
380 scala -classpath target/scala*/classes stepX_YYY
381 ```
382
383 ### Swift
384
385 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
386
387 The Swift implemenation of mal requires the Swift compiler (XCode) to
388 build.
389
390 ```
391 cd swift
392 make
393 ./stepX_YYY
394 ```
395
396 ### Visual Basic.NET ###
397
398 The VB.NET implementation of mal has been tested on Linux using the Mono
399 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
400 required to build and run the VB.NET implementation.
401
402 ```
403 cd vb
404 make
405 mono ./stepX_YYY.exe
406 ```
407
408
409
410 ## Running tests
411
412 ### Functional tests
413
414 The are nearly 500 generic functional tests (for all implementations)
415 in the `tests/` directory. Each step has a corresponding test file
416 containing tests specific to that step. The `runtest.py` test harness
417 launches a Mal step implementation and then feeds the tests one at
418 a time to the implementation and compares the output/return value to
419 the expected output/return value.
420
421 To simplify the process of running tests, a top level Makefile is
422 provided with convenient test targets.
423
424 * To run all the tests across all implementations (be prepared to wait):
425
426 ```
427 make test
428 ```
429
430 * To run all tests against a single implementation:
431
432 ```
433 make test^IMPL
434
435 # e.g.
436 make test^clojure
437 make test^js
438 ```
439
440 * To run tests for a single step against all implementations:
441
442 ```
443 make test^stepX
444
445 # e.g.
446 make test^step2
447 make test^step7
448 ```
449
450 * To run tests for a specifc step against a single implementation:
451
452 ```
453 make test^IMPL^stepX
454
455 # e.g
456 make test^ruby^step3
457 make test^ps^step4
458 ```
459
460 ### Self-hosted functional tests
461
462 * To run the functional tests in self-hosted mode, you specify `mal`
463 as the test implementation and use the `MAL_IMPL` make variable
464 to change the underlying host language (default is JavaScript):
465 ```
466 make MAL_IMPL=IMPL test^mal^step2
467
468 # e.g.
469 make test^mal^step2 # js is default
470 make MAL_IMPL=ruby test^mal^step2
471 make MAL_IMPL=python test^mal^step2
472 ```
473
474
475 ### Performance tests
476
477 Warning: These performance tests are neither statistically valid nor
478 comprehensive; runtime performance is a not a primary goal of mal. If
479 you draw any serious conclusions from these performance tests, then
480 please contact me about some amazing oceanfront property in Kansas
481 that I'm willing to sell you for cheap.
482
483 * To run performance tests against a single implementation:
484 ```
485 make perf^IMPL
486
487 # e.g.
488 make perf^js
489 ```
490
491 * To run performance tests against all implementations:
492 ```
493 make perf
494 ```
495
496 ### Generating language statistics
497
498 * To report line and byte stastics for a single implementation:
499 ```
500 make stats^IMPL
501
502 # e.g.
503 make stats^js
504 ```
505
506 * To report line and bytes stastics for general Lisp code (env, core
507 and stepA):
508 ```
509 make stats-lisp^IMPL
510
511 # e.g.
512 make stats-lisp^js
513 ```
514
515 ## Docker test environment
516
517 There is a Dockerfile included in the `tests/docker` directory that
518 builds a docker image based on Ubuntu Utopic that contains everything
519 needed to run tests against all the implementations (except for MATLAB
520 which is proprietary/licensed).
521
522 Build the the docker image using a provided script. WARNING: this will
523 likely take over an hour to build from scratch and use more 3 GB of disk:
524 ```bash
525 ./tests/docker-build.sh
526 ```
527
528 Launch a docker container from that image built above. This will
529 volume mount the mal directory to `/mal` and then give you a bash
530 prompt in the container. You can then run individual mal
531 implementations and tests:
532 ```bash
533 ./tests/docker-run.sh
534 ```
535
536 You can also specify a command to run within the container. For
537 example, to run step2 tests for every implementation (except MATLAB):
538 ```bash
539 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
540 ```
541
542 **Notes**:
543 * JVM-based language implementations (Java, Clojure, Scala): you will
544 need to run these implementations once manually first before you can
545 run tests because runtime dependencies need to be downloaded to
546 avoid the tests timing out. These dependencies are download to
547 dot-files in the /mal directory so they will persist between runs.
548 * Compiled languages: if your host system is different enough from
549 Ubuntu Utopic then you may need to re-compile your compiled
550 languages from within the container to avoid linker version
551 mismatches.
552
553
554 ## License
555
556 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
557 License 2.0). See LICENSE.txt for more details.
558