simplifying use of properties

K

kartik

Currently, use of (JavaBeans) properties requires manual calls to
getter & setter methods. Wouldn't it be better to extend the language
so that an expression "object.foo" (without a '()'), in the absence of
a field named foo, is treated as equivalent to a call to a
getter/setter method (depending on whether the property is being read
or written).

I feel it would be better to do this *not* by a compile-time
transformation but by changing the spec of the getfield & putfield
instructions to invoke a getter/setter method when there is no
matching field. Then, classes can replace fields with properties (or
vice-versa) without hurting binary compatibility (for clients who
access the fields/properties using the "object.foo" syntax).

Maybe static properties should also be allowed.

Any comments? Thank you.

-kartik
 
H

Hal Rosser

kartik said:
Currently, use of (JavaBeans) properties requires manual calls to
getter & setter methods. Wouldn't it be better to extend the language
so that an expression "object.foo" (without a '()'), in the absence of
a field named foo, is treated as equivalent to a call to a
getter/setter method (depending on whether the property is being read
or written).

I feel it would be better to do this *not* by a compile-time
transformation but by changing the spec of the getfield & putfield
instructions to invoke a getter/setter method when there is no
matching field. Then, classes can replace fields with properties (or
vice-versa) without hurting binary compatibility (for clients who
access the fields/properties using the "object.foo" syntax).

Maybe static properties should also be allowed.

Any comments? Thank you.

you can do that by declaring the properties public - but then other classes
would have access - but you don't want that.
 
S

Stefan Schulz

I feel it would be better to do this *not* by a compile-time
transformation but by changing the spec of the getfield & putfield
instructions to invoke a getter/setter method when there is no
matching field. Then, classes can replace fields with properties (or
vice-versa) without hurting binary compatibility (for clients who
access the fields/properties using the "object.foo" syntax).

What if the property is not directly (or at all) backed by any field?
 
K

kartik

Hal Rosser said:
you can do that What?

by declaring the properties public
Meaning, declaring the fields public? That's a bad idea.
[...] but then other classes would have access - but you don't want that.
I want them to be able to call the getter/setter methods using the
field access syntax, but not to access the underlying field used to
implement the property.
 
K

kartik

Stefan Schulz said:
What if the property is not directly (or at all) backed by any field?
The accessor methods may use a field of the object, store the
information somewhere else, compute it on the fly, etc - client code
is insulated from such choices.
 
S

Stefan Schulz

The accessor methods may use a field of the object, store the
information somewhere else, compute it on the fly, etc - client code
is insulated from such choices.

In that case, you do have a problem: If you redefine getfield JVM
instructions to call accessor methods, what do you do in the following
case:


class NoWay {
public int foo;

public int getFoo(){
return 1;
}

public void setFoo(int x){
// ha-ha
}
}

should a setField for foo change the value?
 
J

John C. Bollinger

kartik said:
Currently, use of (JavaBeans) properties requires manual calls to
getter & setter methods.

"Manual" is an odd choice of words there.
Wouldn't it be better to extend the language
so that an expression "object.foo" (without a '()'), in the absence of
a field named foo, is treated as equivalent to a call to a
getter/setter method (depending on whether the property is being read
or written).

Why would it be better? What do you expect to gain by this? I don't
even see the problem you hope to solve.
I feel it would be better to do this *not* by a compile-time
transformation but by changing the spec of the getfield & putfield
instructions to invoke a getter/setter method when there is no
matching field. Then, classes can replace fields with properties (or
vice-versa) without hurting binary compatibility (for clients who
access the fields/properties using the "object.foo" syntax).

If your basic idea were adopted then the compatibility features of your
suggested implementation would be attractive, but their implementation
would be a bit messy. More importantly, however, implementing this in
the JVM would introduce a (Java convention) <-> (bytecode semantics)
relationship that would be wholly inappropriate. Furthermore, although
there would be compatibility advantages going forward, the suggested JVM
change is _not_ fully binary compatible with existing classes because it
does not reproduce the error behavior currently specified by the
language and VM specs (and implemented by the current compiler / VM
combination).

The JVM, although designed to support Java, can and does support other
languages. It's native language, bytecode, is a high-level OO language
entirely of its own. In consideration of those facts I'd argue that it
is entirely inappropriate to implement a change to Java language
semantics by means of a change to bytecode semantics.


John Bollinger
(e-mail address removed)
 
K

kartik

Stefan Schulz said:
The accessor methods may use a field of the object, store the
information somewhere else, compute it on the fly, etc - client code
is insulated from such choices.

In that case, you do have a problem: If you redefine getfield JVM
instructions to call accessor methods[...]
Only when the field doesn't exist. Otherwise, the change will break existing code.
[...]what do you do in the following
case:


class NoWay {
public int foo;

public int getFoo(){
return 1;
}

public void setFoo(int x){
// ha-ha
}
}

should a setField for foo change the value?

Yes. The field is there, so change its value.
 
S

Stefan Schulz

Only when the field doesn't exist. Otherwise, the change will break
existing code.
[...]what do you do in the following
case:


class NoWay {
public int foo;

public int getFoo(){
return 1;
}

public void setFoo(int x){
// ha-ha
}
}

should a setField for foo change the value?

Yes. The field is there, so change its value.

Maybe it is just me, but i think this is a horribly confusing idea with
just no merit. Why should anyone want this? An invokevirtual is a clear
instruction. A setfield is also a clear instruction. Your proposal is
much less clear, and very error-prone.
 
K

kartik

Stefan Schulz said:
[...]what do you do in the following
case:


class NoWay {
public int foo;

public int getFoo(){
return 1;
}

public void setFoo(int x){
// ha-ha
}
}

should a setField for foo change the value?

Yes. The field is there, so change its value.

Maybe it is just me, but i think this is a horribly confusing idea with
just no merit. Why should anyone want this?
Because
window.visible = true
is clearer than
window.setVisible(true)

Besides, properties allow you to avoid defining accessor methods till
you need them, while retaining flexibility to change the
implementation at any time.

No merit? Properties are supported in many languages like Python,
Ruby, C# and (I think) VB.
An invokevirtual is a clear
instruction. A setfield is also a clear instruction. Your proposal is
much less clear

My proposal may make the getfield & setfield instructions a little
more complex, but it increases clarity at the source level - & that's
what matters for most programmers.
[...] and very error-prone.

What makes it so? Because you find the concept "horribly confusing"?
 
S

Sudsy

kartik wrote:
Because
window.visible = true
is clearer than
window.setVisible(true)
<snip>

Not to me. The first implies a public instance variable. The second hides
the actual implementation. And isn't encapsulation a big part of OOD/A?
So you'd mar the beauty of the language just because YOU think that the
first "is clearer"?
Egads! And using abortions like VB and C# to justify your position?
('tis to weep)
 
K

kartik

John C. Bollinger said:
Why would it be better? What do you expect to gain by this? I don't
even see the problem you hope to solve.
It will make code clearer, and more intuitive; instead of:
window.setVisible(true)
you will be able to write:
window.visible = true

Besides, you can avoid defining accessor methods till you need them,
while retaining flexibility to change the implementation at any time.
If your basic idea were adopted then the compatibility features of your
suggested implementation would be attractive, but their implementation
would be a bit messy.
It doesn't seem that way to me. In the code for getfield/setfield,
when you notice that the field doesn't exist, instead of throwing a
NoSuchFieldException, call a method.
More importantly, however, implementing this in
the JVM would introduce a (Java convention) <-> (bytecode semantics)
relationship that would be wholly inappropriate.
Why is it inappropriate? I feel source code clarity is more important
than source -> bytecode mapping.
Furthermore, although
there would be compatibility advantages going forward, the suggested JVM
change is _not_ fully binary compatible with existing classes because it
does not reproduce the error behavior currently specified by the
language and VM specs (and implemented by the current compiler / VM
combination).
Agreed, but how much code depends on such behaviour? If the decision
is taken not to break such code, perhaps the VM behavior can difer
based on the version of the class file (that defines the current
class), or by a flag in the class file. Such a change to the VM
semantics has been done before - method invocation can sometimes
behave differently based on whether the ACC_SUPER flag is set.
The JVM, although designed to support Java, can and does support other
languages. It's native language, bytecode, is a high-level OO language
entirely of its own. In consideration of those facts I'd argue that it
is entirely inappropriate to implement a change to Java language
semantics by means of a change to bytecode semantics.
We are propsing to change the semantics only for what is presently an
error. This doesn't seem inappropriate, given the benefits.
 
S

Stefan Schulz

On 5 Nov 2004 20:35:36 -0800 said:
Because
window.visible = true
is clearer than
window.setVisible(true)

Besides, properties allow you to avoid defining accessor methods till
you need them, while retaining flexibility to change the
implementation at any time.

Well, you have made an argzment (quality nonwithstanding, i disagree even
on source level) for changing source code semantics. This could
either be implemented on the compiler level, in which case it would
generate
an invokevirtual instruction for _some_ field accesses (and all attendent
unclear code path problems). So even if your argument held, there would be
no reason to tinker with the VM instructions.
No merit? Properties are supported in many languages like Python,
Ruby, C# and (I think) VB.

So what? They are in java too (see the public modifier for fields) ;)
My proposal may make the getfield & setfield instructions a little
more complex, but it increases clarity at the source level - & that's
what matters for most programmers.

I really do not see any increase in source clarity, sorry. Where is the
benefit? If anything, it is "syntactic sugar" for accessing setter/getter
methods, and can be included in the compiler. It will however make it
even more of a living hell to explain to novices that a setter/getter pair
need not be backed by one and only one field of the arguemnt type.
 
C

Chris Uppal

kartik said:
Because
window.visible = true
is clearer than
window.setVisible(true)

I think that the biggest thing /I/ dislike about this is that it confuses the
distinct concepts of the /behaviour/ of an object and its /state/.

The /state/ is inherently a private thing in OO (whether or not it's
implemented in private variables -- there's a fairly good consensus that
variables should always be private for OO).

The /behaviour/ is how it behaves in the "ecology of communicating objects"
that forms an OO program.

Now there are two ways to go from their. One is to say that your proposal fails
to distinguish the two, and hence is unacceptably flawed. I think that as you
have stated it, this is the case -- you really are thinking of the first form
above as accessing a variable and want to (be able to) implement it that way.
That leads to the modifications to the JVM behaviour (which is in itself
unacceptable anyway, IMO). It would also lead to confusion about how
"variables" are inherited. Remember that behaviour can be overriden, state
cannot (Java does allow you to 'hide' superclass fields, but they are still
there and are still in use by code that is not overriden).

Alternatively, you can see both the above forms as purely syntactic variations
on a message send. In that case it is purely a matter for the compiler.
There is nothing whatever to stop you defining your own language that
interoperates with Java-compiled classes, but which makes the syntax you prefer
available. It then becomes a question of will anyone else like your variant
enough for it to become popular. Maybe it would, I don't know, but /I/
wouldn't want to bother with it. The reason for that is that I have no great
interest in "setting objects' properties", what I want to do is /send messages
to them/. For instance:
window.beVisible()
is clearer than either of the forms you give above. Even if you look for pairs
of 0-arg, 1-arg methods and label them "properties", then they'll be rare in my
code. So, even if I did think that your first form provided a significant
advantage over the second, I still wouldn't often use it.

To put it another way, what you are doing is providing an optimised syntax for
accessors, but the problem with that is that the very /concept/ of accessors
has no place in OO programming.

I would certainly agree that the function-call-like syntax for message sends
that Java has inherited from C (via C++) is less than optimal. In fact I think
it sucks. But I don't think that patching "properties" onto the language is
going to help. I view the concept as a mistake, or at least as a red-herring,
and am not particularly impressed by any of the languages you mention that
include it. (Though Ruby has some fine qualities too).

-- chris
 
S

Stefan Schulz

The /state/ is inherently a private thing in OO (whether or not it's
implemented in private variables -- there's a fairly good consensus that
variables should always be private for OO).

Well, i can accept package and protected fields, but i usually would prefer
an accessor with that modifier. Fields should never be public, unless
they are final and refer to an immutable object.
 
C

Chris Uppal

Stefan said:
Well, i can accept package and protected fields, but i usually would
prefer an accessor with that modifier. Fields should never be public,
unless they are final and refer to an immutable object.

What I meant was that /whatever/ the actual access flags on the field, the
state is still conceptually private. I.e. it is perfectly possible to do clean
OO programming even if all the fields are public, because the OO programmer is
not /interested/ in the fields, but only in the behaviour, and so will have no
reason to "violate encapsulation" even if the compiler allows it. That's to
say that 'private', 'public', etc declarations on fields are about /enforcing/
a policy, they are not directly part of the policy itself.

That didn't come across clearly in my first post, I'm afraid.

-- chris
 
K

kartik

Sudsy said:
kartik wrote:

<snip>

Not to me. The first implies a public instance variable. The second hides
the actual implementation. And isn't encapsulation a big part of OOD/A?
You've got me wrong. I was only proposing using the first syntax as a
shorthand for the second (when the field doesn't exist).
And using abortions like VB and C# to justify your position?
Are Python & Ruby also abortions? I've used Python, and I feel it's
anything but an abortion.
 
K

kartik

Stefan Schulz said:
Well, you have made an argzment (quality nonwithstanding, i disagree even
on source level) for changing source code semantics. This could
either be implemented on the compiler level, in which case it would
generate
an invokevirtual instruction for _some_ field accesses (and all attendent
unclear code path problems). So even if your argument held, there would be
no reason to tinker with the VM instructions.
There is: preserving binary compatibility, because classes will then
be able to replace public fields with getter/setter methods wihtout
forcing clients to recompile.
So what? They are in java too (see the public modifier for fields) ;)
Once you have a public field in Java, you can't later replace it with
accessor methods without breaking clients. But in Python, Ruby & C#,
you can. That is what I meant by "properties" as opposed to "fields"
or "instance variables".
I really do not see any increase in source clarity, sorry. Where is the
benefit? If anything, it is "syntactic sugar" for accessing setter/getter
methods, and can be included in the compiler.
Certainly, but that will break binary compatiblity when a class wants
to replace a public field with accessor methods, possibly backed with
a private field.
It will however make it
even more of a living hell to explain to novices that a setter/getter pair
need not be backed by one and only one field of the arguemnt type.
Getter/setter pairs that are not backed with fields are used all the
time in Java. I'm only proposing an easier syntax for their use.
Regarding the novices bit, OO theory says that when you call a method,
you should *not* be concerned with how it's implemented. I feel you
should not be telling novices that a getter/setter pair always has to
be backed with a field.
 
K

kartik

Chris Uppal said:
I think that the biggest thing /I/ dislike about this is that it confuses the
distinct concepts of the /behaviour/ of an object and its /state/.
Not at all. I'm only proposing the former syntax as a shorthand for
the latter (when the field isn't there).
[...]there's a fairly good consensus that
variables should always be private for OO).
Who's going against it?
The /behaviour/ is how it behaves in the "ecology of communicating objects"
that forms an OO program.

Now there are two ways to go from their. One is to say that your proposal fails
to distinguish the two, and hence is unacceptably flawed. I think that as you
have stated it, this is the case
No, it's not.
Alternatively, you can see both the above forms as purely syntactic variations
on a message send. In that case it is purely a matter for the compiler.
You can implement it in the compiler, but that will break binary
compatability when a class decides to replace a publlic field with a
getter/setter pair, possibly backed with a private field.
[...] what you are doing is providing an optimised syntax for
accessors, but the problem with that is that the very /concept/ of accessors
has no place in OO programming.
You can't do away with state; you can only encapsulate it. For
instance, when I'm using a window, I'm clear that it's either visible
or hidden. Once you have state, you want to have accessors for
encapsulation.
Therefore, I don't agree with your statement.
 
S

Stefan Schulz

[... Edited and reordered for greater readability]
There is: preserving binary compatibility, because classes will then
be able to replace public fields with getter/setter methods wihtout
forcing clients to recompile.
Certainly, but that will break binary compatiblity when a class wants
to replace a public field with accessor methods, possibly backed with
a private field.

The change you describe is inherently incompatible, though. In fact, the
VM you describe is fundamentally different and incompatible to the current
JVM.

As i will explain later, even if you allowed field access syntax, and
abused
the setfield/getfield instructions of the JVM, the whole change would still
not be transparent. What you argue for is effectively another language with
wholely different concepts. I'll not say that these concepts in themselves
have no merit, but in the Java programming language, they are not
appropriate, since they run against several other principles of the
language's
design.
Once you have a public field in Java, you can't later replace it with
accessor methods without breaking clients. But in Python, Ruby & C#,
you can. That is what I meant by "properties" as opposed to "fields"
or "instance variables".

No, you can't. Think about reflexive invocation - Will work with a public
method, will not work with a inaccessable field, and getter/setter pairs.

Getter/setter pairs that are not backed with fields are used all the
time in Java. I'm only proposing an easier syntax for their use.
Regarding the novices bit, OO theory says that when you call a method,
you should *not* be concerned with how it's implemented. I feel you
should not be telling novices that a getter/setter pair always has to
be backed with a field.

This is what i said. Most assume it has to be backed by a field, and if
you use field access syntax, you reinforce that notion. I just wonder where
you got the idea i was telling anyone that is has to be that way?
 

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
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top