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 .HOWs (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.

Tags:

Raku