The Perl6 docs state "By default, parameters are bound to their argument and marked as read-only." But running the following code:
# Example 1
sub f1 ( $x ) { say $x.VAR.WHAT; say $x.WHAT; say $x }
f1(1);
yields:
(Scalar)
(Int)
1
while this code:
# Example 2
my $y := 1;
say $y.VAR.WHAT; say $y.WHAT; say $y;
yields:
(Int)
(Int)
1
It's the (Scalar)
in the output of Example1 that I do not understand: why is there a Scalar when I supposedly bind the Int 1 - argument to the identifier $x
? It seems as if the value 1
got "assigned" to $x
, rather than "bound".
Scalar
containers are also used to indicate items, and thus prevent flattening of them. In the absence of a type constraint, the implementation will conservatively wrap the incoming argument into a read-only Scalar
container to avoid any unexpected flattening taking place. Contrast this:
sub foo($x) {
my @a = $x;
say @a.elems;
}
foo([1,2,3]);
Which outputs 1 (no flattening), with a sigilless binding:
sub foo(\x) {
my @a = x;
say @a.elems;
}
foo([1,2,3])
Which outputs 3, since no item context is imposed. Were the Scalar
container not there, both would output 3.
In the presence of a non-Iterable
type constraint, this wrapping will be omitted. Thus writing:
sub f1(Int $x) {
say $x.VAR.WHAT;
say $x.WHAT;
say $x
}
f1(1)
Will output:
(Int)
(Int)
1
With .VAR
simply yielding identity on a non-container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With