There has been a flurry of recent blogs on native property syntax, much of it rather emotional. This blog tries to get past the emotions, hoping to garner interest in the real issues that need to be solved for native properties.
I had blogged on property boilerplate and the work of my graduate student Alexandre Alves in the summer, but I didn't get much reaction then. But recently, there has been a flurry of blogs on native property syntax. Let's try this again.
Many programmers are sick and
tired of boring, repetitive boilerplate code for JavaBeans properties.
Here is a simple code example from the JBoss EJB3 tutorial.
@Entity public class LineItem implements java.io.Serializable { private int id; private double subtotal; private int quantity; private String product; private Order order; @Id @GeneratedValue(strategy=GenerationType.AUTO) public int getId() { return id; } public void setId(int id) { this.id = id; } public double getSubtotal() { return subtotal; } public void setSubtotal(double subtotal) { this.subtotal = subtotal; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public String getProduct() { return product; } public void setProduct(String product) { this.product = product; } @ManyToOne @JoinColumn(name = "order_id") public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } }
64 lines. Boring, repetitive lines.
Alex's implementation of native properties crunched it down to 12 lines. (Don't get hung up on the @Property syntax--see below...)
@Entity public class LineItem implements java.io.Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Property private int id; @Property private double subtotal; @Property private int quantity; @Property private String product; @ManyToOne @JoinColumn(name = "order_id") @Property private Order order;@ }
I thought this would be a total
no-brainer. Wouldn't you rather read 12 lines of code than 64 lines?
Well, apparently not everyone. There are many emotional reactions floating around in the blogosphere.
Does your IDE also read them to you, dude?
Seriously, maybe an IDE could do intelligent code folding and show you a one-line property when it sees six lines of getter/setter pairs in the code. That sounds rather fragile, but it would be better than nothing.
Where do the arrows come in, you
ask. There are several proposals for a property access operator.
The arrow got people excited. Everyone loves to hate the arrow (see here, here, and here). I don't know why--it is just an operator. Maybe .@ is prettier? Surely, there is some token that can be parsed unambiguously and that doesn't cause emotional waves.
Using just the dot is unfortunately a minefield. You'd have to look closely what item.quantity means. Is there an accessible field quantity? Is there a quantity property? Who wins if both are present? Or is that illegal? I am sure that one can cook up a set of rules, but is it worth it? Why are people so attached to the dot? For example, Peter von der Ahé writes: "It has to be '.' (dot). Anything else would look silly."
Having no operator at all might work. Look at the EJB3 example--most of the getters and setters invocations are done through reflection anyway.
There is a lot
of sanctimonious handwringing on how getters and setters break
encapsulation. Yup. They do. People should never write code like that
LineItem class. But guess what...they do.
Why do good people write such evil code? Many tools require bean properties. If you write EJB3 entities, JSF components, client-side components, etc. etc, you end up writing lots and lots of getters and setters.
One of programmers at Borland
once told me how, around 1996, their team showed the Delphi GUI builder to
the Java group. Their eyes popped out. They had never seen a visual GUI
builder. They had never understood why people preferred Visual Basic over
AWT or Motif--after all, everyone knows that Basic is icky. But once they
realized that a VB programmer can do in a day what takes weeks in Motif,
they too wanted a GUI builder. A GUI builder shows a property sheet. Java
needed properties. That's how the JavaBeans spec was born--it fakes
properties as getter/setter method pairs. [I don't know if this story is
actually true--I'd love to hear from the Java veterans.]
Of course, faking properties as getter/setter method pairs has been an ugly mess.
It is tempting to start with a clean slate. My guess, though, is, that we will get some integration of native properties with java.beans.Introspector, for compatibility with legacy code.
Alex used the @Property annotation in his prototype. Sure, a property keyword would have been nicer, but that breaks the gabazillion lines of code that use property as a name. Then again, annotations are not supposed to change the semantics of the class to which they are applied, but Alex' @Property synthesizes getters and setters. What can be done?
I think the token approach will probably win out. I hate to give an example, because people will say "that's so ugly". But just to show that it can be done...you can put an @ after the type. For example, here is a quantity property.
public int @ quantity;
I know it's ugly. Don't tell me "native properties are a bad idea because this syntax is ugly". Someone will come up with something acceptable. Or we'll all get used to something ugly, just like we got used to the colon in the for loop.
Or reified generic types. Or XML
syntax. I am glad that people worry about solving (or creating) tomorrow's
problems, but property boilerplate is a problem that we have today.
Before vilifying a proposal because of unsightly syntax, let's summarize what one wants in native properties.
Here are some issues that have been raised.
The issue that has gotten the most press, namely what operator, if any, to use for property access, seems the least important one.