On Nov 11, 7:35 pm, Charles Oliver Nutter <[EMAIL PROTECTED]>
wrote:
> Rich Hickey wrote:
> > Hello,
>
> > I've been following and enjoying the discussions in this group for a
> > while, and thought I should introduce myself and the language I've
> > been working on. Clojure (http://clojure.sourceforge.net) is a dynamic
> > programming language for the JVM. It is predominantly a functional
> > programming language, and features a rich set of immutable, persistent
> > data structures. When mutable state is needed, Clojure offers a
> > software transactional memory system, and thread-independent dynamic
> > variables. Clojure is a dialect of Lisp, and shares with Lisp the code-
> > as-data philosophy and macro system. Clojure compiles directly to JVM
> > bytecode, and provides easy access to the Java frameworks.
>
> > If anyone is interested and in the NYC area, I will be speaking about
> > Clojure at the LispNYC group (http://lispnyc.org) Tuesday, Nov. 13.
> > Details are on that site.
>
> Welcome to the group! Would it be possible for you to give us an
> overview of the Clojure implementation design? Interpreter/compiled
> considerations? Type system? Integration with Java's type system?
>
Thanks for the welcome.
Clojure is designed to be small, simple and fast. Functions are
primary. All functions implement an IFn interface, which provides an
invoke() function, overloaded for various arities, and an applyTo()
function for unknown or arbitrary arity calls. Normal calling sequence
is cast to IFn, push args, and call the corresponding invoke method,
i.e. no more overhead than Java method calls. Multimethods add an
additional method call and a hash map lookup. All signatures take and
return objects, therefore all primitives are boxed.
Clojure compiles all non-trivial top-level expressions into JVM
bytecode, one class per function, immediately and in-memory. There is
no interpreter. I chose to do this for 3 reasons:
Execution speed
To avoid the (inevitable?) differences between interpreted and
compiled modes
To be able to support debugging with standard JVM bytecode debugging
tools
So far I'm happy on the first 2 fronts, but a bit disappointed in the
inability of the Java IDEs to handle properly adorned bytecode not
mapped to Java source (without writing a language-specific plugin).
JSwat seems to work best. I use ASM for bytecode generation and am
very pleased with it. Currently Clojure has no static .class file
generation capability.
Clojure does not offer its own type system. Clojure is not object-
oriented in the traditional sense, e.g. it doesn't have its own notion
of classes/types etc. It is presumed Clojure programs will primarily
use the built-in Clojure collections, a set of immutable and
persistent implementations of lists, vectors and maps. I had to
provide these, as there are no equivalents in the Java SDK. One of the
critical design requirements was to treat ephemeral garbage as cheap,
and that has worked well in practice - the JIT and optimizers seem
extremely good with short term ephemeral memory use and all-final
immutable classes.
Clojure integrates with the Java type system in several ways. Most of
the core Clojure data structures are represented by Java interfaces,
supporting extension of and access to Clojure from Java. Clojure
strings are Java Strings, Clojure collections implement the read-only
portion of the Collection interface, Clojure IFns are Callable etc. It
is possible to implement Java interfaces dynamically in Clojure.
Currently that is based on Proxy, but will become direct bytecode
generation. Extending Java classes is on the todo list, but the
emphasis will be on treating that similarly to implementing interfaces
and not on arbitrary class definition.
And Clojure can of course consume Java, create Java objects, call
methods etc. With a minimum of (optional) types hints, such calls are
direct, not using reflection. No wrappers or proxies are created for
Java objects. Clojure also extends its core sequence abstraction to
Java reference arrays and Iterables, allowing the bulk of the Clojure
sequence library to work with these Java data structures.
Of the things I've seen discussed here, I'd have to say lightweight
single-method objects have become less interesting than I thought.
I've done similar work in .Net, where there are delegates, and now
having implemented arity overloading with a multiple method interface
I much prefer the latter. That said, reductions in class and
classloader overhead are always good. Full tail-call optimization
would be very welcome. Exceptions dedicated for non-local flow control
are also interesting, as I use them for transaction unwinding and
worry about people inadvertently catching them.
Rich
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM
Languages" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en
-~----------~----~----~----~------~----~------~--~---