TYCHO Search

Search documentation

    ↑ ↓ to move · Enter to open · Esc to close

    Appendix B — Keywords and contextual identifiers

    See §3.6 and §3.7 for the normative definitions.

    B.1 Reserved words

    These 43 words are reserved; none may be used as an identifier.

    and     bool    break   bytes   continue elif    else    enum
    f32     false   float   fn      for      handle  i8      i16
    i32     i64     if      in      inout    int     is      match
    not     null    or      or_else  or_return parallel ptr  return
    select  soa     spawn   string  struct   true    type    u8
    u16     u32     u64
    

    42 of the 43 are lexer keywords: the set is exactly keyword(), which never hands back an identifier token for one. soa is the exception — it lexes as an ordinary identifier and is reserved by the parser, which requires a [ after it in every expression position . The difference is invisible to a program and shows only in the diagnostic: soa := 5 is accepted at its declaration, and the next mention of the name dies with expected '[' after soa, so the binding is declarable and permanently unusable. It is listed here, with the reserved words, because that is what it costs a program — not under B.2, where it sat until 2026-09-02 under a heading promising the opposite.

    is is the variant test, for an enum, an Option or a Result (§19.8). It is reserved, not contextual: no .ty file in this tree used is as an identifier when it was added, so reserving it broke nothing, and an operator keyword shares its position with an ordinary name (x is y) in a way that pass, a whole statement, does not.

    Of these, the type keywords are int, float, bool, string, ptr, bytes, the fixed-width integers u8, u16, u32, u64, i8, i16, i32, i64, and f32. There is no while, char, or void keyword.

    B.2 Contextual identifiers

    Significant only in a specific position; ordinary identifiers elsewhere (a variable of the same name is unaffected).

    WordSignificant position
    package, import, extern, const, subscripttop-level declaration leader
    const, deletestatement leader (when followed by an identifier)
    where, channeltype / expression position. Both are genuinely unaffected as names: where := 5 and channel := 5 compile and print (measured 2026-09-02)
    Option, Result, Channeltype / expression position. These are not reserved either, but §3.5.1 bars every uppercase name from a run-time binding position, so Option := 5 is refused for the same reason Foo := 5 is; they remain legal as a user's own type name, which shadows the builtin
    voida Result's ok payload, and nowhere else (§5.3.6). Not a primitive type keyword: int/float/bool/string/… are lexed as keywords, void is an ordinary identifier the type parser recognises in that one slot, so a variable named void is still legal
    passa whole statement, and only then — the no-op (§14.1). pass := 0 and pass = pass + 1 stay ordinary code, which is why it is not reserved: two files in this tree already used the name
    packedimmediately before struct in a top-level declaration (§17.1a). Ordinary everywhere else, including as a field or variable name
    sinkparameter modifier
    yieldsubscript body
    freehandle body
    rangefor … in head — recognised only to refuse it since 2026-07-29 (§14.4)
    None, Some, Ok, Errvalue constructors
    _match wildcard pattern
    all builtin names (len, push, str, wait, …)resolved as calls; never reserved (§29)