What does the sigil .^ mean in Perl 6?
$foo.^bar
is effectively syntactic sugar for:
$foo.HOW.bar($foo)
In other words, call the bar
method on the meta-class of the $foo
object (.HOW
), and pass the object as the first parameter (so that the method knows the instance of the meta-class it should work on).
For instance:
say "Hello world".^name # Str
say "Hello world".HOW.name("Hello world"); # Str
See also: https://docs.raku.org/language/operators#index-entry-methodop_.%5E
TL;DR An elaboration of Liz's answer plus a bonus section, The HOW stack.
$foo.^bar
The .^bar
method call is "Higher order programming", code that works on $foo
as a programming construct.
is effectively syntactic sugar
^
is "syntax sugar" because it's short and simple and is a mnemonic for "higher".
$foo.HOW.bar($foo)
So, rather than $foo.^bar
calling the bar
method on the object assigned/bound to $foo
as usual for method calls, the bar
method is instead called on the object's HOW object (HOW is short for Higher Order Workings or How Objects Work).
The conventional wording for a HOW object is a "meta-object".
In other words, call the
bar
method on the meta-class of the$foo
object (.HOW
)
Afaik the .HOW
object is normally a concrete instance, not a class in the form of a type object. So the bar
method is normally called on a meta-object rather than on a meta-class.
Thus, for example, say 42.HOW
says Perl6::Metamodel::ClassHOW.new
with a .new
on the end, not (ClassHOW)
. So 42.^bar
would call .bar
on that meta-object.
and pass the object as the first parameter (so that the method knows the instance of the meta-class it should work on).
Afaik the object is passed so the method knows the object it must work on and it is very unlikely to be an instance of the meta-class.
For example in:
say "String".HOW.name("String"); # Str
"String"
is an instance of the Str
class, which is "String"
's .WHAT
, not its .HOW
.
.WHAT
is an object's type. To force some separation in your mind it may help to think of .HOW
as more like a type's "kind".
The HOW stack
class Person { method name { "Fred {rand}" } }
say Person.HOW.HOW.HOW.HOW.HOW.HOW.^name; # KnowHOW
say Person.HOW.HOW.HOW.^name; # KnowHOW
say Person.HOW.HOW.^name; # NQPClassHOW
say Person.HOW.^name; # Perl6::Metamodel::ClassHOW
say Person.^name; # Person
say Person.name; # Fred 0.7356364351848212
KnowHOW
Person
followed by 3 or more chained .HOW
s (and ending with a .^name
) displays KnowHOW
.
KnowHOW
is the "highest" if you will of the HOW objects, the one that determines the behavior of generic 6model objects.
KnowHOW
is agnostic regarding programming languages and object orientation. It isn't aware of things like classes or interfaces. It just "knows how" to do a few things with one of the most important being that it knows how to get a reference to its meta-object.
And in the unique case of KnowHOW
, its meta-object is itself. That's why the additional .HOW
calls after the third are effectively nops.
Given that "the buck stops" with KnowHOW
, it has to have an "on-the-metal" implementation. This is specific to a given backend such as the KnowHOW
code in MoarVM's 6model bootstrap.c code (documentation about its creation).
NQPClassHOW
At the next level, stepping closer to Perl 6, comes NQP, a programming language that was created to write programming languages including itself and Perl 6.
NQPClassHow
is part of NQP. It's a (meta) object that implements a "class" construct.
NQP isn't as sophisticated as Perl 6. (In fact it's basically a subset of it.) For example, the code say foo
will always work if foo
is a standard full P6 object. In contrast, it sometimes won't if foo
is an NQP object. Hence we have to write the first of these; the second won't work:
say Person.HOW.HOW.^name; # NQPClassHOW
say Person.HOW.HOW; # Died with X::Method::NotFound
Perl6::Metamodel::ClassHOW
Finally we arrive at a full P6 meta-class, part of the Rakudo Metamodel.
It's an instance of this class that's responding to the name
method call in say Person.^name
. That response is to display the name of the class of the object passed to it.