(The following describes a proposed extension to Perl 6, methodical scoped
operators or methodicals for short.  It is written in the present tense for
simplicity but should be understood as the future conditional.)

Normally, when you write a method call, the definition of the method is
entirely in the domain of the receiver's class:

    $object.make-me-a-sandwich;  # $object gets to decide what this means

However, this is not always how things work.

    $object.WHAT;  # Larry says that WHAT should return the protoobject

WHAT, WHENCE, postcircumfix:<[ ]>, and similar operators have semantics
(although not implementation) defined by the language itself. Currently, Perl 6
fakes this by having all values inherit from Any or Mu or Cool, which define
the basic, overridable versions of these method-like operators. This cheat
actually works pretty well in a homogeneous environment, but it fails if we have
to consider objects from outside Perl 6.

    $parrot-array.WHAT;  # Method WHAT not found for invocant of type ...

The problem here is that scopes are conflated - WHAT is defined by the
language, which is approximately a lexical scope, while methods on an object
are in some entirely different scope.

A methodical is an operator which syntactically behaves as a method but is
subject to scoping rules.  Methodicals are defined using the ordinary method
keyword, qualified with my or our.  (TODO: This seems the most natural syntax
to me, but it conflicts with existing usage.  Which is more worth having on
it?)  Methodicals do not need to be declared in classes, but they should
generally have declared receiver types.

    {
        my method make-me-a-sandwich(Num:) { ... }

        2.make-me-a-sandwich; # calls our method

        "ham".make-me-a-sandwich; # either an error, or method dispatch
    }

    2.make-ma-a-sandwich; # ordinary method dispatch

The primary use case for methodicals is naturally in the setting.  Many of the
methods which are currently defined on lower-level types could become
methodicals and they would be available on all values, in any code compiled
within the Perl 6 setting, without polluting the referencing environments of
non-Perl 6 code in the same object environment.

    my method WHAT($thing) { ... }

Rakudo already uses something very much like an ad-hoc direct implementation of
methodicals to handle postcircumfix operators.

Methodicals are also useful in user code where the most natural phrasing of a
calculation is as a property of a system type, for instance from the Mandelbrot
Advent example:

    my method mandel(Complex:) {
        my $z = 0i;
        for ^$max-iterations {
            $z = $z * $z + self;
            return 1 if ($z.abs > 2);
        }
        return 0;
    }

Since methodicals do not pollute global referencing environments, and do not
compromise encapsulation, MONKEY_TYPING is not needed here.

A methodical defined inside a class functions much like a private method.
There may be something interesting here, but I'm not entirely sure what.

There are two natural implementations of methodicals in terms of other language
features.  First, it is possible to treat methodicals as ordinary methods
(monkey typing under the hood), but with generated names; the true name is
bound to the program name only within the correct scope.  If possible, the
methods should be treated as anonymous, accessible only though an opaque name
object.  Care must be taken to prevent incorrect exposure of private fields and
methods.

Alternatively, a methodical can be desugared to a multi sub with the same scope
as the methodical itself, changing statically named method calls into calls to
the methodical.  This gives reflection invisibility and privacy for free, but
may require more work to get the multi call semantics exactly right.

Thoughts?

-Stefan

Attachment: signature.asc
Description: Digital signature

Reply via email to