class Rectangle {
num left, top, width, height, right bottom;
}
and can access like normal: var height = rect.bottom - rect.top;
But can later be changed into a computed property without affecting the above callsites, e.g: class Rectangle {
num left, top, width, height;
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
C# is a close 2nd, but it's not binary (or reflection) compatible to change from a field to a property for call-sites (i.e. it's only source-compatible).attr_accessor :left, :top, :width, :height, :right, :bottom
And you can change these to computed properties (regular methods) later without affecting the callsites
I'm surprised to hear that it's not reflection compatible. As a Java programmer, I assumed that was the main point of C# properties: Create a property now because there's no logic needed, but if you need logic in the future you can change the code and nobody outside needs to be aware of the change.
In .NET Reflection, Fields and Properties have distinct API's, i.e. fields can be accessed with `type.GetFields()` and properties with `type.GetProperties()`. The API's are basically wrappers around how they work, i.e. Fields let you get/set an instance's field value whereas with Properties you're instead invoking the properties getter/setter method accessors.
That's the point, but its not directed at reflection, and reflection goes around behind the scenes of the superficial access-notation compatibility. Which does make properties a badly leaky abstraction, which is problematic since their main reason for existing is to plug a leak in the abstraction provided by the method/field distinction.
Consistency of access in Java is also really problematic for the same reason. Which pair of getter/setter methods represents a reified property? This is often done by naming convention, that's usually, but not always consistent (getFoo/setFoo is common, but there's also isFoo/setFoo, isFoo/setIsFoo, foo()/foo(value), etc.). Worse (and this is something both Android's flavor of Java SDK and Objective-C have fallen prey to), not all properties are written symmetrically (e.g. getText() and the various setText() methods on an EditText in Android, although there are some where all of the setters are subclasses of the only getter -- even worse).
As an added bonus, you don't need to write foo.getBar(), you can just write foo.bar and it Just Works, whether foo.bar is a concrete implementation or a computed property.
Look at this blog post for example:
http://java.dzone.com/articles/java-properties-without
The sad thing is the request here is for something more ugly than what is really wanted (this is just automatic getter/setter implementation -- computed properties are better both for developers and consumers of their output.
class Blah(object):
foo = 2 # A normal property. Direct access
@property
def bar(self):
return self.some_lookup_method()
@bar.setter
def bar(self, value):
self.set_the_bar(value) // Sorry if there are any mistakes, I have not
// written any Java code for quite some time.
public class Point
{
private int x;
private int y;
.
.
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void setX(int newX)
{
x = newX;
}
public void setY(int newY)
{
y = newY;
}
}
Look at how long the class definition is for something so basic!In Common Lisp there are two ways to define classes/structures, defstruct and defclass. Defstruct[0] automatically automatically defines everything for you:
(defstruct point x y)
will define the procedures make-point, point-x, point-y, (setf point-x), and (setf point-y). The cool thing is that they are all procedures. It easily change the class definition without changing the code that uses it. There are also some additional options for defstruct to specify default values, how to print the structure, as well as what prefix to use (the default is the name of the structure, 'point' in this case).Defclass[1], while much more verbose than defstruct, is much more powerful:
(defclass point ()
(x :writer set-x :initarg :x)
(y :reader get-y :initarg :y)
(z :accessor z))
will define procedures, set-x, get-y, z, and (setf z). Set-x and (setf z) are the setters, while get-x and z are the getters. To construct a point that is defined this way, one has to use the procedure make-instance which will take keyword parameters[2] :x and :y, for x and y respectively. [0] http://www.lispworks.com/documentation/lw445/CLHS/Body/m_defstr.htm
[1] http://clhs.lisp.se/Body/m_defcla.htm
[2] http://www.gigamonkeys.com/book/functions.htmlIt's just redundant code. Most of the time developers don't actually need to override the basic get/set operation on a variable. Yet you have to write the get/set methods over and over.
How do other languages address this issue?
Scala does a good job. You don't need to actually write a get/set method. But if you wanted to modify getFoo() you would simply implement the method with your custom getter
public int Age{get;set;}
no need to declare private variable, get or set methods.
foo.baz += foo.bar;
vs.
foo.setBaz( foo.getBaz() + foo.getBar() );
Interesting behavior.
Basically you keep states encapsulated without have to manually write methods,you just write methods when you need then.
Java verbosity on that matter is totally unecessary.
Granted when one use an IDE refactoring features can help,but still... A great strenght of the Java language is its stability.But stability doesnt mean a language needs to be that verbose.
This goes back to at least Eiffel (1985).
class Car
attr_reader :model, :company # only read
attr_accessor :color # read and write
endThis is pretty trivial so bear with me... If you have something that looks like this...
class Person
attr_reader :children
def initialize
@children = []
end
end
You can then do this... x = Person.new
x << "Bobby"
You will have then altered the value of @children without completely reassigning it.