LispyScriptA javascript With Lispy Syntax And Macros!
An inherent problem with Javascript is that it has no macro support, unlike other Lisp like languages. That's because macros manipulate the syntax tree while compiling. And this is next to impossible in a language like Javascript.
In LispyScript we write Javascript in a tree structure. If you know Javascript and a Lisp like language, then using LispyScript will be a breeze. Even if you don't know a Lispy Language, all you need to learn is to write code in a tree structure.
(console.log "Hello LispyScript!")
A LispyScript program is made up of expressions in parenthesis. The first element in the expression is a function or a LispyScript keyword. The rest of the elements (separated by space characters) are the arguments to the function. As you can see above we can directly access javascript functions from LispyScript.
A more intricate Hello World!
(if (undefined? window) (console.log "Hello LispyScript!") (alert "Hello LispyScript!"))
You can have expressions within expressions.
An anonymous function in LispyScript.
(function (x) (* x x))
The first element in an expression can be an anonymous function.
((function (x) (* x x)) 2)
That was the anonymous function above evaluated immediately with argument 2. Functions return the last expression evaluated within the function.
You can set a variable name to a function.
(var square (function (x) (* x x))) (console.log (square 10))
The 'var' expression takes a variable name as the second element and sets its value to the third.
All Javascript functions, objects and literals can be used in LispyScript.
(Array.prototype.forEach.call [1, 2, 3]
(function (elem index list)
(console.log elem)))
If you noticed we passed a Javascript literal array as the first argument to 'forEach'.
You can access object methods and properties using the '.' notation.
(console.log (.greet {greet: "hello"}))
ie. If the first element of an expression starts with a '.', it's considered as a property of the second element, and the expression evaluates to the property.
You can also use the 'get' expression to access a property of an object.
(console.log (get "greet" {greet: "hello"}))
(console.log(get 1 [1, 2, 3]))
You can 'set' variables too.
(set name "John") (set window.onload (function () (alert "Page Loaded"))) ; You can set array indices using the three argument version of set (var foo []) (set 1 foo "hello") => foo[1] = "hello"; (set "bar" foo "hello") => foo["bar'] = "hello";
The node server example in LispyScript.
(var http (require "http"))
(var server
(http.createServer
(function (request response)
(response.writeHead 200 {'Content-Type': 'text/plain'})
(response.end "Hello World\n"))))
(server.listen 1337 "127.0.0.1")
(console.log "Server running at http://127.0.0.1:1337/")
And there are Macros! and Templates! and more in LispyScript!
$ npm install -g lispyscript
$ git clone git@github.com:santoshrajan/lispyscript.git $ cd path/to/lispyscript $ npm link
$ lispy
$ lispy test.ls
$ lispy src/test.ls lib/test.js
$ lispy -h
Usage: lispy [-h] [-r] [<infile>] [<outfile>]
Also compile stdin to stdout
eg. $ echo '(console.log "hello")' | lispy
<no arguments> Run REPL
-h Show this help
-r Compile and run
-v Show Version
<infile> Input file to compile
<outfile> Output JS file. If not given
<outfile> will be <infile>
with .js extension
A LispyScript example using Nodejs, Expressjs, Twitter Bootstrap and LispyScript html5 templates.