views:

1299

answers:

7

I am a fan of static metaprogramming in C++. I know Java now has generics. Does this mean that static metaprogramming (i.e., compile-time program execution) is possible in Java? If so, can anyone recommend any good resources where one can learn more about it?

A: 

No, generics in Java is purely a way to avoid casting of Object.

larsivi
+10  A: 

No, this is not possible. Generics are not as powerful as templates. For instance, a template argument can be a user-defined type, a primitive type, or a value; but a generic template argument can only be Object or a subtype thereof.

Thomas
+1: Great answer!
Partial
Yet reflection is more powerful than templates--why would you use the wrong tool (generics) for the job?
Bill K
One word: type safety. (Zero... one... see? One word.)
Thomas
+1  A: 

No. Even more, generic types are erased to their upper bound by the compiler, so you cannot create a new instance of a generic type T at runtime.

The best way to do metaprogamming in Java is to circumvent the type erasure and hand in the Class<T> object of your type T. Still, this is only a hack.

Torsten Marek
+6  A: 

Take a look at Clojure. It's a LISP with Macros (meta-programming) that runs on the JVM and is very interoperable with Java.

Lou Franco
+1  A: 

In a very reduced sense, maybe? http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/

jmagica
A: 

I'm not sure I understand the advantage of static meta-programming.

In Java, you can reflect to find information about your classes and do all the things meta-programming would do, you just get to do them inside your code without adding new syntax and different ways of thinking. Annotations are also able to do certain meta-programming tasks in a more structured way.

I could be wrong about this, I'm seriously considering opening a question on it because I'm not sure I get it. It seems like static meta-programming is a neat hack that gets around the fact that some languages don't keep a lot of compile-time information available at run-time (one of the strong points of Java and of dynamic languages).

If anyone could reply with a link to an example where meta-programming offers a more understandable, readable or otherwise better solution than reflection would, I'd appreciate the effort.

Bill K
Ira Baxter
....And (same authors) "Re-engineering C++ Component Models Via Automatic Program Transformation" available at http://www.semanticdesigns.com/Company/Publications. This describes the work in an incomplete state but has a lot of same flavor.
Ira Baxter
I was referring to an advantage of meta-programming over a more active technology like reflection. I recognize that C++ is limited to compile-time activity and therefore may have to go through hoops to do things that dynamic or VM languages might do at runtime, but why would you want a hack like templates when you have true reflection?
Bill K
@Bill: because performance matters. "Templates" for all their hackiness happen before the program is really compiled. Program transformation does the same. In effect, modify the source to be what you want before the compiler sees it; you the programmer don't have to look at the modified source, just the abstracted source that way you want to think about it. Finally, "reflection" is usually very limited in what it can inspect: for instance, you can't ask arbitrary questios about the code, just those questions the reflection mechanism implements. Transformations can inspect anything.
Ira Baxter
@ira So summing up your message, assuming you're talking Java and performance isn't the goal, reflection and generics are just improved reflection? Outside the original asker's context, I'm interested in the transformations... Although I believe you are mistaken about what java can do (I believe you can get access to the entire parse tree, but not through the reflections api), I'm kinda wondering what Transformations do--I'll look it up.
Bill K
Reflection in a langauge only provides what the langauge providers agree in advance to give you. I know of no langauge(s) [except the LISP family] where the language provides you, through reflection, complete access to the source code as an AST (YMMV). The reason for the restriction for Java/C# is that keeping that information around doesn't help execution time at all, so the langauge designers tossed it. (Providing access to all of it is hard if you want it to have some relation to the compiled code). Transformations systems step *outside* the language and thus are not limited like this.
Ira Baxter
@Bill: The explicit link for a (transformation) *tool* that is "better than reflection" is the DMS Software Reengineering Toolkit. Anything you can with reflection, I can do *meta*.
Ira Baxter
+1  A: 

If you need powerful compile-time logic for Java, one way to do that is with some kind of code generation. Since, as other posters have pointed out, the Java language doesn't provide any features suitable for doing compile-time logic, this may be your best option (iff you really do have a need for compile-time logic). Once you have exhausted the other possibilities and you are sure you want to do code-generation, you might be interested in my open source project Rjava, available at:

http://www.github.com/blak3mill3r

It is a Java code generation library written in Ruby, which I wrote in order to generate Google Web Toolkit interfaces for Ruby on Rails applications automatically. It has proved quite handy for that.

As a warning, it can be very difficult to debug Rjava code, Rjava doesn't do much checking, it just assumes you know what you're doing. That's pretty much the state of static metaprogramming anyway. I'd say it's significantly easier to debug than anything non-trivial done with C++ TMP, and it is possible to use it for the same kinds of things.

Anyway, if you were considering writing a program which outputs Java source code, stop right now and check out Rjava. It might not do what you want yet, but it's MIT licensed, so feel free to improve it, deep fry it, or sell it to your grandma. I'd be glad to have other devs who are experienced with generic programming to comment on the design.

Blake Miller