Inspiration: Lua, JavaScript, Circa, promises, reactive programming
Base concepts:
-
base object === map (no properties or methods)
map = {} map.toString // null
-
anything can be a key for a map
key = {} map = { [key] = 1 }
-
non-OO methods to modify maps (like
table.*
in Lua) so that base objects can really be maps (unlike JS)map = { a = 1 } Map.toString(map) Map.remove(map, 'a')
-
functions have rest parameters (in tuple or array)
function f(a, b, c, ...) { print(...) // tuple print([...]) // array } f(1, 2, 3, 4, 5) // 4 5 // [4, 5]
-
every value is a promise, every function/operator/keyword accepts promises and returns promises
-
every value (reference?) is an observable
-
functions and code blocks
- in functions
this
is dynamically bound - in code blocks
this
isparent.this
- code blocks' return/break/… override parent's return/break/…
- in functions
-
closures
-
variables have function/code block scope
-
AST-level reflection, API to modify code at runtime
-
functions return multiple values (tuples)
a, b, c = f() g(f())
-
strings
- strings === arrays of characters
- template strings
- es6 tags
Syntax/Sugar:
-
collections implements composite pattern
array = [new Drawable(), 1, new Drawable()] array.draw() // invokes draw() on array[0] and array[2], no-op for array[1]
-
=
→ usual assignment,:=
→ reactive assignmentb = 1 c = 2 a := b + c b = 3 print(a) // 5
-
Safe Navigation Operator
?.
(from Groovy)a = { b = {} } a.b.c.d // error a?.b?.c?.d // null // other syntaxes? a..b..c..d a:b:c:d
-
ranges
[1;5] // inclusive ]1; 5[ // exclusive [0; Infinity[ // mixed, infinite [0; 100] - 50 // ? range to set
-
? operator = toBoolean()
if (obj) {} → if (obj?) {}
-
integrated shell syntax
{{ ps auw | grep foo }} //shell delimiters %x"ps auw | grep foo" // like Ruby grep zsh /etc/password | function (line) {} // pipe commands into functions
Maybe
- macros
- tail call optimization