Larry Wall wrote:

>'Course, I left out everything about prototype objects there...
>
>The name Foo also (in context) represents an uninitialized object of
>the class in question.  Any object, initialized or not, can get at
>its type handlers by saying
>
>    Foo.meta
>    $foo.meta
>
>and, in fact, the Foo.^bar syntax is just short for Foo.meta.bar.
>  
>

Perhaps saying it is like:

Foo.meta.get_attribute("bar")

Would be safer. Don't want to stomp on the meta-objects.

>[...]
>of the actual magic being defined elsewhere.  It would be possible
>to access classes et al. only via the mechanisms supplied by the
>metaobject protocols, but that would be kind of like the bad old
>[...]
>  
>

Right, but we should really ship with at least a set of Meta Object
Protocol Roles, that covers the core requirements that we will need for
expressing the core types in terms of themselves;

- classes and roles
- attributes and methods
- subsets (ie constraints/subtypes)
- generics (including, by induction, nested generics)

I *think*, at this point, that's all that are necessary. They are
actually quite a useful set for the concerns I raised earlier about
automatically inferring relational information from the metamodel (if
only I knew these terms back then... ;))
http://groups.google.com/groups?threadm=200303042358.56560.sam%40vilain.net

People can instantiate the roles that cover all that to an actual
metaclass in whatever way they like (eg,
Moose::Meta::Class->isa(Class::MOP::Class)), but not having to detect
the type and then figure out how to talk to it for at least the core of
the object system would be good.

People can diverge completely with completely incompatible metaclasses
that don't .do those roles, the only side effect of which being that
people who write code for the standard Perl 6 metamodel will be
incompatible, and maybe some ways of setting up the class won't work
without another layer of trickery. I *think* that's what you're getting
at. Of course, it shouldn't be prohibited just because it smells.

On different note, there should be nice, per-class ways to make type
constraints not simply code blocks - otherwise too much reverse
engineering will be required to do the final stage of compiling typesafe
code, where you close the classes and discard all the runtime type checks.

An easy example of this is generics. With "where", this is what you
write (ignore the syntax errors for now):

class "Array of Str" is Array where { $_.isa(Str) for @$_ }

But that sucks, because that information about the type of the container
is buried deep within the code reference, is slow, and we can't build
our methods with the right signatures. So, we write;

role Array[::T] { ... }
class "Array of Str" does Array[Str];

Great. Now that information is available to Array in a structured manner
and the signatures can be built correspondingly. But to represent the
core types like Mapping or Set, we also need, for instance, the "unique"
constraint to be represented as an object, not a code block:

For instance,

role Mapping[::T1, ::T2] does Coll[::T1, ::T2] where Unique(0);

The "where Unique(0)" is the important bit. What is "Unique", and who
uses it? In my prototypes, I've been considering it being the job of the
composing class or role to handle that, as a meta-object method call.

So, the above might call Coll.meta.Unique(0) (look, I'm stomping all
over the meta-object now) during the composition of the "Mapping" role,
and it uses this to affect the methods that it builds until you get
something that behaves not entirely quite unlike a Mapping.

However feel free to continue to handwave for now. Personally I'd like
to see this synoptic before the Perl 6.0 release, to avoid the mistakes
of other (*cough* C# *cough* Java 1.5 *cough*) languages that slipped on
getting the generics in their libraries, to their ultimate detriment.

Sam.

Reply via email to