One integer value type does not mean no structs: object does that job. It groups fields, carries methods and can have a constructor. Just remember the semicolon after the closing brace.
object Coord { var x, y; }; // 세미콜론에 주의 / mind the semicolon
object Triangle; // 먼저 이름만 알리기 / forward declaration
object Triangle {
var p: Coord * 5; // Coord 5개짜리 배열 멤버 / a member array of 5
var q;
var prev: selftype; // selftype = 자기 자신의 타입
function constructor(q) { this.q = q; }
function add(other: selftype) { this.q += other.q; }
};| Coord() | Construct, running the constructor if there is one. |
|---|---|
| (Coord * 5)() | A member array has to be made this way before it is indexed. |
| Coord.cast(v) | Reinterpret a plain variable as this type - needed after something like var e = a; loses the type. |
| a.copy() | A real copy. Plain assignment only makes another name for the same thing. |
| a.x, a.y = 5, 7; | Tuple assignment. |
| const a, b = List(), List(); | Two declarations on one line. |
| if (a) | An object converts to a condition: is it non-null. |
copy() is shallow. Scalar members are copied; object-valued members are shared. After b = a.copy(), writing b.p[0].x = 5 also makes a.p[0].x 5, while b.q = 2 leaves a.q alone. The official compiler test asserts exactly this.
Objects inherit, too: object B extends A { ... } adds its own fields to A's. It does not sit well with dynamic allocation, though.
alloc() does not work on every object. The official compiler test asserts that calling it on a class with eleven fields - ten from a base the test calls ObjectWithTooManyFields, plus one - is a compile error. The test does not say whether the limit is the field count or the inheritance, so if you plan to allocate a large or derived struct dynamically, try alloc() before the design depends on it.
Several conditions can be bundled with list and used as one: list(c1, c2, c3) is true when all three are. With the ternary operator it picks a value without stacking ifs.
Everything has an address