kind

Kind in Kind

Sometimes you'll see a funny little ^ in a method call:

say Mu.^name; # OUTPUT:
# Mu

This does not make for a name call on Mu. As is the case with ! and private methods, the ^ is special and significant; like .=, it sugars. This makes for a name call on the HOW of Mu with Mu as its first argument:

say Mu.HOW.name: Mu; # OUTPUT:
# Mu

The name metamethod has to come from somewhere. Provided we're working with Rakudo, in this case, the HOW of Mu originates from the Metamodel::ClassHOW metaclass, which does the Metamodel::Naming metarole. Mu's behaviour as a type originates from the state of its HOW, which carries a type of its own. This is not a true Raku type; it is implemented in untyped nqp, as is the case with most of the Metamodel package.

Oversimplifying typechecks like this internally is a valid strategy in my view. If a value's type is already inferrable from prior signatures, there's no need to keep checking it. The problem is we need to actually be able to make such a check to begin with in order to enforce type safety in the greater stratums of the MOP at its most external layer. We have a greater capacity to deal with this from the ecosystem, though we make a vow to Rakudo in doing so.

Consider a scenario where we want to check for a HOW that can make a fully-featured package declarator, e.g. module. module is relatively simplistic as far as a HOW goes: it can carry a :name, :ver, :auth, and :api, as well as a WHY and WHO:

#|[ A versioned module for the ecosystem. ]
module Eco:auth<zef:Kaiepi>:ver<0.0.1>:api<1> { }

This forwards a :$name, :$ver, :$auth, and :$api to the new_type method on the HOW specified by the module package declarator, which is Metamodel::ModuleHOW, which sets its WHO to a fresh Stash, WHY being set a little later. This information is all stored with API provided by Metamodel::Naming, Metamodel::Documenting, Metaomdel::Versioning, and Metaomdel::Stashing. If we want to check for a HOW that's compatible with such a declarator, we could perhaps use a Junction of these metaroles, excluding the Metamodel::Stashing that parametric roles lack:

say Mu.HOW ~~ Metamodel::Naming & Metamodel::Documenting & Metamodel::Versioning; # OUTPUT:
# Cannot find method 'find_method' on object of type NQPParametricRoleHOW
#   in any  at gen/moar/stage2/NQPCORE.setting line 527
#   in block <unit> at kind.raku line 1

Or not. Rakudo's metaroles aren't actually the Mu type expected of all objects in Raku, and we're forwarding them to a core typecheck. These are nqp parametric roles; they do not inherit, and do not pun, and thus don't carry Mu! While we can forward metaobjects like these around nqp-style with Mu and liberal application of is raw. Thus is the impotus for my Kind class:

use Kind:api<2>;
say Mu ~~ Kind[Metamodel::Naming & Metamodel::Documenting & Metamodel::Versioning]; # OUTPUT:
# True

This is a parametric typechecker for HOWs of metaobjects that can thread junctions essentially.

Kind v1.0.0

Typechecking based on kinds

Authors

  • Ben Davies

License

Artistic-2.0

Dependencies

Test Dependencies

Provides

  • Kind

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.