### 6.1.6 Brackets and Braces

Binding more tightly are the various brackets, and braces: which can be used as infix, prefix, or postfix operators, or as terms (such as tuples and set constructors).

secondary ::= primary | [ primary ] sc-bracketed [ : sort-name ] [ primary ]
sc-bracketed ::= [ [ term-list ] ] | { [ term-list ] }
| \< [ term-list ] \> | \langle [ term-list ] \rangle
term-list ::= term [ , term ] ...


The meaning and sort of such a term are determined by the trait in which the overloading of this syntax is defined.

With brackets, one can write a secondary such as a[3], or a2[3,4], which may be useful for various kinds of arrays (see section 11.7 Array Types) and pointers (see section 11.8 Pointer Types). One can also use brackets to write a secondary such as [2,b], which the LSL syntax for tuples.

With braces, one can write a secondary such as {} or {i}, for various sets or other containers traits, or something like range{10,11,12}. When dealing with overloaded LSL operators, such as set braces, it may sometimes be necessary to give the sort of such a term. For example, if in a certain specification one were dealing with types SetOfInt and SetOfChar, one might want to write {}:SetOfInt to be clear about which empty set is meant by {}. If the C++ types in question were named Set<int> and Set<char>, one would have to use a typedef to give simple names for the Larch/C++ syntax in this context (see section 5.2.5 Typedef Specifiers).