Raku Behind the Docs All corners
Reading the code · Chapter 3

Whitespace, Terms and Blocks

Where a space, a newline or a brace changes what the parser sees, from subscripts that must touch their term to blocks that turn out to be hashes.

28 corners · 42 examples

In most languages spaces can go wherever they read well. In Raku they cannot, because Raku uses whitespace to tell apart things that look alike. After a term, [ touching the term is a subscript and [ after a space is an operator; f(1) and f (1) pass different arguments; a } at the end of a line ends the statement. A few rules explain most of it: a postfix must touch its term, a term followed by whitespace expects an infix operator, and a closing brace followed by a newline behaves like a semicolon.

This chapter goes through those rules, then through the smaller decisions the parser makes at the level of single tokens: which braces are hashes, which words are identifiers, what a colonpair may contain, where comments and Pod begin, and what counts as a number.

3.1 { … } is a Hash only when it looks like one

A pair of braces in term position is either a Block or a hash composer. The compiler decides by looking inside: empty braces are a Hash, and so are braces holding a single comma list whose first element is a pair or a % variable. Anything else is a Block.

my %opts = x => 1;
say {}.^name;
say { a => 1, b => 2 }.^name;
say { :a(1), :b(2) }.^name;
say { %opts, b => 2 }.^name;
say { a => 1; }.^name;
say { "a", 1 }.^name;
say { (a => 1), (b => 2) }.^name;
Reference output
Hash
Hash
Hash
Hash
Hash
Block
Block

A trailing semicolon does not change the verdict, but a first element of any other kind does: "a", 1 is a list of two strings, and a parenthesised pair is a parenthesised expression. Using the topic $_ or a placeholder variable anywhere inside, or adding a second statement, makes the braces a Block even when they start with a pair. %( … ) always builds a Hash.

say { 3 => 4, :b($_) }.^name;
say { a => $^x }.^name;
say { say "hi"; a => 1 }.^name;
say %( 3 => 4, :b($_) ).^name;
say %().^name;
Reference output
Block
Block
Block
Hash
Hash

The third Block is never called, so nothing says "hi".

3.2 A block that only returns a pair is a Hash, so map refuses itTrap

The rule of the previous corner applies to the argument of map too. A block meant to return a constant pair is a hash composer, and map receives a Hash instead of code:

say (1..2).map({ "k" => 1 }).raku;
Reference output
(nothing)
and on standard error
Cannot map a Range using a Hash
Did you mean to add a stub ({ ... }) or did you mean to .classify?
  in block <unit> at example.raku line 1

A block that mentions $_ is a Block. When the pair does not need the topic, a semicolon straight after the opening brace forces a Block; when each element should become a hash, say so with %( … ):

say (1..2).map({ "k$_" => 1 }).raku;
say (1..2).map({; "k" => 1 }).raku;
say (1..2).map({ %( k => $_ ) }).raku;
Reference output
(:k1(1), :k2(1)).Seq
(:k(1), :k(1)).Seq
({:k(1)}, {:k(2)}).Seq

3.3 A brace that touches a term is a subscriptTrap

{ directly after a term opens a hash subscript, whatever the term is. A condition written without a space before its block therefore swallows the block as a subscript, and the statement is left without one:

my $x = 1;
if ($x){ say "yes" }
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Missing block (whitespace needed before curlies taken as a hash subscript?)
at example.raku:3
------> <BOL><HERE><EOL>
    expecting any of:
        block or pointy block

($x){ … } subscripts the parenthesised value, so the compiler reads to the end of the file looking for the block of the if. The same happens with if $x{, for @a{ and when 'x'{: a string literal takes a subscript as readily as a variable. After the parameter of a pointy block, -> $i{ is read as a shape declaration, and the compiler reports that shapes are not implemented. Where no term precedes the brace, as in sub f(){ … } or else{ … }, no space is needed.

3.4 A } that ends a line ends the statementTrap

A closing brace followed by a newline terminates the statement, as if a semicolon stood there. This is what lets a block-shaped statement such as if or sub go without a ;, but it applies to every brace, including the end of a do block or a hash composer on the right of an assignment. An operator on the next line then starts a new statement:

my $x = do { 1 }
    + 2;
say $x;
my $h = { a => 1, b => 2 }
    .keys.sort;
say $h.^name;
Reference output
1
Hash
and on standard error
WARNINGS for example.raku:
Useless use of "+ " in expression "+ 2" in sink context (line 2)
The editor’s engine, Raku++, prints something else here
1
Seq

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

+ 2 becomes a statement of its own, and the compiler warns that its value is thrown away. .keys.sort becomes a method call on $_, and nothing warns: $h holds the Hash, not its sorted keys. A comment after the brace does not help; the statement still ends at the newline. Keep the operator on the brace's line, or end the line with an unspace, }\.

3.5 Inside brackets, a line-ending } separates elements like ;Trap

Parentheses and square brackets hold statements, and a semicolon between statements makes each one an element. A } at the end of a line counts as that semicolon, so a list of hashes written one per line needs no commas, and an operator at the start of a line starts a new element:

say [ { a => 1 }; { b => 2 } ].raku;
say [
    { a => 1 }
    { b => 2 }
].raku;
say (
    { a => 1 }
    + 0
).raku;
Reference output
[{:a(1)}, {:b(2)}]
[{:a(1)}, {:b(2)}]
({:a(1)}, 0)
The editor’s engine, Raku++, prints something else here
(nothing on standard output; standard error says:)
===SORRY!=== Parse error at line 4: expected ] (got '{')
      4 |     { b => 2 }
  at example.raku:4

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A comma at the start of the next line, as in ({ a => 1 } newline , 2), is not a way out: a statement cannot begin with a comma, and the compiler reports a bogus statement.

3.6 A keyword touching ( is a function callTrapQuirk

if, unless, while, until, for, loop, given, when, with and without are keywords only when no ( follows them directly. With the parenthesis touching, each one is read as a call to a sub of that name, and the compiler refuses with two messages:

my $x = 1;
if($x) { say "yes" }
Reference output
(nothing)
and on standard error
===SORRY!===
The word 'if' is interpreted as a 'if()' function call. Please use
whitespace instead of parentheses.
at example.raku:2
------> if<HERE>($x) { say "yes" }
Unexpected block in infix position (two terms in a row)
at example.raku:2
------> if($x)<HERE> { say "yes" }

For loop( the advice reads "whitespace around the parentheses", since the parentheses of a C-style loop are required. The statement modifier form, say "yes" if($x), fails with a plain "Missing semicolon". The words that continue an if or with chain are not checked at all:

my $x = 0;
if $x { say "if" } elsif($x == 0) { say "elsif with parentheses" }
Reference output
elsif with parentheses

3.7 A space after a sub's name moves the parentheses into the argumentTrap

f(…) with the parenthesis touching the name is a call whose argument list is inside the parentheses. f (…) with a space is a call without parentheses, and (…) is only the start of its first argument. Everything after it, up to the end of the list, joins in:

say sqrt(16) + 9;
say sqrt (16) + 9;
sub f(|c) { "f" ~ c.list.raku }
say f(1), 2;
say f (1), 2;
say f (1, 2);
say f [1, 2];
Reference output
13
5
f(1,)2
f(1, 2)
f((1, 2),)
f([1, 2],)

sqrt (16) + 9 is the square root of 25. f (1), 2 passes two arguments, while f (1, 2) passes one: a list. f [1, 2] passes an Array; with a sub that takes no arguments it fails at run time with "Too many positionals passed".

3.8 Parentheses touching the name end the call

The other side of the same rule: once say(…) has its parentheses, the call is complete, and what follows applies to its result. A method call after it goes to the value say returned, and a second parenthesised group is a term with no operator before it:

say (1, 2).elems;
say(1, 2).elems;
Reference output
2
12

The second line prints 12, the two arguments joined, and then asks True, the value of say, for its number of elements.

say(1) (2);
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Two terms in a row
at example.raku:1
------> say(1)<HERE> (2);
    expecting any of:
        infix
        infix stopper
        statement end
        statement modifier
        statement modifier loop
The editor’s engine, Raku++, prints something else here
1

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A subscript touching the name also ends the call: f[1] calls f with no arguments and indexes the result, which for a sub that requires one argument is the compile-time error "Calling f() will never work".

3.9 A sub called without parentheses takes the whole comma list

A sub name followed by a space is a list operator: its arguments run to the end of the comma list, which is usually the end of the statement. Inside a say, a named function without parentheses therefore takes every argument after it. When the sub's signature cannot accept that many, the compiler notices before the program runs:

say sqrt 4, 9;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Calling sqrt(Int, Int) will never work with signature of the proto ($, *%)
at example.raku:1
------> say <HERE>sqrt 4, 9;
The editor’s engine, Raku++, prints something else here
2

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A sub that accepts any number of arguments shows where the list ends:

sub f(|c) { "f" ~ c.list.raku }
say f 1, 2;
say (f 1), 2;
say f 1 ~ "!";
Reference output
f(1, 2)
f(1,)2
f("1!",)

Each argument is a whole expression, so 1 ~ "!" is concatenated before f sees it. The same looseness is behind two corners of the precedence chapter: a reduction takes everything to its right, and say 0 or … prints 0.

3.10 A postfix must touch its term

Subscripts, argument lists and method calls are postfixes, and a postfix is recognised only directly after its term. Separated by a space, .<a> is not a method call, and the compiler says which detached forms it allows:

my %h = a => 1;
say %h .<a>;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Malformed postfix call (only basic method calls that exclusively use a dot can be detached)
at example.raku:2
------> say %h .<HERE><a>;
The editor’s engine, Raku++, prints something else here
1

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A "basic method call" is .name, which with a space before the dot is the dotty infix of the precedence chapter. A bracket after a space is worse off. After a term the parser expects an infix, and [ in that position opens a bracketed infix such as [+] in 1 [+] 2:

my @a = 10, 20;
say @a [0];
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Missing infix inside []
at example.raku:2
------> say @a [<HERE>0];
    expecting any of:
        bracketed infix
        infix
        infix stopper
The editor’s engine, Raku++, prints something else here
[10 20]

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

3.11 A backslash unspace lets a postfix stand apart

A backslash followed by whitespace is an unspace: the parser skips it and the whitespace as if neither were there. It may span lines and include comments, so it can move a postfix onto the next line. A dot is also allowed before any subscript, and a space is allowed after the dot of a method call.

my @a = 10, 20;
my %h = a => 1;
say @a\ [1];
say %h\ .<a>;
say "abc"\   # a comment inside the unspace
    .uc;
say @a.[0..1];
say %h.{"a"};
say "abc". uc;
Reference output
20
1
ABC
(10 20)
1
ABC

The unspace works for argument lists too: f\ (1), 2 calls f with the single argument 1, exactly like f(1), 2.

3.12 A line that starts with a dot continues at dotty-infix precedenceTrap

A method chain can be continued on the next line by starting the line with .method. That works because a dot after whitespace is the dotty infix, and like any infix it has a precedence: tighter than .., looser than a postfix. On a parenthesised term it chains as expected; on a bare range it binds to the endpoint:

my @r = (1..5)
    .grep(* > 2)
    .map(* * 10);
say @r;
my @s = 1..5
    .map(* * 10);
say @s;
Reference output
[30 40 50]
and on standard error
Seq objects are not valid endpoints for Ranges
  in block <unit> at example.raku line 5

The second statement is 1 .. (5.map(* * 10)), and a Seq cannot end a range. Parenthesise the term the chain starts from.

3.13 .& calls any sub as if it were a method

A postfix .&name calls the sub &name with the term as its first argument. It sits on the method-postfix level, so it chains with real method calls and can take further arguments; the sub can also be an anonymous block.

sub double($n) { $n * 2 }
sub join-with($a, $sep, $b) { "$a$sep$b" }
say 5.&double;
say 5.&double.&double;
say "a".&join-with("-", "b");
say (1, 2, 3).map(*.&double);
say 4.&({ $_ + 1 });
Reference output
10
20
a-b
(2 4 6)
5

3.14 ++ needs a container, and a method call returns a value

Postfix ++ is on the level just below the method postfixes, so $x.abs++ increments the result of .abs. That result is a plain value, and the error is not the "cannot modify" of an assignment but a failed dispatch: every candidate of postfix:<++> wants a writable argument.

my $x = -3;
try { $x.abs++ };
say $!.^name;
try { $x.abs = 5 };
say $!.^name;
$x++;
say $x;
Reference output
X::Multi::NoMatch
X::Assignment::RO
-2
The editor’s engine, Raku++, prints something else here
X::Assignment::RO
X::Assignment::RO
-2

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

3.15 Spacing does not group operandsTrap

Whitespace around an infix operator is decoration. It cannot make an operator bind tighter or looser, however strongly the layout suggests it:

say 1+2 * 3;
my $s = 1 ... 3;
say $s;
Reference output
7
1
and on standard error
Potential difficulties:
    Useless use of ... in sink context
    at example.raku:2
    ------> my $s = 1 ...<HERE> 3;

my $s = 1 ... 3 is (my $s = 1) ... 3, because item assignment is tighter than the sequence operator, and the compiler warns that the sequence is thrown away. Likewise 1 .. 5 xx 2 is 1 .. (5 xx 2) and dies because a Seq is not a valid range endpoint. The levels are in the precedence chapter.

3.16 A hyphen or apostrophe joins an identifier only before a letterTrap

Identifiers may contain - and ', as long as each is followed by a letter. $a-b is therefore one variable, not a subtraction, while $a-1 and $a-$b subtract, because a digit or a sigil cannot continue a name.

my $a = 10;
my $b = 3;
my $a-b = "one variable";
say $a-b;
say $a - $b;
say $a-1;
my $don't = "fine";
say $don't;
Reference output
one variable
7
9
fine

A subtraction of a sub call from a variable runs into this rule. The compiler reads one name and does not find it:

my $i = 10;
sub n { 3 }
say $i-n;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Variable '$i-n' is not declared. Perhaps you forgot a 'sub' if this was
intended to be part of a signature?
at example.raku:3
------> say <HERE>$i-n;

3.17 A < touching a term opens a subscriptTrap

< directly after a term is the start of a < > subscript, and after a space it is the less-than operator. In term position it starts a word quote. The parser settles the question by the space alone:

my $x = 3;
say $x < 5;
say $x <5;
say <a b>;
Reference output
True
True
(a b)

When the < touches the term, the parser looks for the closing > of the subscript. If there is none it asks for whitespace ("Whitespace required before < operator"); if there is one later on the line, it takes everything in between as the subscript's words:

my ($x, $y) = 3, 4;
say $x<5 && $y>2;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Two terms in a row
at example.raku:2
------> say $x<5 && $y><HERE>2;
    expecting any of:
        infix
        infix stopper
        postfix
        statement end
        statement modifier
        statement modifier loop

$x<5 && $y> is $x{"5", "&&", '$y'}, and the 2 after it has no operator.

3.18 A sub named after a type, even X, needs its &Trap

A name followed by ( is a call, unless the name is a type: then it is a coercion. X is a type, the package that holds the exception classes such as X::AdHoc, so a helper sub called X is never reached that way:

sub X($a) { "my X got $a" }
say X(1);
Reference output
(nothing)
and on standard error
Impossible coercion from 'Int' into 'X': no acceptable coercion method found
  in block <unit> at example.raku line 2
The editor’s engine, Raku++, prints something else here
my X got 1

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

Without parentheses, X 1 is two terms in a row. The sub still exists as &X, and the same holds for a sub named after any other type:

sub X($a) { "my X got $a" }
sub Int($a) { "my Int got $a" }
say &X(1);
say Int("42").raku;
say &Int("42");
say (1, 2) X (3, 4);
Reference output
my X got 1
42
my Int got 42
((1 3) (1 4) (2 3) (2 4))
The editor’s engine, Raku++, prints something else here
my X got 1
"my Int got 42"
my Int got 42
((1 3) (1 4) (2 3) (2 4))

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

X is the only single capital letter with this problem. Subs named Z or R do not clash with the metaoperators, which need an operator right after the letter, and the cross operator X keeps working between two lists.

3.19 => quotes the word on its left only on the same lineTrap

The fat arrow turns an identifier on its left into a string key. It looks for that identifier across spaces and tabs only. Across a newline, or a comment, or an unspace, the word is an ordinary name, here a call to a sub a that would take => 1 as its argument:

my %h = a
    => 1;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Preceding context expects a term, but found infix => instead.
at example.raku:2
------>     =><HERE> 1;
The editor’s engine, Raku++, prints something else here
(nothing: Raku++ accepts the program and prints nothing)

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A quoted key, 'a' newline => 1, is a string already and may be followed by the arrow on the next line.

3.20 A colonpair's number must be a plain integerQuirk

:3days is the pair days => 3, a form meant for adverbs such as :2nd. The number must be an unsigned integer made of digits. :2<101> is not a pair at all but a number in base 2, and an underscore after the digits starts the key:

say (:3days).raku;
say (:0days).raku;
say :2<101>;
say (:1_000days).raku;
Reference output
:days(3)
:days(0)
5
:_000days(1)
The editor’s engine, Raku++, prints something else here
(nothing on standard output; standard error says:)
===SORRY!=== Parse error at line 2: Malformed radix number
      2 | say (:0days).raku;
  at example.raku:2

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

:1_000days is the pair _000days => 1: an underscore may begin an identifier, and the digits stop before it. A decimal point sends the parser to the radix form and fails there; a sign is not accepted at all (:-1day is a "Bogus statement"):

say (:2.7days).raku;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Malformed radix number
at example.raku:1
------> say (:2<HERE>.7days).raku;
    expecting any of:
        number in radix notation
The editor’s engine, Raku++, prints something else here
:days(2.7)

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

3.21 A colonpair's value must touch its name

The value of a colonpair is a bracketed term directly after the name: parentheses for an expression, angle brackets for words, square brackets for an Array and braces for a Hash or a Block, decided as in the first corner.

say (:foo(1)).raku;
say (:foo<bar>).raku;
say (:foo[1, 2]).raku;
say (:foo{ a => 1 }).raku;
say (:foo{ $_ * 2 }).value.^name;
Reference output
:foo(1)
:foo("bar")
:foo([1, 2])
:foo({:a(1)})
Block

With a space, :foo is complete on its own, the pair foo => True, and the value becomes a second term:

say (:foo 1).raku;
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Two terms in a row
at example.raku:1
------> say (:foo<HERE> 1).raku;
    expecting any of:
        infix
        infix stopper
        statement end
        statement modifier
        statement modifier loop

:foo (1) fails the same way.

3.22 # starts a comment outside quotes; #` and a bracket embed one

A # outside any quote comments out the rest of the line. Inside a string or a word quote it is an ordinary character. # followed by a backtick and an opening bracket starts an embedded comment, which ends at the matching closing bracket, may span lines, and can sit in the middle of an expression. Doubled brackets let the comment contain single ones.

say "a # not a comment";
say 1 #`( an embedded comment ) + 2;
say 3 #`{{ doubled { braces } inside }} + 4;
say 5 #`[
    spans lines
] + 6;
say <x #y z>;
Reference output
a # not a comment
3
7
11
(x #y z)

A backtick that is not followed by a bracket is an error rather than a line comment, while #( and # `( with a space are ordinary line comments:

say 1; #`not a bracket
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
Opening bracket required for #` comment
at example.raku:1
------> say 1; #`<HERE>not a bracket

3.23 #| and #= attach documentation to a declaration

#| before a declaration and #= after it are declarator comments: the text is kept and returned by .WHY on the declared object. #|( with a bracket spans lines, and the lines are joined with single spaces.

#| Adds one.
sub inc($x) { $x + 1 }
sub dec($x) { $x - 1 }  #= Subtracts one.
#|( Doubles,
    across two lines. )
sub double($x) { $x * 2 }
say &inc.WHY;
say &dec.WHY;
say &double.WHY;
Reference output
Adds one.
Subtracts one.
Doubles, across two lines.
The editor’s engine, Raku++, prints something else here
Adds one.
Subtracts one.
Doubles,
    across two lines.

Measured with Raku++ 4.0.1-245-ge1e6e3a1-modified (2026-09-28) arm64-darwin. The book shows the reference compiler’s output; the editor runs Raku++ compiled to WebAssembly.

A #| comment attaches to the next declaration, not to the next line. Ordinary statements in between do not stop it:

#| Meant for nothing in particular.
say "a statement";
sub later { }
say &later.WHY;
Reference output
a statement
Meant for nothing in particular.

3.24 Pod directives must start a line

A line whose first non-blank character is = followed by a word such as begin, for or comment starts a Pod block, which the compiler skips. Indentation before the = is allowed:

say 1;
=begin comment
say 2;
=end comment
say 3;
  =begin pod
  indented is fine too
  =end pod
say 4;
Reference output
1
3
4

After code on the same line, the = of =begin is read as an infix operator where a term was expected, and the compiler suspects the Pod mistake:

say 1; =begin comment
say 2;
=end comment
Reference output
(nothing)
and on standard error
===SORRY!=== Error while compiling example.raku
An error in Pod syntax is suspected. Perhaps an '=end comment' marker
was forgotten or was improperly nested? Alternately, an infix '=' was
seen where a term was expected.
at example.raku:1
------> say 1; =<HERE>begin comment

3.25 A line starting =word then a space is Pod, even mid-statementTrap

Any identifier works as the name of an abbreviated Pod block, not only the standard ones, and such a block runs to the next blank line. A continued assignment whose = touches a sub name followed by a space is therefore Pod, and so is every line after it up to a blank one:

sub answer($n) { 42 + $n }
say "before";
my $x
    =answer 1;
say "x is $x";
Reference output
before

Nothing after before is printed and nothing warns: lines 4 and 5 are documentation, and my $x is a complete statement ending at the end of the file. =answer(1); and =answer; are code, because the name is not followed by whitespace. A space after the = avoids the question.

3.26 Every Unicode space is whitespace, but some do not split words

Between tokens, any character with the Unicode space property is whitespace: the no-break space U+00A0, the em space U+2003, the ideographic space U+3000 and the rest, and a line separator such as U+2028 ends a line. Word quoting is the exception: < > does not split at the three no-break spaces (U+00A0, U+2007, U+202F), which keep the words on either side together, although .words does split there.

use MONKEY-SEE-NO-EVAL;
say EVAL "1\x[A0]+\x[A0]2";
say EVAL "my\x[3000]\$x = 3;\x[2028]\$x * 2";
say EVAL("<a\x[A0]b c>").map(*.chars);
say EVAL("<a\x[2003]b c>").map(*.chars);
say "a\x[A0]b".words.elems;
Reference output
3
6
(3 1)
(1 1 1)
2

The example builds its programs with EVAL so that the invisible characters are visible in the source. In the third line the word quote keeps a, the no-break space and b together as one three-character word; with an em space the same quote has three words. A zero-width space, U+200B, is not whitespace, and a program containing one between tokens does not compile.

3.27 Numeric literals allow _ between digits, and e makes a Num

An underscore may separate digits anywhere, one at a time, including just after a radix prefix such as 0x. A literal with a decimal point is a Rat, even without a leading digit; a literal with an exponent is a Num. A leading zero does not make a number octal, and the compiler says so.

say 1_000_000;
say 0x_ff;
say 0b1010, " ", 0o17, " ", 0d19;
say .5.^name;
say 1e3.raku;
say 1E3.^name;
say 0777;
Reference output
1000000
255
10 15 19
Rat
1000e0
Num
777
and on standard error
Potential difficulties:
    Leading 0 has no meaning. If you meant to create an octal number, use
    '0o' prefix; like, '0o777'. If you meant to create a string, please add
    quotation marks.
    at example.raku:7
    ------> say 0777<HERE>;

Doubled underscores (1__000) are refused with "Only isolated underscores are allowed inside numbers", a trailing one (1000_) is simply confusing to the parser, and the radix prefixes are lowercase only: 0XFF does not parse.

3.28 A decimal point needs a digit after itTrap

.5 is a number, but 5. is not: a dot after digits is the start of a method call unless another digit follows. On its own at the end of a number it is an error, and before a letter it calls a method, so 1.e3 is not a thousand:

say 1.e3;
Reference output
(nothing)
and on standard error
No such method 'e3' for invocant of type 'Int'
  in block <unit> at example.raku line 1

say 5.; fails at compile time with "Decimal point must be followed by digit". Write 5.0 and 1.0e3, or 1e3.