range
This syntax simply calls the Range constructor.
a..b is inclusive and a...b is exclusive of b.
.. splits tokens earlier than .,
so you can write 0...array.length but have to write (0...6).by 2.
a... is an infinite range.
. 0..1 . 2...4 . (4...8).by 2 . @take 8... 3
sub
sub is a poly with special syntax.
It does Map lookups, Seq lookups by index.
It also partially applies functions.
Remember that spaces are significant:
a[b] calls sub on a while a [b] calls a on an Array.
map = 1 -> 1 . map[1] foo = \a b c [a b c] || Call `sub` with 2 arguments. bar = foo[1 2] . bar 3 || Calling `sub` with 1 argument may require parentheses. . [0 1 2][(Math.min 2 3)]
:= can be used with subs too.
You can remove values with del, which returns a ? of the value that was there.
map = empty Map map[1] := 2 . map[1] . del map[1] . del map[1]
Many types also support sub, as in Array[Number].
Usually this is just the identity, so it's just for documentation.
&
& lets you write simple functions one one line.
Use &() to write a function of one argument, _, on one line.
There are more short forms for named methods:
obj&foois short forobj.foo.bind obj..&foois short forthis&foo.&foois short for:\_ ...args _.foo ...args
&.foo is short for &(_.foo).
. @keep [1 2 3 4] &(divisible? _ 2) . @map [1 2 3] 'foo&repeat . @map [1 2] &toString . @map ['a 'bb 'ccc] &.length
& is compatible with [] for partial application.
. @map 0..3 'abc&slice[0]
For operators, &+ and friends represent a function version.
For non-unary operators this is a variadic function.
. @map [true false true] ¬ . @map [1 2 3] &+[1]
with
with lets you create an empty object and build it up by modifying it.
It assigns to _, or to a new local specified with as.
. with []
_.push 1
_.push 2
. with {} as o
o.x := 1
o.y := 2
pipe
A common pattern is to repeatedly apply transforms to a value.
With pipe, _ on each line of the indented block represents the value of the previous line.
The start value goes before the indented block. [1 2 3 4 5 in this example.]
pipe [1 2 3 4 5] @keep _ &(divisible? _ 2) sum_ || Same as: sum (@keep [1 2 3 4 5] &(divisible? _ 2))
There is also \pipe, which works like \case and \switch: it makes a function with a single implicit argument passed into pipe.
If you ever get stuck having to use a fluent API, pipe could help reduce the pain.
ignore
Mason will complain if you don't use a local, so just ignore it.
second = \a b ignore a b ignore second
pass
Mason doesn't expect certain expressions to be used as values and will complain.
If you want to use them as values anyway, use pass.
Foo = class get x || Changing state in a getter, very naughty! .y := 1 null f = new Foo || Mason doesn't expect a getter to do anything, so it complains if you take out `pass`. pass f.x f.y