[Prev][Next][Index][Thread]
Java and Lisp
At the Dynamic Objects Event at ObjectWorld earlier this month, there
was an informal discussion about the relationship between Lisp and
Java, and what might be done to take advantage of Java technologies in
Lisp.
John has asked in this mailing list for someone to try to summarize
the discussion. I have not seen any response. Some of the topics that
I am NOT prepared to summarize include:
- Defining a protocol whereby methods on CL-HTTP objects could be fired
to produce Java source, Java byte-code or Javascript source.
- Extending the Java virtual machine byte-code to better support our
favorite dynamic language.
My personal favorites, which I WOULD like to discuss, are representing
Java programs in CL, and representing CL programs in Java.
REPRESENTING JAVA PROGRAMS IN COMMON LISP:
------------------------------------------
Imagine a java-class metaclass. Classes defined using this metaclass
would follow the rules for Java classes, such as:
- Single inheritance, but multiple "interface inheritance".
- "Declaring" the existence of an interface without providing a
definition would produce a method providing only an undefined
interface error. A subclass would have to provide the "real"
method.
- Single argument method dispatch. Method dispatch in Java is more
like Flavors or Smalltalk than like CLOS. For example, we might
define a SEND method with an argument list like:
(class-or-instance message &rest args)
Note that the first argument can be an instance of a Java class, or
it can be a Java class itself (or the name of a Java class).
- No initargs.
- A different initialize-instance protocol than for standard-object, which
directly supports the idea of inherited, parameterless initialization
code which is run at CLASS DEFINITION time.
A DEF-JAVA-CLASS macro would be defined which created the java-class
classes and methods, initializing them as appropriate.
Up to this point, all I've described is a mechanism for programming in
an arguably stilted style. We get something useful only when we add
two additional interrelated features:
1. Invoking the SEND method calls out to a Java virtual machine
byte-code engine, using the byte-code stored in the java-class
class representation.
2. A LOAD-JAVA-CLASS function which reads Java class files (i.e. the
Java virtual machine byte-code) and creates the appropriate
java-class class objects.
With this, Lisp programmers would have access to the multitude of Java
class libraries being developed. Want a giff displayer? Just use
someone's Java class library. Etc.
Some issues are:
- Is this the right way to do this? I.E. capture the semantics in a
java-class metaclass and a send method, keeping the hair in the
implementation of SEND and LOAD-JAVA-CLASS?
- The usual foreign-function/data issues. Should Java data be
identical with the corresponding Lisp Data (i.e. should Java data
within the java-engine be represented using Lisp objects) or should
there could be a set of (possibly no-op) conversion functions?
Perhaps the conversion functions are called automatically by the
send mechanism, based on information built into the system and
obtained from the Java classes. Maybe there is a good way to bury
this so that programmers never have to worry about this.
- What are the implications of having user interfaces defined within
Java class files which are completely unrelated to GUI code in the
same application which uses CLIM, CLX, etc.?
REPRESENTING COMMON LISP PROGRAMS IN JAVA:
------------------------------------------
Suppose the above exists. A natural extension is to have a compiler
which can generate Java class files from def-java-class forms,
allowing a Lisp programmer to generate mobile application code.
This is another way to approach the first undiscussed issue above,
whereby CL-HTTP servers want to be able to generate Java applet code
on the fly. One big win from this is that the facility with which
Lisp programs can be written to generate and compile code on the fly
could be used to imbue servers with the ability to automatically
generate Java applets on a custom basis.
Of course, a Lisp programmer wants to be able to use arbitrary Lisp
code within def-java-class. We want to be able to call our favorite
built-in or user-defined functions. CAUTION, from here on out, things
get very speculative...
What is the right way to make this work? One way would be to extend
the Java virtual machine definition to include Lisp-like operations
such as function calls. A compiler could be provided which generates
the appropriate new instructions, and the vendor's Lisp implementation
source could be recompiled and distrubted as class libraries. The
lossage here is in getting the world to support the new instructions.
I don't want to get into that.
Another way would be to re-implement all of Lisp, including DEFUN,
etc., to use def-java-class, and to require that programmers only send
messages to code which has been converted in this way. Perhaps the
compiler can be made smart enough to translate such forms as DEFUN and
DEFVAR for us....
Both of these raise the usual "modularizing Lisp" issues about how the
utilities can be written so that hello-world doesn't require bignum
arithmetic libraries, etc. This is its own hard problem. (...which I
am personally interested in, but is probably outside the scope of this
discussion, so email me.)
All of this ignores what to me seems like the real issue: what are the
semantics of function calls, global variables, symbols, packages, etc.
in a Java world? A straightforward definition might involve defining
SYMBOL and FUNCTION Java class. Symbols have the usual symbol-value
and symbol-function attributes. A function call like (foo x y z)
becomes something like (send (send foo symbol-function)
call-yourself-on x y z). Foo is a symbol instance obtained at load
time by sending various messages to the package system objects. Yuk.
This seems pretty inefficient. What should the primitive built-in
operations be? (Read on before responding...)
Rather than going though the symbol-function, is there a way to
recognize those calls which can be viewed as operations on their first
argument. For example (length x) could be viewed as sending the
length message to the object x. I already snuck this in above, where
symbol-function is message on symbol objects. Perhaps a declaration
syntax can be designed which allows the compiler to recognize such
situations and produce code which is more idiomatic to Java?
If this can be done in a way that isn't a complete kludge, then
arbitrary Lisp programs (with additional declarations, etc.) could be
compiled to mobile, distributable, Web code. Rather than programming
in Java (yuk), we can program and develop in CL and simply DISTRIBUTE
in Java. The vendors might provide CL implementations as Java class
libraries.
Imagine a CL-HTTP which is built on top a Lisp which could be compiled
and distributed this way. The applets could include server code which
generated applets....