syntax identifiers

Documentation for syntax identifiers assembled from the following types:

language documentation Syntax

From Syntax

(Syntax) identifier identifiers identifiers

Identifiers are grammatical building blocks that may be used to give a name to entities/objects such as constants, variables (e.g. Scalars) and routines (e.g. Subs and Methods). In a variable name, any sigil (and twigil) precedes the identifier and does not form a part thereof.

constant c = 299792458;     # identifier "c" names an Int 
my $a = 123;                # identifier "a" in the name "$a" of a Scalar 
sub hello { say "Hello!" }# identifier "hello" names a Sub

Identifiers come in different forms: ordinary, extended, and compound identifiers.

Ordinary identifiers

An ordinary identifier is composed of a leading alphabetic character which may be followed by one or more alphanumeric characters. It may also contain isolated, embedded apostrophes ' and/or hyphens -, provided that the next character is each time alphabetic.

The definitions of "alphabetic" and "alphanumeric" include appropriate Unicode characters. Which characters are "appropriate" depends on the implementation. In the Rakudo/MoarVM Raku implementation alphabetic characters include characters with the Unicode General Category value Letter (L), and the underscore _. Alphanumeric characters additionally include characters with the Unicode General Category value Number, Decimal Digit (Nd).

# valid ordinary identifiers: 
x
_snake_oil
something-longer
with-numbers1234
don't-do-that
piece_of_π
駱駝道              # "Rakuda-dō", Japanese for "Way of the camel" 
# invalid ordinary identifiers: 
42                 # identifier does not start with alphabetic character 
with-numbers1234-5 # embedded hyphen not followed by alphabetic character 
is-prime?          # question mark is not alphanumeric 
x²                 # superscript 2 is not alphanumeric (explained above) 

Extended identifiers

It is often convenient to have names that contain characters that are not allowed in ordinary identifiers. Use cases include situations where a set of entities shares a common "short" name, but still needs for each of its elements to be identifiable individually. For example, you might use a module whose short name is Dog, while its long name includes its naming authority and version:

Dog:auth<Somebody>:ver<1.0>  # long module names including author and version 
Dog:auth<Somebody>:ver<2.0>
 
use Dog:auth<Somebody>:ver<2.0>;
# Selection of second module causes its full name to be aliased to the 
# short name for the rest of # the lexical scope, allowing a declaration 
# like this. 
my Dog $spot .= new("woof");

Similarly, sets of operators work together in various syntactic categories with names like prefix, infix and postfix. The official names of these operators often contain characters that are excluded from ordinary identifiers. The long name is what constitutes the extended identifier, and includes this syntactic category; the short name will be included in quotes in the definition:

infix:<+>                 # the official name of the operator in $a + $b 
infix:<*>                 # the official name of the operator in $a * $b 
infix:«<=»                # the official name of the operator in $a <= $b 

For all such uses, you can append one or more colon-separated strings to an ordinary identifier to create a so-called extended identifier. When appended to an identifier (that is, in postfix position), this colon-separated string generates unique variants of that identifier.

These strings have the form :key<value>, wherein key or value are optional; that is, after the colon that separates it from a regular identifier, there will be a key and/or a quoting bracketing construct such as < >, « » or [' '] which quotes one or more arbitrary characters value.[1]

# exemplary valid extended identifiers: 
postfix:<²>               # the official long name of the operator in $x² 
WOW:That'sAwesome
WOW:That's<<🆒>>
party:sweet<16>
 
# exemplary invalid extended identifiers: 
party:16<sweet>           # 16 is not an ordinary identifier 
party:16sweet
party:!a                  # ...and neither is !a 
party:$a                  # ...nor $a 

In an extended identifier, the postfix string is considered an integral part of the name, so infix:<+> and infix:<-> are two different operators. The bracketing characters used, however, do not count as part of it; only the quoted data matters. So these are all the same name:

infix:<+>
infix:<<+>>
infix:«+»
infix:['+']
infix:('+')

Similarly, all of this works:

my $foo:bar<baz> = 'quux';
say $foo:bar«baz»;                               # OUTPUT: «quux␤» 
my $take-me:<home> = 'Where the glory has no end';
say $take-me:['home'];                           # OUTPUT: «Where [...]␤» 
my $foo:bar<2> = 5;
say $foo:bar(1+1);                               # OUTPUT: «5␤» 

Where an extended identifier comprises two or more colon pairs, their order is generally significant:

my $a:b<c>:d<e> = 100;
my $a:d<e>:b<c> = 200;
say $a:b<c>:d<e>;               # OUTPUT: «100␤», NOT: «200␤» 

An exception to this rule is module versioning; so these identifiers effectively name the same module:

use ThatModule:auth<Somebody>:ver<2.7.18.28.18>
use ThatModule:ver<2.7.18.28.18>:auth<Somebody>

Furthermore, extended identifiers support compile-time interpolation; this requires the use of constants for the interpolation values:

constant $c = 42;  # Constant binds to Int; $-sigil enables interpolation 
my $a:foo<42> = "answer";
say $a:foo«$c»;    # OUTPUT: «answer␤» 

Although quoting bracketing constructs are generally interchangeable in the context of identifiers, they are not identical. In particular, angle brackets < > (which mimic single quote interpolation characteristics) cannot be used for the interpolation of constant names.

constant $what = 'are';
my @we:<are>= <the champions>;
say @we:«$what»;     # OUTPUT: «[the champions]␤» 
say @we:<$what>;
# Compilation error: Variable '@we:<$what>' is not declared 

Compound identifiers

A compound identifier is an identifier that is composed of two or more ordinary and/or extended identifiers that are separated from one another by a double colon ::.

The double colon :: is known as the namespace separator or the package delimiter, which clarifies its semantic function in a name: to force the preceding portion of the name to be considered a package/namespace through which the subsequent portion of the name is to be located:

module MyModule {               # declare a module package 
    our $var = "Hello";         # declare package-scoped variable 
}
say $MyModule::var              # OUTPUT: «Hello␤»

In the example above, MyModule::var is a compound identifier, composed of the package name identifier MyModule and the identifier part of the variable name var. Altogether $MyModule::var is often referred to as a package-qualified name.

Separating identifiers with double colons causes the rightmost name to be inserted into existing (see above example) or automatically created packages:

my $foo::bar = 1;
say OUR::.keys;           # OUTPUT: «(foo)␤» 
say OUR::foo.HOW          # OUTPUT: «Perl6::Metamodel::PackageHOW.new␤» 

The last lines shows how the foo package was created automatically, as a deposit for variables in that namespace.

The double colon syntax enables runtime interpolation of a string into a package or variable name using ::($expr) where you'd ordinarily put a package or variable name:

my $buz = "quux";
my $bur::quux = 7;
say $bur::($buz);               # OUTPUT: «7␤»