Subscripts

A subscript lets you call an instance like a function — container(key) — to index into it. It's how Array, Dictionary, and friends are wired up; you can wire your own types the same way.

struct Grid { var width: Int var cells: [Int] // row-major: cell (row, col) lives at row * width + col subscript(row: Int, col: Int) -> Int { get { self.cells(row * self.width + col) } set { self.cells(row * self.width + col) = newValue; } } } var g = Grid(width: 3, cells: [0, 0, 0, 0, 0, 0]); g(1, 2) = 7; let value = g(1, 2); // 7

A subscript declaration looks a lot like a computed variable: get and an optional set (with implicit newValue). Parameters follow the same labeling rules as functions — single-name parameters are positional (g(1, 2)); give a parameter two names to require a label at the call site.

Multiple subscripts

You can declare more than one — different label sets pick different subscripts, like overloaded functions:

<!-- sample: continue --> struct Point { let x: Int let y: Int } extend Grid { subscript(at point: Point) -> Int { get { self.cells(point.y * self.width + point.x) } set { self.cells(point.y * self.width + point.x) = newValue; } } } println("\(g(at: Point(x: 2, y: 1)))"); // same cell, different syntax

Read-only subscripts

Drop the set block to make the subscript read-only:

<!-- sample: continue --> extend Grid { subscript(rowSum row: Int) -> Int { get { var total = 0; for col in 0..<self.width { total = total + self.cells(row * self.width + col); } total } } } println("\(g(rowSum: 1))"); // 7

Assigning to a read-only subscript is a compile error.

Note: subscripts are called with parentheses (obj(key)), not square brackets — square brackets in Kestrel are reserved for type parameters.

Note: avoid assigning through chained subscripts (e.g. g.cells(row)(col) = v on a [[Int]] field) — nested subscript assignment is currently broken in 0.16 and slated for a fix in 0.17. Reads through chains are fine; for writes, keep the setter a single subscript deep, as the row-major Grid above does.