2. Source text
2.1 Encoding#
Source is UTF-8. A byte-order mark is accepted only at byte zero. NUL bytes, invalid UTF-8, the Unicode bidirectional format characters (U+202A to U+202E and U+2066 to U+2069), and characters confusable with ASCII punctuation are rejected with a diagnostic naming the line and column. CRLF is normalised for parsing. These rules are Luce Base's.
Identifiers are ASCII: a letter or _, then letters, digits or _, at most 128 bytes. The standalone _ is the pattern wildcard. Unicode is fully supported inside text and comments.
2.2 Layout#
A statement suite after : is either one simple statement on the same line or a newline followed by a block indented by exactly four spaces. Type and interface bodies always use the indented form. Tabs are rejected. A same-line suite holds no compound statement and no second statement. Inside brackets, newlines and indentation do not count. A file may nest suites, brackets and operators a hundred levels deep, and a chain of calls or operators may be three hundred links long; deeper nesting is a diagnostic, never a crash.
if cached: return result
if image.width > maximum:
let scale = maximum / image.width
image.resize(scale)2.3 Comments and documentation#
# starts a comment to the end of the line. A run of ## lines directly above a declaration is its documentation, read by luce doc. A comment is never a directive.
2.4 Names and scope#
Names are case-sensitive. Scope is static and lexical: a module, then a function, then each suite. A name is visible from its binding to the end of its suite. Shadowing is an error: a local may not reuse the name of another visible local, parameter, or top-level declaration, and an import may not be shadowed. Conventions: snake_case for functions, bindings, fields and enum cases; CapitalCase for types; UPPER_CASE for nothing.
The core names are the language's own functions and types: assert, error, print, trap, int, float, bool, str, bytes, unit, never, list, map, set, Error, ErrorCode, Weak, task. No module-level declaration, import, local or parameter takes one. A member (a field, a method, an enum case) may take any name but a reserved word, a core name too, since it is only reached through its value or its type: report.print, Token.str. What else the language provides is in its standard modules (§6.8), so abs, min or input is an ordinary name.
2.5 Reserved words#
and as break catch class continue elif else enum false for from func if import in
interface is let match none not or pub recover return self spawn struct test true type
var wait while withinit, deinit, close, and main are ordinary names with a meaning in one position each.