"Real" Templates for Java?

M

Markus Schaber

Hi,

Does anybody know a tool for java that does "real" templates (Not the
limited "Generics" that come with Java 1.5, but more like the Templates
in C++ are, so you have multiple specialised class files for differently
instantiated Templates to avoid all hidden run-time typecasts etc)?

We hope to get the following advantages over the java 1.5 Generics:

- Avoiding of runtime typechecks / casts altogether.

- Availability of the actual type parameters inside the template
instances (so you can e. G. do a
T[] blubb = new T[100];
which impossible with Generics.

- Signature-Based templating (we write a template that accepts all
objects that have a foobar() method, and only when using the template,
you have to ensure that your Class/Interface parameter you use for
instantiation has this foobar() method. This allows to use the same
template (in different places) for different types that have no common
parent providing the foobar() method.

- Runs in java 1.4 VMs, as it will take some time for 1.5 to get stable
enough.

- Possibility of templating primitive types (currently, this is not so
important for us, as the number of primitive types is rather limited and
won't expand in the near future :).

Hints to both "preprocessor" and direct byte-code creating tools are
welcome, but we prefer open source tools (or at least tools which come
together with their source code and the license allows us to modify them
and fix bugs).

Thanks for your answers,
Markus Schaber
 
D

Daniel Bonniot

Does anybody know a tool for java that does "real" templates

First, your requirements are incompatible with the definition of
Java-the-language, so I'm assuming what you are looking for is a
Java-like language that supports those features, while compiling to Java
bytecodes and generally assuring compatibility with Java code.

One close match for your requirements seems to be PolyJ
(http://www.pmg.lcs.mit.edu/polyj/). They offer more power than Java
1.5. Note however that they use an homogeneous translation, so you won't
avoid the casts nor the boxing/unboxing for primitive types.

A big set back is that development seems to have died in July 2000,
while there are still important bugs and missing features
(http://www.pmg.lcs.mit.edu/polyj/bugs.html), including no inner classes
and no full support of JDK 1.1.

Another project (with which I'm involved) to look at is the Nice
language (http://nice.sf.net).

Regarding your requirements:
- Avoiding of runtime typechecks / casts altogether.

The translation is homogeneous, so the runtime checks are still there. I
don't know of any tool that does the expansion. That should be done in
the future, especially for primitive types, where it really makes a
difference.
- Availability of the actual type parameters inside the template
instances (so you can e. G. do a
T[] blubb = new T[100];
which impossible with Generics.

new T[...] is possible in Nice.
- Signature-Based templating (we write a template that accepts all
objects that have a foobar() method, and only when using the template,
you have to ensure that your Class/Interface parameter you use for
instantiation has this foobar() method. This allows to use the same
template (in different places) for different types that have no common
parent providing the foobar() method.

Nice uses type constraints, since we believe it allows for better design
and documentation. Still, it can handle using the same generic code with
different types developed independently. That's possible because you can
define "abstract interfaces", and make existing classes (imported from a
package you don't control) implement those interfaces.

I refer you to the relevant part of the user manual for a detailed
motivating example:
http://nice.sourceforge.net/manual.html#abstractInterfaces
- Runs in java 1.4 VMs, as it will take some time for 1.5 to get stable
enough.

It does.
- Possibility of templating primitive types (currently, this is not so
important for us, as the number of primitive types is rather limited and
won't expand in the near future :).

You can use primitive types as type parameters. However, you must be
aware that in the current implementation this will possibly cause
boxing/unboxing.
Hints to both "preprocessor" and direct byte-code creating tools are
welcome, but we prefer open source tools (or at least tools which come
together with their source code and the license allows us to modify them
and fix bugs).

Nice compiles directly to java bytecode. It is actively maintained and
developed, and it is available under the GPL. It has many other
improvements, like anonymous functions/closures, multimethods, tuples,
optional parameters to methods, and method contracts (as in Design by
contract)... All this is designed to be as seamlessly inter operable
with Java as possible. Find out more at http://nice.sf.net/ and feel
free to ask further questions about it.

Cheers,

Daniel
 
M

Markus Schaber

Hi, Daniel,

First, your requirements are incompatible with the definition of
Java-the-language, so I'm assuming what you are looking for is a
Java-like language that supports those features, while compiling to
Java bytecodes and generally assuring compatibility with Java code.

Exactly.

But - being honest - you must admit that a "Java-the-language" itsself
does not exist since jdk 1.1, and currently, we have 4 or 5 different
(although somehow compatible) versions (1.0 as the original language,
then 1.1 which brought inner classes etc, then the assert statement came
in somewhere between 1.2 and 2.4, and now we have Generics, Autoboxing
et al in 1.5).

That's the reason why I did not explicitly specify a java-like language.
One close match for your requirements seems to be PolyJ
[snip]

I also had a look at polyj, but the drawbacks you found yourself were non
Another project (with which I'm involved) to look at is the Nice
language (http://nice.sf.net).

Thanks, I'll have a look at it.
The translation is homogeneous, so the runtime checks are still there.
I don't know of any tool that does the expansion.

C++ usually does the full expansion at compile time. NextGen and C# both
defer the expansion to runtime, NextGen via a custom classloader, and C#
via JIT.
That should be done
in the future, especially for primitive types, where it really makes a
difference.

As Java 1.5 permits a List<String> to be assigned to an untyped List
variable, those checks cannot be avoided altogether with homogeneous
translation, I'm afraid.
- Availability of the actual type parameters inside the template
instances (so you can e. G. do a
T[] blubb = new T[100];
which impossible with Generics.
new T[...] is possible in Nice.

That's great.
Nice uses type constraints, since we believe it allows for better
design and documentation. Still, it can handle using the same generic
code with different types developed independently. That's possible
because you can define "abstract interfaces", and make existing
classes (imported from a package you don't control) implement those
interfaces.

That's - ehm - "Nice". Well, really, this looks like what I've always
missed when programming java. (My other "main language" is Python where
all those problems don't exist :)
Nice compiles directly to java bytecode. It is actively maintained and
developed, and it is available under the GPL. It has many other
improvements, like anonymous functions/closures, multimethods, tuples,
optional parameters to methods, and method contracts (as in Design by
contract)... All this is designed to be as seamlessly inter operable
with Java as possible. Find out more at http://nice.sf.net/ and feel
free to ask further questions about it.

Thanks, I'll have a deep look at it.

Markus
 
D

Daniel Bonniot

As Java 1.5 permits a List<String> to be assigned to an untyped List
variable, those checks cannot be avoided altogether with homogeneous
translation, I'm afraid.

In Nice there is no notion of untyped List. Instead, we allow legacy
code to be "retyped", so you can specify what the type parameters are.

Still, the problem is these, since you might call a method that expects
a List<T> for any T, and you want to pass it an ArrayList<int>. One
option is to compile ArrayList<int> to something that deals with ints,
but also accepts the Object interface. Thus you get full speed when
using it with a known primitive type, and go though boxing only in
polymorphic code. Furthermore, you could also specialize the polymorphic
code to make that boxing unnecessary. That's at least sure when you have
accept to the polymorphic code source, but I guess that could even be
done on the bytecode for legacy code.

Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top