mason

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:

&.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] &not
. @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