Steffen Schwigon:
> Thomas Wittek <[EMAIL PROTECTED]>:
>> Maybe I just phenomenally misunderstood multi subs, but unless I
>> did, I can't see why we want to have subs when we can have multi
>> subs that can do the same and even more.
> 
> I understand your point and I confess I'm not sure.
> 
> At least there seems to be a visibility difference. In S12 I found
> those two sentences:
> 
> 1. [sub (or method) without a multi] [...] Only one such sub (or
>    method) can inhabit a given namespace, and it hides any outer subs
>    (or less-derived methods) of the same short name.
> 
> 2. [subs or methods declared multi] [...] It does not hide any
>    routines with the same short name but a different long name. In
>    other words, multis with the same short name can come from several
>    different namespaces provided their long names differ and their
>    short names aren't hidden by a non-multi declaration in some
>    intermediate scope.

So it looks like we can hide several multis with one sub:

  class Foo {
    multi method somesub (Int $arg) {
      "foo - Int: $arg".say
    }
    multi method somesub ($arg) {
      "foo - Scalar: $arg".say
    }
  }

  class Bar is Foo {
    multi method somesub ($arg) {
      "bar - Scalar: $arg".say
    }
  }

  class Baz is Foo {
    method somesub ($arg) {
      "baz - Scalar: $arg".say
    }
  }

  my $foo = Foo.new;
  my $bar = Bar.new;
  my $baz = Baz.new;

  $foo.somesub("scalar");
  #> foo - Scalar: scalar

  $foo.somesub(42);
  #> foo - Int: 42

  $bar.somesub("scalar");
  #> Bar - Scalar: scalar

  $bar.somesub(42);
  #I'd expect (but it doesn't do that, see text below):
  #using more specialized method from Foo
  #> Foo - Int: 42

  $baz.somesub("scalar");
  #> Baz - Scalar: scalar

  $baz.somesub(42);
  #_not_ using method from Foo as a non-multi sub overwrites it
  #> Baz - Scalar: 42

Interestingly $bar.somesub(42) doesn't use the multi method somesub (Int
$arg) of the class Foo (whose signature would provide a better match)
but it also uses multi method somesub ($arg) of the class Bar. So
actually every method that "somehow" matches in a less derived class
will be used. The more specialized methods of the more derived classes
are hidden, which I didn't expect (but what probably will be better
performance wise).

So I have no Idea why I would like to use a non-multi as even multis
hide the methods of more derived classes.

So even if there are cases where I want the non-multi-behavior (what
ever it really is), I think they are rare.
So I'd suggest that this behavior shouldn't be the default for all subs.
Instead I'd find it more intuitive if every sub is a multi sub by
default and that you could opt in the non-multi-behavior with a keyword
like "overriding", "dominant" or "preferred".

I think that the multi-behavior will be more common and thus should be
the default (as it is in most other languages). The probably less common
non-multi-behavior should require an additional keyword. Not vice versa.

Again, that's all written from my fairly small knowledge of the Perl6
language. But supposed that one, who starts learning Perl6, will also
have a small knowledge at the beginning, this concepts might confuse the
beginner, if he/she has to define extra keywords for a behaviour that's
probably more common and omitting the keywords will lead to a less
common behavior.

Maybe we should steal the ruby "principle of least surprise" here, which
I find a very good principle.

Maybe someone can enlighten me ;)

Best regards,
-Thomas

Reply via email to