Dictionaries

ton.dict user = {name: "kuro", age: 22}
print(user["name"])     // kuro
user["age"] = 23
user["city"] = "paris"   // adds a new key
print(keys(user))         // [name, age, city]
print(has(user, "age"))    // true

Dict keys are always strings (see Known limitations): a bare identifier key (name: ...) is treated as its own name, and a non-identifier key needs a string literal ("first name": ...). Reading a missing key returns nil rather than erroring; writing to a new key adds it. keys()/values() iterate in insertion order.

Spread (...) merges another dict's entries into a literal in place — a later entry (spread or not) overrides an earlier one with the same key, keeping that key's original position rather than moving it to the end:

ton.dict base = {a: 1, b: 2}
ton.dict merged = {...base, b: 99, c: 3}   // {a: 1, b: 99, c: 3}

The spread expression must itself be a dict — spreading anything else is a runtime error.

Dot access (since beta-2.0.0) — d.key reads a key (or nil) and d.key = value sets it, exactly like d["key"]. Use brackets for keys that aren't valid names or are computed.

ton.dict cfg = {port: 8080}
cfg.host = "localhost"
cfg.port += 1
print(cfg.port, cfg.host)            // 8081 localhost
print(cfg.missing?.value)            // nil (optional chaining)

Destructuring — pick keys into variables, optionally renaming them with key: name, and collect the rest with ...rest:

ton.let {name, age: years, ...rest} = {name: "rusher", age: 30, city: "paris"}
print(name, years, rest)             // rusher 30 {city: paris}

for key, value in d { ... } walks the pairs; items(d), dict(pairs), merge(a, b) and remove(d, key) complete the toolbox (see Built-in native functions).

Edit this page on GitHub