On Tue, Sep 22, 2009 at 9:59 AM, Don Cohen don-sourceforge-xxz@isis.cs3-inc.com wrote:
Alessio Stalla writes:
> Exactly, we agree. The point I was trying to make is that the > container class must exist, so the compiler must create it. Or the compiler could create only the code vector and the class loader could create the class.
Right, that's what happens right now, however in my view the code vector and the class are two representations of the same thing, that is, when the compiler dumps the code vector it is writing the class in binary form.
> > Good, so you should be able to write a "classloader" that supports > > creation of an anonymous subclass of "compiledFunction" (of which > > there might never be any instances) given a single argument of type > > byte vector. > Anonymous classes don't exist in the JVM, but apart from that, you (Does this mean that you have to look for names that don't yet exist and worry that later you're going to be asked to create a class of the same name that you made up?)
Yes, or do like the abcl compiler does - invent class names sufficiently weird that you can safely hope no one will use the same name, and if one actually will, that's his problem, not yours ;)
> have just described the abcl classloader ;) However, my original point That does not need any temporary files, right?
Right, it doesn't.
> was not about the general compilation model of abcl, which is more > than fine by me; rather, it was about the specific fact that the > generated code includes instructions to load the other code it needs > (compiled local functions), and I think that is a Bad Idea and we can > use classloaders properly to avoid it. I guess you mean that when you call compile the result could be something like a list of pairs of code vectors and generated names and that a class loader for that list (multiple class loader?) could create classes for all of them and allow them to refer to each other as necessary.
The point is that classloaders already work like this! When classloader X loads a class, and that class refers to class C, X is asked by the JVM to load C as well. In abcl we are not using this feature, rather we use an ad-hoc loading model that needs temporary files. I propose to replace that completely and adopt the JVM way.
If in lisp you do (compile (defun f(x) (g x))) when g is not yet defined, what does f compile into? Can you load a class that refers to another class that does not exist? How does that work if the classes are all immutable?
Afaik you cannot have forward-referenced classes, or better: you can only until the referring class must be 'resolved' (dynamically linked). I don't know precisely when that happens but surely before instantiation. However note that your example will probably be compiled by abcl into a call like G.getSymbolFunction().execute(x) i.e. G will not be resolved to a class at compile time (else how would you handle redefinition?). However, what I'm talking about is (compile 'f (lambda (x) (flet ((g (k) k)) (g x)))) - here g is known at compile time, and compiled to its own class. What I propose is this: suppose f is compiled to a class named foo41 and g to foo42, then in one of foo41's methods you'll have code like LispObject g = new foo42(). When loading foo41 we'll use our abcl-specific classloader which knows how to resolve foo42 too (because it knows where to read it from memory or from the file system, depending on the type of compilation), and everything magically works (I hope :)
Cheers, Ale