=begin pod :kind("Language") :subkind("Language") :category("fundamental")

=TITLE Metaobject protocol (MOP)

=SUBTITLE Introspection and the Raku object system

X<|MOP>
X<|Introspection>

Raku is built on a metaobject layer. That means that there are objects
(the I<metaobjects>) that control how various object-oriented constructs
(such as classes, roles, methods, attributes or enums) behave.

The metaobject has a practical benefit to the user when a normal object's type
is needed. For example:

=begin code
my $arr = [1, 2];
sub show-type($arr) {
    my $type = $arr.^name;
    say $type;
}
show-type $arr; # OUTPUT: «Array␤»
=end code

To get a more in-depth understanding of the metaobject for a C<class>, here is
an example repeated twice: once as normal declarations in Raku, and once
expressed through the L<metamodel|/type/Metamodel::ClassHOW>:

    class A {
        method x() { say 42 }
    }

    A.x();

corresponds to:

    constant A := Metamodel::ClassHOW.new_type( name => 'A' );  # class A {
    A.^add_method('x', my method x(A:) { say 42 });             #   method x()
    A.^compose;                                                 # }

    A.x();

(except that the declarative form is executed at compile time, and the latter
form does not).

The metaobject behind an object can be obtained with C<$obj.HOW>, where HOW
stands for Higher Order Workings (or, I<HOW the *%@$ does this work?>).

Here, the calls with C<.^> are calls to the metaobject, so C<A.^compose> is
a shortcut for C<A.HOW.compose(A)>. The invocant is passed in the parameter
list as well, to make it possible to support prototype-style type systems,
where there is just one metaobject (and not one metaobject per type, as
standard Raku does it).

As the example above demonstrates, all object oriented features are
available to the user, not just to the compiler. In fact the compiler just
uses such calls to metaobjects.

=head1 Metamethods

These are introspective macros that resemble method calls.

Metamethods are generally named with ALLCAPS, and it is considered good
style to avoid creating your own methods with ALLCAPS names.  This will avoid
conflicts with any metamethods that may appear in future versions of the
language.

=head2 X<WHAT|syntax,WHAT>

The type object of the type. This is a pseudo-method that can be overloaded
without producing error or warning, but will be ignored.


For example C<42.WHAT> returns the C<Int> type object.

=head2 X<WHICH|syntax,WHICH>

The object's identity value. This can be used for hashing and identity
comparison, and is how the C<===> infix operator is implemented.

=head2 X<WHO|syntax,WHO>

The package supporting the object.

=head2 X<WHERE|syntax,WHERE>

The memory address of the object. Note that this is not stable in
implementations with moving/compacting garbage collectors. Use C<WHICH> for
a stable identity indicator.

=head2 X<HOW|syntax,HOW>

Returns the metaclass object, as in "Higher Order Workings".

    say (%).HOW.^name # OUTPUT: «Perl6::Metamodel::ClassHOW+{<anon>}␤»

C<HOW> returns an object of type C<Perl6::Metamodel::ClassHOW> in this case;
objects of this type are used to build classes. The same operation on the C<&>
sigil will return C<Perl6::Metamodel::ParametricRoleGroupHOW>. You will be
calling this object whenever you use the C<^> syntax to access metamethods. In
fact, the code above is equivalent to C<say (&).HOW.HOW.name(&)> which is much
more unwieldy. L<Metamodel::ClassHOW|/type/Metamodel::ClassHOW> is part of the Rakudo implementation, so use with caution.

=head2 X<WHY|syntax,WHY>

The attached L<Pod|/language/pod> value.

=head2 X<DEFINITE|syntax,DEFINITE>

The object has a valid concrete representation. This is a pseudo-method that
can be overloaded without producing error or warning, but will be ignored.

Returns C<True> for instances and C<False> for type objects.

=head2 X<VAR|syntax,VAR>

Returns the underlying C<Scalar> object, if there is one.

X<|is itemized?>
The presence of a C<Scalar> object indicates that the object is "itemized".

    .say for (1, 2, 3);           # OUTPUT: «1␤2␤3␤», not itemized
    .say for $(1, 2, 3);          # OUTPUT: «(1 2 3)␤», itemized
    say (1, 2, 3).VAR ~~ Scalar;  # OUTPUT: «False␤»
    say $(1, 2, 3).VAR ~~ Scalar; # OUTPUT: «True␤»

=head1 Structure of the metaobject system

B<Note:> this documentation largely reflects the metaobject system as
implemented by the L<Rakudo Raku compiler|https://rakudo.org/>, since the
L<design documents|https://design.raku.org/> are very light on details.

For each type declarator keyword, such as C<class>, C<role>, C<enum>,
C<module>, C<package>, C<grammar> or C<subset>, there is a separate metaclass in the C<Metamodel::> namespace. (Rakudo implements them in the
C<Perl6::Metamodel::> namespace, and then maps C<Perl6::Metamodel> to
C<Metamodel>).

Many of these metaclasses share common functionality. For example
roles, grammars and classes can all contain methods and attributes, as well
as being able to do roles.  This shared functionality is implemented in
roles which are composed into the appropriate metaclasses. For example
L<role Metamodel::RoleContainer|/type/Metamodel::RoleContainer> implements
the functionality that a type can hold roles and
L<Metamodel::ClassHOW|/type/Metamodel::ClassHOW>, which is the metaclass
behind the C<class> keyword, does this role.

Most metaclasses have a C<compose> method that you must call when you're done
creating or modifying a metaobject. It creates method caches, validates things
and so on, and weird behavior ensues if you forget to call it, so don't :-).

=head2 Bootstrapping concerns

You might wonder how C<Metamodel::ClassHOW> can be a class, when being a
class is defined in terms of C<Metamodel::ClassHOW>, or how the roles
responsible for role handling can be roles. The answer is I<by magic>.

Just kidding. Bootstrapping is implementation specific. Rakudo does it by
using the object system of the language in which itself is implemented,
which happens to be (nearly) a subset of Raku known as
L<NQP|/language/faq#What_language_is_NQP_written_in?>. NQP
has a primitive, class-like kind called C<knowhow>, which is used to
bootstrap its own classes and roles implementation. C<knowhow> is built on
primitives that the virtual machine under NQP provides.

Since the object model is bootstrapped in terms of lower-level types,
introspection can sometimes return low-level types instead of the ones you
expect, like an NQP-level routine instead of a normal L<Routine|/type/Routine>
object, or a bootstrap-attribute instead of L<Attribute|/type/Attribute>.

=head2 Composition time and static reasoning

In Raku, a type is constructed as it is parsed, so in the beginning, it must
be mutable. However if all types were always mutable, all reasoning about them
would get invalidated at any modification of a type. For example the list of
parent types and thus the result of type checking can change during that time.

So to get the best of
both worlds, there is a time when a type transitions from mutable to
immutable. This is called I<composition>, and for syntactically declared
types, it happens when the type declaration is fully parsed (so usually when
the closing curly brace is parsed).

If you create types through the metaobject system directly, you must call
C<.^compose> on them before they become fully functional.

Most metaclasses also use composition time to calculate some properties like
the method resolution order, publish a method cache, and other house-keeping
tasks. Meddling with types after they have been composed is sometimes
possible, but usually a recipe for disaster. Don't do it.

=head2 Power and responsibility

The metaobject protocol offers much power that regular Raku code
intentionally limits, such as calling private methods on classes that don't
trust you, peeking into private attributes, and other things that usually
simply aren't done.

Regular Raku code has many safety checks in place; not so the metamodel. It
is close to the underlying virtual machine, and violating the contracts with
the VM can lead to all sorts of strange behaviors that, in normal code, would
obviously be bugs.

So be extra careful and thoughtful when writing metatypes.

=head2 Power, convenience and pitfalls

The metaobject protocol is designed to be powerful enough to implement the
Raku object system. This power occasionally comes at the cost of convenience.

For example, when you write C<my $x = 42> and then proceed to call methods on
C<$x>, most of these methods end up acting on the L<integer|/type/Int> 42, not
on the L<scalar container|/type/Scalar> in which it is stored. This is a piece
of convenience found in ordinary Raku. Many parts of the metaobject
protocol cannot afford to offer the convenience of automatically ignoring
scalar containers, because they are used to implement those scalar containers
as well. So if you write C<my $t = MyType; ... ; $t.^compose> you are
composing the Scalar that the C<$>-sigiled variable implies, not C<MyType>.

The consequence is that you need to have a rather detailed understanding of
the subtleties of Raku in order to avoid pitfalls when working with the MOP,
and can't expect the same L<"do what I mean"|/language/glossary#DWIM>
convenience that ordinary Raku code offers.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
