Guide
Classes and Structs
Values and objects, constructors, Destroy, Properties, Statics, Operators, Extend, and visibility.
A Struct is a value type, copied when it’s assigned or passed, and kept inline in arrays: what
a vector, a color, or a particle should be. A Class is a reference type, shared when it’s
assigned, reference-counted, and freed the moment its last reference goes: what an enemy, a
level, or a connection should be.
Structs
A Struct’s constructor takes its Fields in order, or by name. Its Methods read it, and ByRef
ones change it in place.
Import std.core
Struct Money
Field cents: Long
Method ToString(): String => "${cents / 100}.{cents % 100:02}"
Operator +(a: Money, b: Money): Money => Money(a.cents + b.cents)
Operator ==(a: Money, b: Money): Bool => a.cents == b.cents
ByRef Method Spend(amount: Money)
cents -= amount.cents
End Method
End Struct
Local wallet = Money(cents: 1050)
Local price = Money(325)
wallet.Spend(price)
Print(wallet.ToString(), (price + price).ToString(), price == Money(325))$7.25 $6.50 True
Classes
A Class’s New is its constructor and runs once per object. A Field with no zero, like a
non-nullable Class, has to be set by every New. Destroy runs when the object is freed.
Import std.core
Class Texture
Field path: String
Static Field loaded: Int = 0
New(path: String)
Self.path = path
loaded += 1
Print("load {path}")
End New
Method Destroy()
loaded -= 1
Print("free {path}")
End Method
End Class
Function ShowLevel()
Local wall = Texture("wall.png")
Local floor = Texture("floor.png")
Print("{Texture.loaded} textures loaded")
End Function
ShowLevel()
Print("{Texture.loaded} textures loaded")load wall.png load floor.png 2 textures loaded free floor.png free wall.png 0 textures loaded
Reference counting frees objects as soon as they’re unused, with no pause for a collector. Two
objects that refer to each other keep each other alive, so one side of a cycle, like a child’s
reference to its parent, is a Weak<T>; a debug build reports what leaked when the program ends.
Inheritance and Abstract
A Class Extends one base. Its Override Methods replace the base’s, Super calls the base’s,
and an Abstract Class or Method has to be filled in by a Class extending it.
Import std.core
Abstract Class Weapon
Field name: String
New(name: String)
Self.name = name
End New
Abstract Method Damage(): Int
Method Describe(): String => "{name} hits for {Damage()}"
End Class
Class Sword Extends Weapon
New()
Super.New("sword")
End New
Override Method Damage(): Int => 12
End Class
Class Bow Extends Weapon
Field arrows: Int = 2
New()
Super.New("bow")
End New
Override Method Damage(): Int => arrows > 0 ? 9 : 0
End Class
Local arsenal: Weapon[] = [Sword(), Bow()]
For w In arsenal
Print(w.Describe())
End For
Local second = arsenal[1]
If second Is Bow Then Print("a bow, with arrows")
Local bow = second As? Bow
Print(bow?.arrows ?? 0)sword hits for 12 bow hits for 9 a bow, with arrows 2
Extend
Extend adds Methods to a type that’s declared elsewhere, the built-ins and std’s included,
where its module is imported.
Import std.core
Extend Int
Method Squared(): Int => Self * Self
Method IsEven(): Bool => Self % 2 == 0
End Extend
Print(7.Squared(), 10.IsEven())49 True
Visibility
Everything in a file is private to it unless it says otherwise: Public is seen by every module
that imports it, and Package by the other files of its package. A Class’s Protected members
are seen by its file and by the Classes extending it.
Report an issue with this page or with FutureBlitz on GitHub.