Identifiers
An identifier names a binding, function, type, field, module or other declaration.
Identifier ::= IdentStart IdentContinue*
IdentStart ::= 'A'…'Z' | 'a'…'z' | '_'
IdentContinue ::= IdentStart | '0'…'9'
An identifier starts with an ASCII letter or an underscore and continues with letters, digits and underscores. It cannot be one of the 38 keywords.
let count = 1;
let x1 = 2;
let _scratch = 3;
let parsedValue = 4;
Rules
- ASCII only. Letters outside ASCII are not identifier characters:
let café = 1;stops witherror: unexpected character 'é' (U+00E9). Non-ASCII text belongs in literals and comments. - Case-sensitive.
count,CountandCOUNTare three different names. - No keywords. A keyword in a name's place is a syntax error, such as
error: expected a pattern after the binding keyword before 'while'forlet while = 1;. Fornoneandfailthe message names the problem directly:error: 'none' is a reserved keyword and cannot name a binding. - A lone
_is not a name. In a binding or pattern,_discards the value instead of naming it:let _ = Compute();. See Destructuring.
Primitive type names such as int, bool and char8 are not keywords; they are predefined type names, listed in the Primitive Types appendix. A few other words have a meaning only in a particular position; Keywords lists them.
Naming conventions
Rux code uses two spellings, and rux lint checks them:
| Spelling | Used for | Examples |
|---|---|---|
| PascalCase | Types (structs, enums, variants, unions, interfaces, aliases), enum and variant cases, functions and methods, constants, modules | HttpRequest, ParseInput, MaxSize, Io |
| camelCase | Local bindings, parameters, loop variables, fields, named variant fields | userId, fileName, red |
Neither spelling uses underscores. A name that breaks the convention compiles, and rux lint suggests the fix:
warning: function name 'parse_input' should be PascalCase
help: rename it to 'ParseInput'
warning: local variable name 'Result' should be camelCase
help: rename it to 'result'
The primitive types and their built-in aliases (int, float64, byte) are lower case by long tradition. A declaration that has to keep a foreign spelling — a C type name in a binding, say — can opt out with #Allow("naming.type") or #Allow("naming.const").