The review of SE-0451: Raw identifiers ran from October 24 through November 7, 2024, and the Language Steering Group has decided to accept this proposal with a revision to clarify the behavior regarding whitespace:
- The only whitespace that should be permitted in a raw identifier is
Pattern_White_Space
(which is stable), minus line/paragraph separators, and minus any already forbidden ASCII characters (like U+0009). That leaves{U+0020, U+200E, U+200F}
. - All other
White_Space
not in the set above, as defined in the Unicode 16.0.0 standard, should be forbidden.
Basing the allowed character set on a Unicode character property raises questions of how to manage the potential introduction of new White_Space
characters by future Unicode standards. The Language Steering Group feels that it is sufficient for now to fix the set of characters to the current Unicode definition. The current Swift implementation already assumes that all scalars outside of the BMP are identifier characters, for better or for worse. We see it as a valuable project to bring Swift's handling of Unicode more in line with the Unicode Consortium's recommendations (a subject that came up during the pitch and review of this proposal) regarding character sets, normalization, long-term source stability, and other issues with the current implementation, but this proposal does not need to individually be burdened with solving those problems.
During the review, reviewers raised concerns about backward deployment of code using raw identifiers, and how Swift runtimes, demanglers, and other tools on existing systems would process them. Existing versions of these tools are unaware of raw identifiers, and so demangling a declaration with special characters in its name could lead to misleading output, such as if a type were named `Array<Swift.Int>`
. The implementers believe there are solutions to these potential problems—by including the backticks as part of the declaration name when mangling or generating runtime metadata for a declaration, existing implementations will render the runtime names of that declaration with the included backticks, avoiding confusion or string collision problems when using demanglers or using stringified type names as values. The implementers have also found places in the Swift runtime where space characters (U+0020) are used as separators in runtime data structures, but they believe these structures can also be handled by transposing spaces in identifiers for a disallowed whitespace character (such as U+00A0). Future reflection API implementations will need to be aware of the implementation choices made here, but these choices should allow the implementation to exist compatibly with current Swift tooling.
Reviewers also considered lifting restrictions on identifiers further than proposed. In particular, many reviewers asked whether identifiers beginning with numeric digits could be supported without requiring backticks during member access:
struct Foo {
static var `123`: Int
static var `0cool`: Int
}
let bar = Foo.123 + Foo.0cool
Other reviewers noted that this might conflict with the use of .0
, .1
, etc. for tuple element access, though this doesn't seem like a fundamental limitation. Tuple element names do not undergo any processing as numbers (so x.0
must be accessed exactly as such, and not as x.00
, x.0x0
, or other possible integer literal spellings), but allowing identifiers to consist entirely of digits could create new ambiguities for labeled tuples, since in a tuple of the form
("foo", `0`: "bar")
, it would be ambiguous whether .0
referred to the first element by order or to the named element `0`
. There are potential solutions to these problems, such as disallowing digit-only labels in tuples, or only allowing them when they correspond to positional order. A separate proposal that deals with these issues could add support for identifiers beginning with digits to what this proposal already allows.
Thanks to everyone who participated in the review!