Skip to content

Subscripts ​

Implementation status: built-in collection / String subscripts Implemented; custom subscript declarations Partially implemented (Phase 40/41 get/set MVP); KeyPath arrays / Optional paths Implemented (Phase 46–48)

A subscript is the syntactic sugar obj[i] for accessing collection elements. SYX supports both built-in type subscripts (such as Array, String, Dictionary) and custom subscript declarations (get/set).

Array Subscripts ​

swift
let items = [10, 20, 30]
print(items[0])                            // 10
items[1] = 99
print(items)                               // [10, 99, 30]
OperationStatus
arr[i] readImplemented
arr[i] = v writeImplemented
Out of boundsRuntime R003 (including negative indices; ≠ nil / silent)
Negative indexR003 (same path as out of bounds)

Source: crates/syx-driver/tests/fixtures/differential/suite1/array_index.sy

Dictionary / Object Subscripts ​

swift
func main() {
    let m = ["a": 1, "b": 2]
    print(m["a"])                          // 1 (Optional<Int>)
    m["c"] = 3
    print(m.count)                         // 3

    let obj: Object = { "name": "SYX", "version": 110 }
    print(obj["name"])                     // "SYX"
}

Optional return: dict[k] always returns Optional<V>, because at runtime "the key does not exist" cannot be distinguished from "the value is nil".

String Subscripts ​

swift
let s = "abc"
print(s[0])                                // "a" (grapheme Character)
print(s[1])                                // "b"
Index semanticsInt grapheme offset (Phase 84; ADR-227)
ComplexityO(n) for a single random access (.nth grapheme iteration; ≠ Swift's opaque Index)
Return typegrapheme Character
Out of boundsR003 (including negative indices; ≠ an empty Character)

History: before Phase 84 indexing counted Unicode scalars, so combined emoji could be split. Phase 84+ aligns with grapheme clusters; ADR-227 pins the honest O(n) Int offset (not opaque Index GA).

For complete String character semantics, see Chapter 4, Strings and Characters.

Custom subscript Declarations ​

A type may declare a subscript (MVP since Phase 40/41, with complete get/set):

swift
class Matrix {
    var data: Array<Array<Int>>
    init(rows: Int, cols: Int) {
        var d: Array<Array<Int>> = []
        for _ in 0..<rows {
            var row: Array<Int> = []
            for _ in 0..<cols { row.append(0) }
            d.append(row)
        }
        self.data = d
    }

    subscript(row: Int, col: Int) -> Int {
        get { return self.data[row][col] }
        set { self.data[row][col] = newValue }
    }
}

func main() {
    let m = Matrix(rows: 2, cols: 2)
    m[0, 0] = 1
    m[1, 1] = 4
    print(m[0, 0])                         // 1
    print(m[1, 1])                         // 4
}
ElementDescription
subscript(params) -> TSubscript declaration
get { … }Read (Phase 40 GA)
set { … }Write (Phase 41 MVP)
newValueImplicit parameter inside the set block

Status: custom subscript declarations are Partially implemented (Phase 40/41); the recommended usage is "get required, set optional".

Single-Parameter Subscripts ​

swift
class Grid {
    var cells: Array<String> = ["a", "b", "c", "d"]
    subscript(i: Int) -> String {
        get { return self.cells[i] }
        set { self.cells[i] = newValue }
    }
}

func main() {
    let g = Grid()
    print(g[0])                            // "a"
    g[0] = "x"
    print(g[0])                            // "x"
}

KeyPath Subscripts (Phase 46–48) ​

A KeyPath is a type-safe object reference path:

swift
let arr = [1, 2, 3]

// Array subscript KeyPath
let kp = \Array<Int>.[0]
print(kp(arr))                             // 1

Property KeyPaths ​

swift
class Person {
    let name: String
    init(name: String) { self.name = name }
}

let p = Person(name: "Alice")
let nameKp = \Person.name
print(nameKp(p))                           // "Alice"

Optional KeyPaths (Phase 46) ​

swift
class Box {
    let value: Int?
    init(value: Int?) { self.value = value }
}

let b = Box(value: 42)
let vKp = \Box.value?.description          // Optional path
print(vKp(b))                              // "42"

KeyPath Array Subscripts ​

swift
let arr = [1, 2, 3]
print((\Array<Int>.[0])(arr))              // 1

Test: lang/array_subscript_check.rs

Subscripts vs. Methods ​

NeedChoose
Array / Dictionary / Object element accessBuilt-in subscript
Indexed access on a custom typeCustom subscript
Type-safe reference pathsKeyPath
Dynamic string field accessObject["key"]

Complete Example ​

swift
class SafeArray {
    private var data: Array<Int> = []
    private var maxIndex: Int = 0

    func append(_ x: Int) {
        self.data.append(x)
        self.maxIndex = self.data.count - 1
    }

    subscript(i: Int) -> Int? {             // get-only
        get {
            if i < 0 { return nil }
            if i > self.maxIndex { return nil }
            return self.data[i]
        }
    }

    subscript(safe i: Int, default d: Int) -> Int {
        get {
            if i < 0 { return d }
            if i > self.maxIndex { return d }
            return self.data[i]
        }
    }
}

func main() {
    var a = SafeArray()
    a.append(1)
    a.append(2)
    a.append(3)

    print(a[0])                             // Optional(1)
    print(a[10])                            // nil
    print(a[safe: 10, default: -1])         // -1
}

Multi-label parameters: subscripts support multiple parameters (subscript(row: Int, col: Int)) and multiple labels (subscript(safe i: Int, default d: Int)).

Diagnostics ​

CodeTriggerFix
S004Subscript parameter / return type mismatchFix it
P001subscript syntax errorCheck the get/set blocks
R003Array / String subscript out of boundsCheck the index range

Differences from Swift ​

SwiftSYX
Grapheme-cluster subscriptsImplemented (since Phase 84)
Custom subscript get/setPartially implemented (Phase 40/41)
Full KeyPath surfacePartially implemented (\Type.prop / \Type.[i] / \Type?.prop are supported; dynamic member lookup is not implemented)
subscript(dynamicMember:)Not implemented
Protocol subscript requirementsPartially implemented
subscript labels / multiple labelsImplemented

Next chapter → Inheritance

See also → Language Reference: Declarations · Language Reference: Expressions · Chapter 4, Strings and Characters · Chapter 11, Properties

SYX · Apache-2.0