An expression in Perl 6 is parsed as termish
things with infixish
things between them. A termish
is in turn defined as zero or more prefixish
things, followed by the term itself, followed by zero or more postfixish
things. The postfixish
takes in all of:
- Method calls ( like
.foo
)
- Postfix operators (like
++
)
- Postcircumfix operators (like the
[42]
in @a[42]
)
- Doing hyper (
>>
) on these to distribute them across a data structure
Since it just looks for zero or more of them, then you can freely interleave method calls and hash and array indexes. This explains why @weekdays.antipairs.hash{'Sunday'}
parses fine (and why @weekdays.antipairs.hash<Sunday>
would also work, and even @weekdays.antipairs.hash<Sunday>.say
is fine too).
As for the .
, the grammar simply accepts and ignores a .
before a postfix
or a postcircumfix
. Here's a slightly cut-down version of the parser, that I've annotated a bit to explain what the pieces are.
token postfixish {
<!stdstopper>
# If we're not in a string interpolation, allow unspace (that's
# where you write `\ ++`, for example, allowing spreading
# postfixish things over multiple lines).
[ <!{ $*QSIGIL }> [ <.unsp> | '\\' ] ]?
# Here we match the >> for doing a hyper. Note that it accepts
# but disregards a '.' before it. It's not captured at all and
# doesn't affect the code that is compiled.
[ ['.' <.unsp>?]? <postfix_prefix_meta_operator> <.unsp>?]**0..1
[
| <OPER=postfix>
# When there'd be no confusion with a method call, a '.' is
# also accepted and disregarded before a postfix operator
| '.' <?before \W> <OPER=postfix> ## dotted form of postfix operator (non-wordy only)
| <OPER=postcircumfix>
# Ditto here for recognized postcircumfixes
| '.' <?[ [ { < ]> <OPER=postcircumfix>
| <OPER=dotty>
| <OPER=privop>
]
}
Thus the .
means nothing at all in this context. The parser simply accepts it and then moves on to look for the thing it actually cares about at that point.
One other thing worth noting is that postfix and postcircumfix operators all work after a dotty term too, operating on $_
. Thus:
my @xs = 1..10;
.++ for @xs;
say @xs;
Will produce:
[2 3 4 5 6 7 8 9 10 11]
Here's a postcircumfix example:
my %h = a => 1, b => 2, c => 3;
say .<a> + .<c> given %h;
Which produces 4
.
Perl 6 syntax is generally designed to make it easy to shift code from one form to another, and accepting the .
in places even where it's not strictly needed eases that a little (so one could refactor to say %h1.<a> + %h2.<b>;
and the parser will be fine with it). It may also be helpful for learning purposes to consider %h<a>
short for %h.<a>
, which would in turn make .<a> given %h
a little less of a surprise.
The extra space afforded by the .
may also aid clarity, especially if one was to stack multiple postfixes, and could even - should a language extension for some reason decide to define some "interesting" terms or postfix operators - serve as a means to disambiguate.