Adding Virtual Classes to Scala
Write down related thoughts here, without worrying about feasibility, peer-ridicule ,..
Are Packages Virtual Classes
It would be nice to be able to "subclass" java.io and override File to do security checks for example.
Ingo Adriaan, just to make sure I don't get it wrong, do you mean "can packages contain virtual classes"?
Adriaan Yep, that's what I meant, but it's too invasive for a first take on VC's anyway
Erik Virtual classes in "packages" (in 'attributes' slots in fragments) in gbeta are non-trivial. The semantics of this is similar to open classes or partial classes, i.e., it is a way to add declarations to a specified context in a physically separate location (e.g., in a different file). Ex in a slightly Scala-like syntax:
The reason why this construct is a bit hard to handle is that you may have any number of 'other' files that wish to add declarations to the location FooLib, and name clashes are hard to detect until link time because these other files should be separately compilable. Another thing is that this kind of feature is incompatible with a requirement that the exact superclass of a given class (here: a version of a virtual class) must be known somewhere in the program, because we may choose to link Foo.gb with zero or more of the files fl1.gb and fl2.gb (if zero, Foo has no nested Baz; if both, Foo has a name clash on Baz; if one, the choice between fl1.gb and fl2.gb determines the exact class).
So is this similar to what you mean by having virtual classes in packages? In that case it's very interesting, but not trivial.
Geoff I do not think it would be feasible to "subclass" packages using the virtual class mechanism, as it seems very important to the virtual class encoding that the initial enclosing "module" declare the classes as virtual.
Maybe this is a good time to make import more powerful. Since packages can be considered virtual classes.
David Pollak posted his thoughts about a better import, I think we should consider them as part of the design of VC's.
Geoff It may be feasible to consider packages as virtual classes, but I think this would require that the classes in a package be defined as virtual from the start (see above). However, it is not really clear to me
how this interacts with what David is proposing. Though I am not entirely clear on what he is proposing. My interpretation is that currently
only makes the contents of
foo visible in the current scope, rather than acting more like
open in Standard ML, for example, and actually putting the contents of a module into the current
scope. However, I am guessing that David is not proposing that
import actually pull in code, but that
import should be transitive: if you import
package2 then you have also imported
package2 by importing
Example expansion by Martin
Sean I'm not so happy with <:, it seems like virtual should be a class modifier (to state that the class can be refined) and then just use extends as with classes. Its weird to me that <: means both extends and the class is virtual, while extends means extends and the class is no longer virtual. But this is just a syntactic gripe.
Inheriting from virtual classes
said: Based upon my discussion with Martin I was under the impression we would need to disallow examples like the following, where a virtual class is inherited from in a subclass of its enclosing class:
That is, having E inherit from C in B would need to be disallowed. However, I just worked out
what I think would be the translation based Martin's example, and it seems to be accepted by the Scala compiler without problems. Are there language features I am not taking into account, or is it not a functionally equivalent translation?
wrote in e-mail:
I don't think there is any need to disallow that inheritance relation (i.e.,
inheriting from inherited virtual in same object), and the translation
should also work as-is.
Okay, maybe I just misunderstood what Martin was telling me. It could be he was talking about the restriction on inheriting at different nesting depths.
Virtual case classes
Geoff I think this is the correct way to compile virtual case classes
Ingo I am currently using the following idiom in ScalaFX, but I realized that it is actually not possible with virtual classes. It only works for me because I currently have to write all boiler plate code for assembling the modules myself anyways. Here is an example (refering to the A of the first example from above):
We cannot have something like Modulefinal, since we don't know the precise C that R will extend at compile time. The compiler would need to create a concrete class R for every instantiation of Module at runtime, i.e., when it knows the value of a. I mainly used this idiom for namespace subdivision. I don't see another (static) way to do it. Is it safe to say that a class hierarchy involving a virtual base class must entirely go into a single namespace? This might be a problem for large hierarchies. Can we/Do we want to address this issue? Am I missing something?
Erik We discussed this. In gbeta it is supported to inherit from a class which is not statically known, but the planned approach for Scala would be to require that the superclass is statically known at each level. So when inheriting from a virtual class (e.g., R extends a.C) the exact set of mixins included in that virtual class (a.C) should be known in every version of the enclosing class (here we only have one: Module), such that a concrete class and a factory method can be generated. The rationale is that it should be possible to determine at compile-time the exact value (i.e., the exact set of mixins) of all classes that may exist at run-time, because it would be a too radical change to the Scala execution model to allow for run-time creation of classes. In the concrete example 'val a' could refer to instances of different classes with different values for the virtual class C, and hence this could not be supported without run-time creation of classes, i.e., this kind of program should be rejected.
> One thing we should keep in mind is that CaesarJ (http://caesarj.org/) uses a scheme
> that may actually be very similar, in order to provide virtual classes in an
> extension of Java. So we'd need clarify the differences.
Sean My encoding, which I guess is related to the current encoding, is based on the open class pattern presented in the Jiazzi paper, except with language-level mixins we can get around the problem that we can't extend the open type parameters directly.