Wednesday, March 19, 2008

Concise Instance Creation Expressions (CICE)

Another proposal CICE is being put out there for Java 7. To compile the code posted here you will need the latest cice prototype. You can run it using your installed jre. Now, let's get down to the code! First I'm gonna show you the current Java version, then I'll show you the CICE version.

Java Version

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;

/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");

public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});

}
}

Now, the main problem people have with java is that it's overly verbose, and they're right in that aspect. CICE aims to reduce that verbosity; by making it more concise and to the point. Now you know the basics of that implementation; it's a simple JFrame with a button that when you click it will display a message in your console.

Now the same app but with CICE:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* Created: Mar 19, 2008 5:57:45 PM
*
* @author Robert O'Connor
*/
public class CICEGui {
JFrame frame = new JFrame("CICE Gui");
JButton button = new JButton("Press me");

public CICEGui() {
button.addActionListener(ActionListener(ActionEvent e){
System.out.println("Button pressed");
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(Runnable() {
new CICEGui();
});
}
}


The above is a lot less verbose; What's missing? You'll notice the difference primarily in the main() method and the addActionListener() method call to attach the event listener to my JButton.
What's missing? That's right the
public void run() { ... }
and
public void actionPerformed(ActionEvent e) { ... }
How can this be and how do I get access to the ActionEvent reference? Well notice the following:
button.addActionListener(ActionListener(ActionEvent e) {
System.out.println("Button pressed");
});
I passed in the ActionEvent parameter to the Concise Instance Creation Expression! Using CICE, I was able to eliminate the methods. Also note, that I was able to eliminate using the word new is not needed with CICE. I was also able to state my intent cleanly, and in a lot less verbose way. How many lines were eliminated between the Java version and the CICE version?

(rob-laptop)rob@~/playground/src/main/java$ wc -l misc/UsualJavaGui.java misc/CICEGui.java
43 misc/UsualJavaGui.java
34 misc/CICEGui.java
77 total
(rob-laptop)rob@~/playground/src/main/java$

Well, that's 9 lines! Why should you have to type out the method definition if there is only ONE method in the interface or abstract class?

4 comments:

(blank) said...

I've always been a fan of CICE, but the lack of the "new" keyword always rubs me wrong. Basically, there is an invisible anonymous class hiding under the anonymous method. I think the intention is better expressed as:

button.addActionListener(new ActionListener(ActionEvent e){
...
});

Robby O'Connor said...

If i understand CICE right -- the point it is to be concise; and w/o the new keyword; it's straight-forward and concise. Why add this 'new'? Not sure why it rubs you wrong..

(blank) said...

Being concise is a fine goal but I believe that needs to be in harmony with what it "says", since language design is somewhere in the realm of communicating intent.

Java (so far) doesn't have any concept of inner methods, like Pascal did. That was my rub, however...

I must say that you made me doublethink my original objection. Maybe the idiom is worth having since FCM is going that way too.

Robby O'Connor said...

If you want anonymous methods -- peek at the FCM proposal :) But yeh =)