class creates a JavaScript class.
The class body consists of a constructor followed by method definitions.
You can use computed method names with (). This allows you to implement polys.
dimension = poly \
abstract
|| If superclass is missing, it will be Object, so this is just for show.
Point = class
construct x y
.x := x
.y := y
|| This implements the builtin `to-string` method.
|| Any expression can go within the parentheses;
|| if it's a method, its `symbol` property will be fetched.
(dimension) \
2
transpose! !\
{x y} = this
.y := x
.x := y
p = new Point 1 2
. dimension p
p.transpose!()
. p
static
A do block sets _ to the class and lets you do anything with it.
These usually aren't needed.
static defines static methods.
Constructor arguments prefixed with . become properties.
Point = class do _.origin := new _ 0 0 static || `empty` is a builtin poly (empty) \ .origin from-array \arr new Point arr[0] arr[1] construct .x .y pass . empty Point . Point.from-array [1 2]
The parts of a class must come in this order:
do, static, construct, then methods.
get / set
Getters and setters are also supported.
Point = class construct x y .x := x .y := y get len Math.sqrt + (** .x 2) ** .y 2 || Setter has `_` as its implicit parameter. set len scale = / _ .len .x := * .x scale .y := * .y scale p = new Point 3 4 . p.len p.len := 25 . p
my
When you don't intend a method to be used by others, just put my in front.
This works on all kinds, including get/set.
my doesn't actually do anything, but mason-doc is planned to use that information.
Bouncer = class allow-entry? \guess =? guess .password my get password 'swordfish _ = new Bouncer . _.allow-entry? 'abc123 || not actually secret . _.allow-entry? _.password
super
Class inheritance works the same as in JavaScript.
Declare the superclass by writing it after the class.
The constructor of an inherited class must call super
before attempting to access this.
You can use super in methods to call the same method on a super class,
or super.foo to call a different method.
Like in JavaScript, static methods are inherited.
A = class static get super-static 4 construct foo .foo := 0 super-method \ 1 overridden-method \x x B = class extends A construct || Illegal to write to `.bar` here super() || It's OK after you've called `super` .bar := 1 overridden-method \x + (super x) .bar other-method \x super.overridden-method x b = new B . b.foo . b.super-method() . b.overridden-method 1 . b.other-method 3 . B.super-static
record
If a class is just a container for various fields, there's an easy record syntax.
Point = class x y || Can still put method definitions here. get transpose new Point .y .x (new Point 1 2).transpose
The class will inherit from the Record trait (traits are up next!).
Records can be pattern matched. They also have a default 'toString.