Macro Library for Java?

P

pintman

Hey there!

Looking for a macro library the only thing I found was Jatha[1].
Because the last update of it was in 2001 I wanted to know whether
there is someone who could suggest another library being able to handle
macro expansion in java?!


Thanks for any kind of help and greetings,
Marco.


[1] http://www.cybercom.net/~kimbly/jatha/
 
S

Stefan Ram

pintman said:
Because the last update of it was in 2001 I wanted to know whether
there is someone who could suggest another library being able to handle
macro expansion in java?!

A macro package that is aware of the Java-syntax might become
broken by the next Java version (sometimes, these packages are
not maintained on a long-term base).

Therefore, one might prefer to use a general-purpose preprocessor,
a very good one is:

http://www.nothingisreal.com/gpp/

Another system, enforcing a certain style more strictly, is:

http://www.ross.net/funnelweb/
 
S

Stefan Ram


Recently, I wrote a GPP macro for a counting loop.

Java lacks a loop to only express »repeat the following
statement n times« and not add any other designation.

The following prints »alpha« 6 times.
Two such loop control macors are nested.

public class Main
{ public static void main ( final java.lang.String[] args )
{ REPEAT( 2 )
REPEAT( 3 )
java.lang.System.out.println( "alpha" ); }}

The code generated is:

public class Main
{ public static void main ( final java.lang.String[] args )
{ for(int SYM1=( 2 );(SYM1--)!=0;)
for(int SYM2=( 3 );(SYM2--)!=0;)
java.lang.System.out.println( "alpha" ); }}

and I did it as follows. gpp does not contain a symbol name
generator, but is so versatile that one can write it on
the fly using the powerful »defeval« and »eval« meta-macros:

<#define REPEATNAME|0>
<#define NEXTSYM|<#defeval REPEATNAME|<#eval 1+<#REPEATNAME>>>>
<#define REPEAT|<#NEXTSYM>for(int SYM<#REPEATNAME>=(#1);(SYM<#REPEATNAME>--)!=0;)>

I have defined another gpp-mode, where I can write definitions like:

$define BLOCK new java.lang.Runnable(){ public void run(){$1}}

$define IN_EDT javax.swing.SwingUtilities.invokeLater($1)

Then, to execute any statement in the EDT:

$define INEDT IN_EDT(BLOCK($1))

Debug-print where we are:

$define LOCATE do{ java.lang.System.out.print( new java.lang.Throwable().getStackTrace()[0].toString() + ": " ); }while(false)

Debug-display a reference variable with its name, type and value:

$define DISPLAY do{ LOCATE(); java.lang.System.out.println( "\"$1\" =( " +((( $1 )== null )? "null" :( $1 ).getClass().getName() )+ " )\"" +( $1 )+ "\"." ); }while(false)

Drawback for the aficionados of Eclipse and similar IDEs:
The IDE will not recognice some of the macro syntax.
 
R

Robert Klemme

pintman said:
Hey there!

Looking for a macro library the only thing I found was Jatha[1].
Because the last update of it was in 2001 I wanted to know whether
there is someone who could suggest another library being able to handle
macro expansion in java?!

Hm, what do you need that for? I've never felt the need for that in
several years of doing Java. IMHO there are superior mechanisms that
also have the added advantage of not breaking tool support.

Kind regards

robert
 
P

pintman

Robert said:
Hm, what do you need that for? I've never felt the need for that in
several years of doing Java. IMHO there are superior mechanisms that
also have the added advantage of not breaking tool support.

With macros its possible to create new abstraction layers into the java
programming language without the need of parsers. For instance it would
be possible to create Singletons (or other paradigms) without the need
of knowing implementation details. Another example is the usage of
shortcuts for syntatic constructs. If I need to handle a lot of
integers it could be more understandable to say

for(int i : 1..5)

instead of

for(int i=1; i++; i<=5)

As one could see in LISP there are a lot of applications for this.

Greetings,
Marco.
 
P

pintman

Stefan said:
A macro package that is aware of the Java-syntax might become
broken by the next Java version (sometimes, these packages are
not maintained on a long-term base).

Why? As long as Java syntax stays backward compliant all macros
creating code for old syntax will work.
Therefore, one might prefer to use a general-purpose preprocessor,
a very good one is:

http://www.nothingisreal.com/gpp/

Thanks for that although the last release was in 2004. :(


Greetings,
Marco.
 
S

Stefan Ram

pintman said:
Why? As long as Java syntax stays backward compliant all macros
creating code for old syntax will work.

The macro system might become confused when it has to process
code that uses a new syntax.
 
S

Stefan Ram

pintman said:
for(int i : 1..5)
instead of
for(int i=1; i++; i<=5)

The Java way to do this might be

public class Main
{ public static void main( final java.lang.String[] args )
{ for( final int i : new de.dclj.ram.system.iteration.IntegralRange( 10, 12 ))
java.lang.System.out.println( i ); }}

10
11
12

This uses my library ram.jar

http://www.purl.org/stefan_ram/pub/ram-jar

The class is being described incompletly here (source code
of the class can be reached from there):

http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/system/iteration/IntegralRange.html

The object oriented approach might be:

public class Main
{
public static void loop( final int from, final int to,
final de.dclj.ram.event.Accept<java.lang.Integer> acceptor )
{ for( int i = from; i < to && acceptor.accept( i ); ++i ); }

public static void main( final java.lang.String[] args )
{ loop( 12, 14 + 1, new de.dclj.ram.event.Accept<java.lang.Integer>()
{ public boolean accept( final java.lang.Integer i )
{ java.lang.System.out.println( i ); return true; }}); }}

using

http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/event/Accept.html
 
R

Robert Klemme

pintman said:
With macros its possible to create new abstraction layers into the java
programming language without the need of parsers.

True, although I have to say I always feel wary about preprocessing. I
think Stroustrup regretted not having got rid of CPP in C++ for a reason...

Do you have concrete examples where the benefits of macro processing far
outweigh the disadvantages?
> For instance it would
be possible to create Singletons (or other paradigms) without the need
of knowing implementation details.

Hm, I've never felt it too much typing to do that pattern myself.
> Another example is the usage of
shortcuts for syntatic constructs. If I need to handle a lot of
integers it could be more understandable to say

for(int i : 1..5)

instead of

for(int i=1; i++; i<=5)

In this particular example I don't see improvements in readability and
the breaking of tool support would definitively make me not use a macro
for this.
As one could see in LISP there are a lot of applications for this.

I guess Lisp is a bit different because the macro facility is so tightly
integrated with the language (and very powerful indeed). But YMMV.

Thanks for giving a bit more background on your motivation!

Kind regards

robert
 
S

Stefan Ram

Robert Klemme said:
Do you have concrete examples where the benefits of macro processing far
outweigh the disadvantages?

I have a license (the GPL) at the top of each of hundreds of
Java source files. This is inserted during the make process
with a preprocessor. I'd just need to change the file with
preprocessor definitions at a single place to change all
source files to incorporate another license.

An example of a generated Java source file is:

http://www.purl.org/stefan_ram/java/de/dclj/ram/system/iteration/IntegralRange.java

It also contains

/** (...)
@version slr@2006-06-05T07:51:48+02:00
@see <a href="http://(...)IntegralRange.java">source code</a>
@see <a href="http://(...)IntegralRange.html">documentation</a>
@see <a href="http://(...)ram-jar">Library homepage</a> */ (...)
@de.dclj.ram.meta.description.Cleared("slr@2006-06-05T07:51:48+02:00") (...)
public class IntegralRange

So, links to the source code, the documentation and the
library home are inserted into every source file and
documentation file. This is also done by the preprocessor,
which inserts the text "IntegralRange" at all the three places
where it is used above. Also, the same version date is
inserted in both the JavaDoc comment and an annotation.

To do this manually, would be less consistent across source
files, more work, and more error prone.
 
R

Robert Klemme

Stefan said:
I have a license (the GPL) at the top of each of hundreds of
Java source files. This is inserted during the make process
with a preprocessor. I'd just need to change the file with
preprocessor definitions at a single place to change all
source files to incorporate another license.

An example of a generated Java source file is:

http://www.purl.org/stefan_ram/java/de/dclj/ram/system/iteration/IntegralRange.java

It also contains

/** (...)
@version slr@2006-06-05T07:51:48+02:00
@see <a href="http://(...)IntegralRange.java">source code</a>
@see <a href="http://(...)IntegralRange.html">documentation</a>
@see <a href="http://(...)ram-jar">Library homepage</a> */ (...)
@de.dclj.ram.meta.description.Cleared("slr@2006-06-05T07:51:48+02:00") (...)
public class IntegralRange

So, links to the source code, the documentation and the
library home are inserted into every source file and
documentation file. This is also done by the preprocessor,
which inserts the text "IntegralRange" at all the three places
where it is used above. Also, the same version date is
inserted in both the JavaDoc comment and an annotation.

To do this manually, would be less consistent across source
files, more work, and more error prone.

True. Personally I stick with the class doc templates eclipse provides.
But this doesn't allow for easy changes of course.

Kind regards

robert
 
P

pintman

Stefan said:
pintman said:
for(int i : 1..5)
instead of
for(int i=1; i++; i<=5)

The Java way to do this might be

public class Main
{ public static void main( final java.lang.String[] args )
{ for( final int i : new de.dclj.ram.system.iteration.IntegralRange( 10, 12 ))
java.lang.System.out.println( i ); }}

As you always see in Java there is a great verbose blowup that I wanted
to get rid off. Of course there are ways to DO the same but macros are
a way to WRITE it down in a way that does the same.

But thanks for your supporting libraries.


Greetings,
Marco.
 

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
474,265
Messages
2,571,069
Members
48,771
Latest member
ElysaD

Latest Threads

Top