Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Friday, January 05, 2007

Proposal for new property operator

There's been a few blog postings about adding property support to the Java language properly. Here's a synopsis. The goal is to make it easier to access object properties, using property names, rather than method names.

I'm amazed at some people's ability to Not Get It.

The proposal is too add a special operator, ->, for this purpose.

This means that you have to be aware that something is a property before you know how to access it.

Properties in other languages are powerful because they are accessed just like fields. You see this in Ruby especially. You can change your mind and switch from simple public instance variables to getter/setter methods at any time, without breaking any existing code. Ruby will even generate the getter and setter for you. Braindead simple.

So, Mr. Danny Coward, here's a proposal for you. I would like the property access operator to be ..

Let me make that more clear: .

You know, the exact operator used in other languages, the exact operator that anyone would expect.

Let the compiler do the work. The -> operator is an approach to make the compiler do less work and the developer do more. That is ass-backwards. I'm slaying dragons over here in Tapestry 5 land, to make the environment bend over backwards to adapt to the user, easily and seamlessly. It would be nice if the overlords in charge of the Java language would take that as their lesson. Complexity is not solved by adding more complexity. Complexity is solved by removing complexity ... even if it requires a bit more work behind the scenes to support that simplicity.

Of course, this may all be a distraction from their main attemmpt to screw the pooch: super modules. More on that soon.

14 comments:

s_dani_g said...

Preach it! I had to work in C# for a while, and the one C# language feature I liked that Java lacks is the built-in property support. I love having it at the language level. This whole JavaBean naming / parameter type / return type convention stinks. I say go with the dot (.) and add some property support at the language level!

Tim Vernum said...

I agree (mostly).
I've posted some similar comments about the Java 7 "features" in my blog.

One disagreement though - I always assumed the reason for it being a new operator was to make it clear to the user that it may have a performance hit.
When C# brought this in, there were a lot of complaints from java people that it was bad for performance. That foo.bar might now actually go and do a database lookup, and that's slow, and the user doesn't know that it's going to happen, because to the user it just looks like a member field access.
I can appreciate that concern, but I don't think we should be driving a whole new syntactical construct out of a unproven fear that developers might get confused by the existing construct.

Now, if it really is about making it easier for compilers (but I'd be surprised) then they have absolutely no excuse for it.

Joe Walker said...

You understand of course that the issue is that methods (i.e. getters and setters) and member variables are in different namespaces. So:

public int foo = 42;
public int foo() { return 42; }

is valid.
The problem when using . is, how do we create simple rules without side cases to regulate this mixing of namespaces.

That's not to sat that I think such a ruleset is impossible, just that I've not tried, and I think the people that say it can't be done are smart.

Howard said...

It's a given that retrofitting something like this into Java is a pain, but that doesn't mean you throw in the towel. Instead of chasing every possible degenerate case, you chase the reasonable cases, and add checks and warnings for the degenerate cases. There's a huge divide between valid and reasonable. Naming your classes "a", "b", "c", etc. is valid but not reasonable.


Also, in your example, it's pretty clear that instance.foo is the property, and instance.foo() is the method. The harder case is for the class to be able to access a property bypassing the accessors, as in, accessing the instance variables. Unclear what that would look like w.r.t. a property keyword (I would prefer an instance variable and a @Property annotation).

s_dani_g said...

Howard - the problem with just annotating instance variables is that you can't add any custom code to the accessors or modifiers (like validity checks, etc). That's why I prefer something like the C# example here.

A.A.A said...

i think you should chek here:

http://weblogs.java.net/blog/forax/archive/2007/01/a_property_prop_1.html

Jesse Kuhnert said...

Yeah, I'm not buying the "it's impossible" argument for supporting what we all know is the best syntax "foo.bar" .

I wouldn't be surprised at all if it isn't easy, lord knows I'd rather not remember anything from my red drag book - but this isn't the kind of area where people come up with half assed solutions I would hope.

I mean, you have access to the language itself. The compiler / interpreter / everything. It's scary to see people proposing things like this.

Anonymous said...

Hi guys,

Stop all these whining. Howard and all those OS proponents, maybe you missed the news that Java is now open source. Why not grab the source, roll up your sleeves and get your hands dirty by implementing that darn thing yourself and release is to the community?

Howard said...

I think you misunderstand ... Sun still owns the Java language, they just have open sourced the code. Ultimately, they still control the TDK, the software suite that validates that a given language is Java. To introduce this kind of change requires a corresponding change to the TDK.

Also, I haven't coded C or C++ in years and years!

Finally, the most important part of open source is the open exchange of ideas, not necessarily code. In this case, the idea that complexity is the problem and the solution is greater simplicity, not the introduction of more syntax.

Anonymous said...

use jruby? done? :)

Massimo said...

For the records: Sun open sourced part of Java not the whole.

And this arguments has no clue about the topic.

jsight said...

This won't happen for backwards compatibility reasons. If you had code such as:

protected int value;
public void setValue (int val) {
this.value = val;
}

And another class calls:
a.value = blah;

What will the new compiler do?

Do you really want code that has radically different behavior depending on whether it was compiled with Java 1.5 or Java 1.7? And you think that merely hiding this difference in a compiler warning will help?

Unfortunately, some less than optimal syntax, or breaking compatibility are your only options.

Java tends to lean towards the latter, and Howard always leans towards the former. :)

Kalle said...

Come on jsight. Surely the visibility of the member attribute should take precedence over property getter/setters. In that case the compiler could give you a warning such as: "Set method for property 'value' never got invoked". If you really want to invoke the setter in that case, you explicitly call the setter, as simple as that.

Java designers have never cared much for the "prettiness", or readability of the language, but this is just absurd. One of the most powerful features of built-in properties is that you can make a simple member attribute at first, and then later change it to a property and do some additional manipulation without having to go through your code and changing every instance of object.value to object->value.

They got it right in Object Pascal/Delphi (20 years ago):
property value : integer read GetValue write SetValue;

Barry said...

I'd be happy if the compiler just generated getter/setter methods for public properties. Typing o.getProp() instead of o.prop does not really make much difference and signals you might be running code on the other side. The following code

o.prop = true;
if ( o.prop ) {
//do some stuff if o.prop is true
}

should do exactly what you would expect.