HaloO Stevan,

you wrote:
I hope that .isa, .does and .meta are normal Method subtypes and *not*
slots on some implementation objects/structures.


I am not sure I understand this. Can you elaborate?

With pleasure!

OK, where do I start? ...

The origin of OO stems from the need to organize data structures
and code that deals with them in a way that prevents glitches.
The idea is to somehow put the functions into the data. This is
the syntactical idea in the most prominent OO-languages Java and
C++. Typical implementaion is through pointer tables that the
instances carry around. This approach breaks down when it comes
to multi methods.

Type theory started from the other end. Actually, since data
manipulation is difficult to model there where only pure functions
or lambda expressions and their application. A type system starts
out with primitive types and then introduces so-called arrow types
or function types written in Perl6 as :( ::A --> ::B ) these days.

With first-class functions or closures the question arises "when is an
arrow type a subtype of another?". This question is answered differently
for Subs and Methods! For subs the ::A of the subtype has to be a
*supertype* of the ::A of the supertype. In plain english a function
has to accept a wider or equal range of types if it shall replace another. For methods the invocant part of ::A goes with the outer subtype relation
of the methods. The rest works as with subs. After the most specific method
from a set of applicable ones is selected it can be bound to or curried on
the invocant and temporarily becomes a sub. This binding of the invocants
is called single or multiple dispatch depending on the arity of the invocant
type. BUT it is *no* lookup inside the invocant!

To summarise: a free method just states its required type of
invocants that it can handle and the dispatcher ensures two things:
1) that the invocant type matches
2) that the most specific method in scope is bound to it
This implies that you can taylor an invocant if you know the constraints.
Classes and roles are a very convenient means to automate this tayloring.
As such they are a very powerfull implementation device.

BTW, the above also explains my difficulties with Damians metric
dispatch because you can decide if ::A.does(::B) but defining a
measure from how far away ::A does that is beyond me.

Coming back to .isa, .does and .meta I just wanted to say that I hope
they are not implemented as slots on some data structure of your meta
model but as self-contained parts of Perl6 The Language.

Here is an example of a 2D distance method

  role Point
  {
    has Num $.x;
    has Num $.y;
  }
  method distance( Point $a, Point $b --> Num )
  {
     return sqrt( ($a.x - $b.x)**2 - ($a.y - $b.y)**2);
  }

Now comes the not-yet-Perl6 part:

  Complex does Point where { $.x := $.real; $.y := $.imag }

  Array[Num] does Point
    where { $.size >= 2 or fail;
            $.x := @.values[0]; $y := @.values[1] }

a hash might just work with the right keys and value types

  my %g = { x => 2.4, y => 3.14 }; # %g.does(Point) is true
  my %h = { x => 0.8, y => 1.22 };

  say distance( %g, %h );

  my @a = (0, 3);

  my Complex $c = (4,3);

  say distance( @a, $c );
  say distance( %h, @a );
  say distance( (0,3), (2,6) ); # works if List.does(Array)
  say distance( [1,1], [2,4] ); # works because Ref[Array].does(Array)
  say distance( $c, [0,1,2,3] ); # works because [0,1,2,3].does([0,1])
  # etc.
--
$TSa.greeting := "HaloO"; # mind the echo!

Reply via email to