After 3 months of delay, it was quite amusing that the initial MO bridge took only 3 hours to land:
pugs> vv('hello, world').HOW ^Str pugs> vv('hello, world').HOW.HOW ^Class
(The vv()
above is a makeshift call that casts 6.2.0-land values into 6.28.0-land objects; it will go away once all existing built-in types are wrapped into MO.)
To understand what the ^Class
notation means, let's take a brief look at Perl 6's object model, as implemented by Pugs 6.28.0's MO (Meta Object) subsystem.
In a traditional class-based object system such as Ruby's, the String
class would be an instance of the Class
class:
irb(main)> String.instance_of?(Class) => true irb(main)> String.instance_of?(String) => false
Because of this, you can't call .new
on a String instance, and you can't call .length
on the String class:
irb(main)> String.new.new NoMethodError: undefined method `new' for "":String irb(main)> String.new.length => 0 irb(main)> String.length NoMethodError: undefined method `length' for String:Class
Perl 5, on the other hand, takes an unique approach: When we say IO::String->new
, the IO::String
is not a Class object -- rather, it is a prototypical IO::String
object that has no attributes!
IO::String->isa('Class');
#=> false (perl5 doesn't have a built-in Class)
IO::String->isa('IO::String');
#=> true
IO::String->new->new;
#=> IO::String=GLOB(0x18ab160)
IO::String->new->getpos;
#=> 0
IO::String->getpos;
Error: Can't use string ("IO::String") as a symbol ref...
The advantage of this arrangement is that several object systems -- prototype-based, closure-based, et cetera -- can exist simultaneously in the same program, without having to inherit from an universal Class
class.
However, a bare literal "IO::String"
is a terrible way to represent a prototypical object: it makes reflection needlessly difficult, and the error message for accessing the non-existing attribute slot ("Can't use string as a symbol ref...") seems to obey the principle of most surprise.
Perl 6's solution to this is simple: The prototypical string object, spelled ::Str
or simply Str
(if it's in scope), is a genuine Str instance. However, any attempt to access its attributes raises a sensible exception. Just as in Perl 5, so-called class methods such as .new
are simply those methods that does not access instance attributes, and you can call them on both ::Str
and regular Str instances.
Calling an object's WHAT
method returns the prototypical object. This replaces Perl 5's ugly ref($x) || $x
idiom:
pugs> 'hello'.WHAT ::Str pugs> Str.WHAT ::Str
On the other hand, because Perl 6's builtin objects are backed by a normal class-based dispatch system, you can reliably obtain a list of all Str's supported methods, by querying the Class
instance that implements ::Str
:
pugs> vv('hello').HOW ^Str pugs> vv('hello').HOW.methods ["HOW","WHICH","bless","reverse"]
So there we have it: the Perl5ish prototypical object Str.WHAT
is also spelled ::Str
, and the Rubyish class object Str.HOW
is also spelled ^Str
.
The next step is to expose all MO's meta-objects (Role/Method/Class/Object) into Perl 6 land, and adapt our Perl 5 bridge to use Moose.pm, such that a class Foo {...}
declaration in Pugs can generate both Haskell-side and Perl5-side representations, and work seamlessly with libraries on either side. Stay tuned!
Audrey,
It's great have you back blogging on the progress of Pugs again.
Sometimes I wonder if we shouldn't simplify the spec for 6.x some we can get something complete and working out the door the sooner.
With the all the bells and whistles of Perl 6, sometimes I get concerned that it will be easy enough to pick up and get started with for newcomers...or that a working implementation will take too long.
Although there's a lot of effort to Do-What-I-Mean in a lot of different cases, it seems at times the basic simplicity of, well, being less complicated, is lost.
Mark
Posted by: Mark Stosberg | 2007.03.03 at 01:55 AM
It's so nice to see Audrey starts to post tutorial-like journals, which are very helpful for us to understand the magic behind the scene. :)
Thank you!
agentz
Posted by: | 2007.03.03 at 02:57 PM