Hello,

I am forking this off the "Perl 6 OO and bless" thread since that seems to have gotten bogged down in what it all means to Perl 5 interoperability. This was not really my intent with the original thread, but I think it is still a fruitful discussion so I will re- make my original point here with more detail.

First I need to establish a few things on which my argument rests.

So, S02 says that Perl 6 is an OO engine. Which means that a hash is not a literal "thing" but an instance of the class ^Hash. This means that a hash now has methods which can be called on it, and inherits from ^Object.

Because @Larry does not want the OO-ness of the language to get in the way of doing ones job, all the methods of ^Hash are either transformed into pseudo-built-in-functions using macros (see the Hash/ delete/UnaryForm part of S29), or would be aliased as multi-subs which dispatch using MMD.

Take this (very simplified) pseduo-code for &exists:

  method Hash::exists (^Hash %h: Any $label) return Bool {
      %h{$label} ?? bool::true !! bool::false
  }

And lets assume that a macro has been written to make it callable in the built-in function style which will transform this:

  exists %h{'foo'}

Into this:

  %h.exists('foo');

Now, what happens when we bless a hash.

  class Foo {
      method new ($class: %params) {
          $class.bless(%params);
      }
      method bar ($self:) { ... }
  }

The result of Foo.new is an instance of ^Foo. In Perl 5, the hash would be tagged with the package name it was blessed into, but it would still be a hash reference, only now you could also call methods on it. This *won't* work the same in Perl 6 though. This is because, what is blessed is not a literal "hash", but an instance of ^Hash. If we follow the Perl 5 logic, then we can now call methods on this blessed hash, but we cannot use the hash built-in functions since they are just macro transformations into method calls. Take this code example:

  my $foo = Foo.new({ one => 1, two => 2 });
  exists $foo{'one'}; # this will not work

The reason this the above code will not work is because "exists $foo {'one'}" will be transformed by the macro to "$foo.exists('one')", which will fail since no &Foo::exists exists. Even if we tried to do this (and assuming the macro would DWIM):

  Hash::exists $foo{'one'};

This would fail anyway since Hash::exists is expecting a ^Hash instance as it's invocant arg, and not a ^Foo instance, so it would fail on the parameter/argument type check.

I think this is a deep problem with how &bless works, how the container types work, and maybe even how our MMD system works. I think we need to have a well reasoned solution to this which is devoid of any magic hand waving.

Thanks,

Stevan



Reply via email to