On Thu, Mar 31, 2005 at 01:11:37PM -0500, Aaron Sherman wrote:
: If you declare a variable to be of a type (let's even say a class to be
: specific), then you have hinted to the compiler as to the nature of that
: variable, but nothing is certain.
: 
: That is to say that the compiler cannot:
: 
:       * Make any type-massaging choices yet on (implicit or explicit)
:         method invocations
:       * Issue any errors based on signature miss-matches
: 
: Ok?

Yes.  You might perhaps be able to get warnings on things that
look like signature mismatches, but I certainly wouldn't make it
mandatory, or even the default.

: Now we move on to the idea of finalization. Please correct me where I
: conflate finalization and openness. I'm not sure I understand the
: difference at all (no, I'm certain I don't).

I think you already dug this up, but no harm in reiterating:

    open/closed: whether you can munge the class definition itself.
    final/non-final: whether this is guaranteed to be a leaf node class.

: We assert (don't have the docs handy, but I'll just arm-wave the syntax)
: that the class is now finalized.

We don't allow assertions that a particular class is final, because that's a
reversed dependency.  We only allow you to assert that a particular class is
non-final.  One way to do that is simply to derive from it.

: This means any attempt to re-define the
: interface of the class is a compile-time error, correct?

If we let you do it, but we don't.  :-)

The interface can be assumed frozen by the compiler only if the
entire application requests the class finalization optimization,
and if by CHECK time nobody has registered a dependency on the class
by either deriving from it or claiming that they will derive from it
in the future.  Applications with pluggable architecture should probably
not request the optimization unless there is some point in time at which
it can be determined that all plugins have been linked in.

: What about
: changing the internals of the class (e.g. changing the code associated
: with a method without re-defining the signature)?

That's more like the open/closed distinction, though for an open
class you could also change the interface on the fly, which would
invalidate some or all of your method dispatch caches.

The optimizer is also in control of open/closed classes, and you
may only declare that a class must remain open.  You may not declare
a class closed.  Again, your application may ask that all closable
classes be closed.

Final classes are a subset of closed classes, so if the optimizer
determines that it can finalize a class but not close a class, the
class is not finalized either.  That's not actually a big problem,
because unlike with finalization, classes may only remain open
by explicit declaration of the dependency, whereas classes may be
implicitly made non-final by deriving from them.

This is all policy of the default metaclasses.  You may, of course,
have other metaclasses that establish different policies.  There are
applications where you probably want your classes to be born closed.
This may negativly impact your ability to do AOP.

: Next, what are the conditions under which a class can be finalized?
: 
:       * Can we finalize a class which has non-finalized ancestors?

All ancestors are by definition non-final.

:       * What if it has method parameters/return values or member
:         variables whose types are not finalized?

Depends on the extent to which we support named type equivalence vs
structural type equivalence, I suppose, and whether the compiler uses
type name information to make assumptions about the structure.

:       * What if it applies roles which are not finalized?

Roles cannot be derived from, so they're always final in that sense.
We should probably consider them closed by default as well, or at least
closed after first use.  If a role specifies implementation, it's always
default implementation, so overriding implementation always occurs in a class
instead.

Basically, in Perl 6 I think roles take on the, er, role of finalized
classes in specifying immutable interfaces, to a large extent.

: Obviously each one of these questions comes with a host of "what happens
: if" questions given a "yes" answer....
: 
: Another question: how does finalization interact with a class's
: metaclass? Does the metaclass become a const? Is the type of a metaclass
: itself a finalized class? If not, can it be finalized by user code?

Metaclasses can do whatever they like.  They're worse than traits,
if that's possible.

As I say, the default metaclass is what provides the standard policies,
but they can be warped in whatever direction you like, if you want
everyone to hate you.

: > One additional wrinkle is that *anyone* is allowed to declare a
: > class non-cooperative (open or non-final) during *any* part of the
: > compilation
: 
: ... even after it is declared final?

Can't declare anything final in Standard Perl.

: Will core types be finalized by default?

Certainly not.  This whole rigamarole is to avoid the Java type fiasco.

We do put some restriction onto low-level types like "int" such that
the compiler can assume a particular representation of the value.
But that doesn't stop you from wrapping additional methods around it,
as long as your derived class doesn't add data.  If you want to add data,
derive from Int rather than int, since Int knows how to be a Real Objectâ.

: > I hope this clears things up a little.
: 
: Clear.... that's a word ;-)

According to Charles Williams, the four virtues required for reading
poetry aloud are Clarity, Speed, Humility, and Courage.  Just define
life as a form of poetry, and you're all set.

Larry

Reply via email to