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