Aaron Sherman writes:
> What I do not think should be allowed (and I may be contradicting
> Larry here, which I realize is taking my life in my hands ;) is
> violating the compile-time view of the "static" type tree. 

That sentence is getting pretty C++-derived-like, which Perl is hardly
anymore.  We have to reorganize your brain a bit.  Let's pretend that
we're in Smalltalk instead of Java (no offense or compliment to
either--I'm just taking extremes).  

Types don't form a tree.  /Classes/ form a dag, which is, for all
intents and purposes, a tree.  But types are something very different.
There are three kinds of types:

    * Roles (types with behavior)
    * Subtypes (roles with value restriction)
    * Classes (roles with an implementation specification)

In particular, subtypes can form very complex non-tree-like structures,
and structures which are not determinable by the compiler in the general
case (if they were, then we'd have GÃdel's truth machine).  But that's
okay, because it all boils down to calling the subtype closures and
having those determine the implications of the structure, bypassing the
structure itself.

Let's step back into Perl 5 for a moment and pretend that objects are
just blessed hashes again.  If every object has some metadata stuffed
into that hash, then you could really factor all three of these types of
types into the subtype category.  Subtypes are something that you can't
really do any static analysis on.  That means that I can circumvent your
"static view" rule by doing exactly that: putting metadata on objects
and making every type a subtype.  But because the compiler has every
ability to do that for us, and might just be the way it does things, it
seems like we've just run in a big circle: outlawing something possible,
and then walking through a loophole to make it possible again.

> That is, you can load an object "foo" at run-time, without and
> interface definition, but it can't change the shape of the type tree
> or its existing interfaces. If it wants to do that, it has to provide
> an interface def (e.g. what an autoload module should be able to
> provide).
> Why? Because if you can do that, then this:
>       my X $a;
>       $a.m(1) = 1;
> ALWAYS has to work because you might have replaced X at run-time with a
> class that has a "method m(int) is rw()", and the compiler must silently
> (perhaps with an optional warning) permit it.

And if X were defined as `Any where { $_.can('m') }`, then could you
still make that guarantee?  You could say "no, we can't so that would be
an illegal code segment at compile time", then I ask that you consider
if X were defined as `Any where { $_.can('m') && $_.CLASS.m ~~ rw }`
(testing whether it has an rw m method... barring syntax).  You'd have
to say "no" there, too, because there's no way to tell what that opaque
codeblock is doing. 

> Please think carefully about how dynamic you want Perl 6 to be....
> Dynamic is good, but there's such a thing as too much of a good thing.

We'd like Perl 6 to be as dynamic as Perl 5.


Reply via email to