A lisp-like language that runs on node, written in Purescript (which is written in Haskell).
First make sure you have purescript (>= 0.8.5) and pulp (>= 8.1.0) installed, as well as node, npm and bower.
Run bower install then pulp run --interactive to get a REPL.
Alternatively, you can interpret a file with pulp run $(cat <filename>).
pulp build --optimise --to ssc.js
sed -i '1s/^/#!\/usr\/bin\/env node\n/' ssc.js
chmod +x ssc.jsEverything is an S-expression. Quoted lists are supported.
Values are immutable.
Defining variables is done with def: (def x 3)
Defining functions is similar:
(def (f x y) (+ x y)
(def (compose f g)
(lambda (x) (f (g x))))Primitive types come in the following flavors:
- Atoms => 'atom
- Strings => "hello world"
- Bools => True, False
- Ints => 2, -2
There's one type of collection, a linked list. List literals can be made as follows: '(1 True "string").
+add 2 or more numbers-subtract 2 or more numbers*multiply 2 or more numbers/divide 2 or more numbers%mod 2 or more numbers=check equality between numbers<check if the first number is less than the second>check if the first number is greater than the second<=check if the first number is greater than the second>=check if the first number is less than the second/=check equality between numbers&&truth-functional and||truth-functional orstring=?check equality between stringsstring>?check if the first string is greater than the secondstring<?check if the first string is less than the secondstring>=?check if the first string is less than the secondstring<=?check if the first string is greater than the secondheadget the first element in a nonempty listtailget the tail of a listconsadd an element to the front of the given listeqvcheck equality of two terms of the same type==same aseqv
While based on Write Yourself A Scheme, there are quite a few differences:
- Instead of using Refs to store the environment, the environment is stored in a StateT transformer monad.
- Instead of using an association list as the environment, StrMaps are used
- No support for dotted lists
- "IO primitives" are handled by the REPL as directives instead of given as language primitives.
In particular, the base monad for the transformer stack is left polymorphic: The REPL uses Aff to deal with user input, and the source-code file interpreter uses Eff. In principle this means one could use, for example, the Trampoline monad at the base to handle stack overflows in the language (which were a serious problem in a previous version), though I haven't tested this yet.