(&& x y) => x && y
(|| x y) => x || y
(+ x y) => x + y
(- x y) => x - y
(* x y) => x * y
(/ x y) => x / y
(% x y) => x % y
(+= x y) => x += y
(-= x y) => x -= y
(*= x y) => x *= y
(/= x y) => x /= y
(%= x y) => x %= y
(= x y) => x = y
(== x y) => x == y
(=== x y) => x === y
(!= x y) => x != y
(!== x y) => x !== y
(! x) => !x
(++ x) => ++x
(-- x) => --x
(. x y) => x.y
While the dot operator's base form should be a prefixed s-expression like all the others, it may be awkward to use in practice: (. (. ($ "body") (addClass "hidden")) (hide))
=> $("body").addClass("hidden").hide();
Since the dot operator is so common in idiomatic JavaScript, I propose allowing it to be infixed as a special case: ; expands to the above prefixed version
($ "body").(addClass "hidden").(hide)
For blocks we use a wrapper function rather than the curly brace block so that lexical scoping for variables can be ensured: (do (= x 5) => (function() {
(++ x)) var x;
x = 5;
return ++x;
}).call(this);
The ternary operator: (?: x y z) => (x ? y : z)
Perhaps we can create a useful distinction between the ternary operator and if-statements by giving if implicit do (just as cond has implicit progn in Common Lisp), but I'm not sure what the most elegant solution is. Thoughts?Functions:
(function) => (function() {});
(function ()) => (function() {});
(function () => function() {
(+ 1 1)) return 1 + 1;
};
(= foo (function () => var foo;
(+ 1 1))) foo = function() {
return 1 + 1;
}
We could build a simple unhygienic macro system using the traditional quote ('), quasiquote (`), unquote (,) and unquote-splicing (,@) operators, as well as rest parameters (&). Here's how you might define a macro called unless: ; macro definition
(mac unless (x & args)
`(if (! ,x) ,@args))
; example usage
(unless true
(alert "Won't be executed"))
; expands to:
(if (! true)
(alert "Won't be executed"))
=> if (!true) {
alert("Won't be executed");
}
More coming...