txt: ## mop.md
  Metaobject protocol (MOP)
  
  Introspection and the Raku object system
  
  Raku is built on a metaobject layer. That means that there are objects (the *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:
  
  ```raku
  my $arr = [1, 2];
  say $arr.^name;   # OUTPUT: «Array␤»
  
  ```
  
  To get a more in-depth understanding of the metaobject for a `class`, here is an example repeated twice: once as normal declarations in Raku, and once expressed through the [metamodel](/type/Metamodel/ClassHOW):
  
  ```raku
  class A {
      method x() { say 42 }
  }
  
  A.x();
  ```
  
  corresponds to:
  
  ```raku
  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 `$obj.HOW`, where HOW stands for Higher Order Workings (or, *HOW the \*%@$ does this work?*).
  
  Here, the calls with `.^` are calls to the metaobject, so `A.^compose` is a shortcut for `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.
  
  # [Metamethods](#Metaobject_protocol_(MOP) "go to top of document")[§](#Metamethods "direct link")
  
  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 (since they are used conventionally for things like [phasers](/syntax/Phasers). This will avoid conflicts with any metamethods that may appear in future versions of the language.
  
  ## [WHAT](#Metaobject_protocol_(MOP) "go to top of document")[§](#WHAT "direct link")
  
  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 `42.WHAT` returns the [`Int`](/type/Int) type object.
  
  ## [WHICH](#Metaobject_protocol_(MOP) "go to top of document")[§](#WHICH "direct link")
  
  The object's identity value. This can be used for hashing and identity comparison, and is how the `===` infix operator is implemented.
  
  ## [WHO](#Metaobject_protocol_(MOP) "go to top of document")[§](#WHO "direct link")
  
  The package supporting the object.
  
  ## [WHERE](#Metaobject_protocol_(MOP) "go to top of document")[§](#WHERE "direct link")
  
  The memory address of the object. Note that this is not stable in implementations with moving/compacting garbage collectors. Use `WHICH` for a stable identity indicator.
  
  ## [HOW](#Metaobject_protocol_(MOP) "go to top of document")[§](#HOW "direct link")
  
  Returns the metaclass object, as in "Higher Order Workings".
  
  ```raku
  say (%).HOW.^name # OUTPUT: «Perl6::Metamodel::ClassHOW+{<anon>}␤»
  ```
  
  `HOW` returns an object of type `Perl6::Metamodel::ClassHOW` in this case; objects of this type are used to build classes. The same operation on the `&` sigil will return `Perl6::Metamodel::ParametricRoleGroupHOW`. You will be calling this object whenever you use the `^` syntax to access metamethods. In fact, the code above is equivalent to `say (&).HOW.HOW.name(&)` which is much more unwieldy. [`Metamodel::ClassHOW`](/type/Metamodel/ClassHOW) is part of the Rakudo implementation, so use with caution.
  
  ## [WHY](#Metaobject_protocol_(MOP) "go to top of document")[§](#WHY "direct link")
  
  The attached [Pod](/language/pod) value.
  
  ## [DEFINITE](#Metaobject_protocol_(MOP) "go to top of document")[§](#DEFINITE "direct link")
  
  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 `True` for instances and `False` for type objects.
  
  ## [VAR](#Metaobject_protocol_(MOP) "go to top of document")[§](#VAR "direct link")
  
  Returns the underlying [`Scalar`](/type/Scalar) object, if there is one.
  
  The presence of a [`Scalar`](/type/Scalar) object indicates that the object is "itemized".
  
  ```raku
  .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␤»
  ```
  
  Please refer to the [section on item context](/language/contexts#Item_context) for more information.
  
  # [Metaclass methods](#Metaobject_protocol_(MOP) "go to top of document")[§](#Metaclass_methods "direct link")
  
  Same as you can define object and class methods (which do not have access to the instance variables), you can define metaclass methods, which will work on the metaclass. These are conventionally defined by a caret (`^`) at the front of the method identifier. These metaclass methods might return a type object or a simple object; in general, they are only conventionally related to the metaobject protocol and are, otherwise, simple methods with a peculiar syntax.
  
  These methods will get called with the type name as first argument, but this needs to be declared explicitly.
  
  ```raku
  class Foo {
      method ^bar( Mu \foo) {
          foo.^set_name( foo.^name ~ "[þ]" );
      }
  }
  my $foo = Foo.new();
  say $foo.^name; # OUTPUT: «Foo␤»
  Foo.^bar();
  say $foo.^name; # OUTPUT: «Foo[þ]␤»
  
  ```
  
  This metaclass method will, via invoking class metamethods, change the name of the class it's been declared. Since this has been acting on the metaclass, any new object of the same class will receive the same name; invoking `say Foo .new().^name` will return the same value. As it can be seen, the metaclass method is invoked with no arguments; `\foo` will, in this case, become the `Foo` when invoked.
  
  The metaclass methods can receive as many arguments as you want.
  
  ```raku
  class Foo {
      method ^bar( Mu \foo, Str $addenda) {
          foo.^set_name( foo.^name ~ $addenda );
      }
  }
  Foo.new().^bar(  "[baz]" );
  my $foo = Foo.new();
  say $foo.^name;  # OUTPUT: «Foo[baz]␤»
  
  ```
  
  Again, implicitly, the method call will furnish the first argument, which is the type object. Since they are metaclass methods, you can invoke them on a class (as above) or on an object (as below). The result will be exactly the same.
  
  # [Structure of the metaobject system](#Metaobject_protocol_(MOP) "go to top of document")[§](#Structure_of_the_metaobject_system "direct link")
  
  **Note:** this documentation largely reflects the metaobject system as implemented by the [Rakudo Raku compiler](https://rakudo.org/), since the [design documents](https://design.raku.org/) are very light on details.
  
  For each type declarator keyword, such as `class`, `role`, `enum`, `module`, `package`, `grammar` or `subset`, there is a separate metaclass in the `Metamodel::` namespace. (Rakudo implements them in the `Perl6::Metamodel::` namespace, and then maps `Perl6::Metamodel` to `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, the role [`Metamodel::RoleContainer`](/type/Metamodel/RoleContainer) implements the functionality that a type can hold roles and [`Metamodel::ClassHOW`](/type/Metamodel/ClassHOW), which is the metaclass behind the `class` keyword, does this role.
  
  Most metaclasses have a `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 :-).
  
  ## [Bootstrapping concerns](#Metaobject_protocol_(MOP) "go to top of document")[§](#Bootstrapping_concerns "direct link")
  
  You might wonder how [`Metamodel::ClassHOW`](/type/Metamodel/ClassHOW) can be a class, when being a class is defined in terms of [`Metamodel::ClassHOW`](/type/Metamodel/ClassHOW), or how the roles responsible for role handling can be roles. The answer is *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 [NQP](/language/faq#What_language_is_NQP_written_in?). NQP has a primitive, class-like kind called `knowhow`, which is used to bootstrap its own classes and roles implementation. `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 [`Routine`](/type/Routine) object, or a bootstrap-attribute instead of [`Attribute`](/type/Attribute).
  
  ## [Composition time and static reasoning](#Metaobject_protocol_(MOP) "go to top of document")[§](#Composition_time_and_static_reasoning "direct link")
  
  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 *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 `.^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.
  
  ## [Power and responsibility](#Metaobject_protocol_(MOP) "go to top of document")[§](#Power_and_responsibility "direct link")
  
  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.
  
  ## [Power, convenience and pitfalls](#Metaobject_protocol_(MOP) "go to top of document")[§](#Power,_convenience_and_pitfalls "direct link")
  
  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 `my $x = 42` and then proceed to call methods on `$x`, most of these methods end up acting on the [integer](/type/Int) 42, not on the [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 `my $t = MyType; ... ; $t.^compose` you are composing the Scalar that the `$`-sigiled variable implies, not `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 ["do what I mean"](/language/glossary#DWIM) convenience that ordinary Raku code offers.
  
  # [Archetypes](#Metaobject_protocol_(MOP) "go to top of document")[§](#Archetypes "direct link")
  
  Typically, when multiple kinds of types share a property, it is implemented with a metarole to be mixed into their metaclasses. However, not all common properties of types can be implemented as mixins. Certain properties are common to various kinds of types, but do not share enough behavior to be possible to implement as mixins. These properties are known as *archetypes*.
  
  HOWs should provide an `archetypes` metamethod that takes no arguments and returns a `Metamodel::Archetypes` instance. This is used by the compiler to determine what archetypes are supported by metaobjects. The rest of this section will cover how each of the archetypes that exist in Rakudo work.
  
  ## [parametric](#Metaobject_protocol_(MOP) "go to top of document")[§](#parametric "direct link")
  
  Parametric types are incomplete types that may have an arbitrary number of type parameters. Here, type parameters refer to parameters of the type itself; these may be any object that a signature allows you to include, not just types alone. When parameterized with type arguments, parametric types will produce a more complete type of some sort.
  
  If a HOW supports parameterization, it should have the `parametric` archetype and must provide a `parameterize` metamethod. The `parameterize` metamethod must accept a metaobject and may accept any number of type parameters as arguments, returning a metaobject. For example, a `parameterize` metamethod that allows a type to be parameterized with any type arguments may have this signature:
  
  ```raku
  method parameterize(Mu $obj is raw, |parameters --> Mu)
  ```
  
  ### [Parametric classes and grammars](#Metaobject_protocol_(MOP) "go to top of document")[§](#Parametric_classes_and_grammars "direct link")
  
  Because of how the parametric archetype is implemented, it's possible for classes and grammars to be augmented with support for parameterization by giving them a `parameterize` metamethod, despite the type not having the `parametric` archetype. This can be useful in cases where the features of roles make them inappropriate to use for a parametric type.
  
  One scenario where parametric classes and grammars are useful is when parameterizations of a type should override or add multiple dispatch candidates to existing methods or regexes on the original parametric type. This is the case with parameterizations of types like [`Array`](/type/Array) and [`Hash`](/type/Hash), which may optionally be parameterized to mix in more type-safe versions of their methods that work with instances' values directly. In Rakudo, these are implemented as parametric classes using the metamethods provided by [`Metamodel::Mixins`](/type/Metamodel/Mixins) and [`Metamodel::Naming`](/type/Metamodel/Naming) to create a mixin of the metaobject given and reset its name before returning it. This technique can be used to write extensible grammars when used in combination with multi tokens, for instance:
  
  ```raku
  grammar Bot::Grammar {
      token TOP { <topic> || .+ }
  
      proto token topic {*}
      multi token topic:sym<command> { <command> <.ws> <command-args> }
  
      token command      { '$' <!ws>+ }
      token command-args { <!ws>+ % <.ws> }
  
      method ^parameterize(::?CLASS:U $this is raw, +roles) {
          my Str:D $name   = self.name: $this;
          my Mu    $mixin := $this.^mixin: |roles;
          $mixin.^set_name: [~] $name, '[', roles.map(*.^name).join(','), ']';
          $mixin
      }
  }
  
  role Greetings[Str:D $name] {
      multi token topic:sym<greeting> { ^ [ 'hi' | 'hello' | 'hey' | 'sup' ] <.ws> $name }
  }
  
  my constant GreetBot = Bot::Grammar[Greetings['GreetBot']];
  GreetBot.parse: 'sup GreetBot';
  say ~$/; # OUTPUT: «sup GreetBot␤»
  
  ```
  
  Parametric classes can also be used to simulate support for parameterization on other kinds. For instance, the [Failable](https://modules.raku.org/dist/Failable:cpan:KAIEPI) ecosystem module is a parametric class that produces a subset upon parameterization. While the module itself does some caching to ensure no more type objects are made than what's necessary, a more basic version of it can be implemented like so:
  
  ```raku
  class Failable {
      method ^parameterize(Failable:U $this is raw, Mu $obj is raw --> Mu) {
          Metamodel::SubsetHOW.new_type:
              name       => $this.^name ~ '[' ~ $obj.^name ~ ']',
              refinee    => Metamodel::Primitives.is_type($obj, Any) ?? Any !! Mu,
              refinement => $obj | Failure
      }
  }
  
  ```
  