News for hackers. Stuff that matters.
Re:Java 9 features announced by memonkey on Monday August 18, 2014 @02:47PM (#8193915)
Sorry to ask, but as a noob who just picked up Java, how do other languages address this issue? What's wrong with getters and setters?
Re:Java 9 features announced by mythz on Monday August 18, 2014 @03:58PM (#8194302)
IMO Dart has the best implementation of properties, which you can start out as normal fields, e.g:

    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).
Re:Java 9 features announced by ppog on Monday August 18, 2014 @05:20PM (#8194751)
Your comment about changing a field to a property being a breaking change in C# is correct, but in practice, C# programmers tend to use auto properties (e.g. public int Left { get; private set; }) rather than public fields. These are fully fledged properties, but the getters and setters are implemented by the compiler (and back directly onto a compiler-generated field). Because they are properties, they can then be changed to computed properties (or e.g. validation added to setters) without breaking binary or reflection compatibility.
Re:Java 9 features announced by tieTYT on Monday August 18, 2014 @04:56PM (#8194623)
Why does it matter if it's binary compatible? How does that affect the programmer? I guess I don't understand the difference/significance between binary and source compatibility?

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.

Re:Java 9 features announced by mythz on Monday August 18, 2014 @05:11PM (#8194706)
Binary compatibility is important when accessing properties of a type defined in another Assembly, i.e. if an Assembly was updated where a Field was changed to a Property it would break access from dependent Assemblies.

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.

Re:Java 9 features announced by dragonwriter on Monday August 18, 2014 @05:21PM (#8194760)
> 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.

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.

Re:Java 9 features announced by depoll on Monday August 18, 2014 @05:55PM (#8194934)
Another important aspect of properties in C# is that they are a target for metadata (i.e. Attributes). This is something that's frustratingly broken with the method getter/setter approach. And while you can fix it by convention (e.g. a priority list for lookup on the getter, then setter, if those exist), it ends up being inconsistent and unnecessarily painful.

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).

Re:Java 9 features announced by srgpqt on Monday August 18, 2014 @04:55PM (#8194620)
Ruby is quite similar.

attr_accessor :left, :top, :width, :height, :right, :bottom

And you can change these to computed properties (regular methods) later without affecting the callsites

Re:Java 9 features announced by roller on Monday August 18, 2014 @05:29PM (#8194807)
In C#, these aren't 100% source-compatible either. For example, you can't pass properties using ref or out parameters.
Re:Java 9 features announced by zmmmmm on Monday August 18, 2014 @07:17PM (#8195222)
Amusingly, your Dart solution is exactly what Groovy does, which is where this whole thread started.
Re:Java 9 features announced by mateuszf on Monday August 18, 2014 @04:23PM (#8194440)
afaik scalas properties are as good as in case of dart. Also, operations like + are also normal methods on numbers.
Re:Java 9 features announced by Tloewald on Monday August 18, 2014 @02:59PM (#8193995)
The purpose of a getter or setter is to abstract the implementation out from the usage. Computed properties (e.g. C#'s ability to replace a concrete property with a virtual property without breaking any code) do this without requiring mindless implementation (boilerplate code) for the common case (a property that is exactly what it seems to be).

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.

Re:Java 9 features announced by bassman7755 on Wednesday August 27, 2014 @03:28AM (#8231132)
The problem is that you cant add computed accessor methods to java without breaking code backwards compatibility. This is because a public fields and a public methods have different inheritance semantics - public field access does not trigger polymorphic resolution. Hence auto replacing it with a access method would break any code that relies on the static resolution of the public field (i.e. resolution by referencing type). To fair there probably isnt much code out there that would fall foul of this since there isnt any good reason to write code that relies on public field "hiding" by subclasses, but it would be technically non backwards compatible.
Re:Java 9 features announced by TylerE on Monday August 18, 2014 @03:28PM (#8194144)
In python the default is that things that look like attributes/properties REALLY are direct access. If you later need to shim them out into a function you use the @property decorator (and foo.setter if you need read/write)

    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)
Re:Java 9 features announced by rch on Monday August 18, 2014 @05:03PM (#8194664)
Thanks for mentioning this. I've found the Python approach works really well in practice.
Re:Java 9 features announced by malisper on Monday August 18, 2014 @07:09PM (#8195199)
The problem with getters and setters is that the code for them is nearly identical, yet they have to be written in nearly every single class:

  // 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.html
Re:Java 9 features announced by redtrackker on Monday August 18, 2014 @02:53PM (#8193951)
What's wrong with getters and setters?

It'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

Re:Java 9 features announced by hugozap on Monday August 18, 2014 @02:53PM (#8193949)
For c# just:

public int Age{get;set;}

no need to declare private variable, get or set methods.

Re:Java 9 features announced by Tloewald on Monday August 18, 2014 @02:59PM (#8193998)
And you can replace it with a virtual property in the future (changing the underlying implementation) without breaking anything. And user code ends up simpler and more readable too:

foo.baz += foo.bar;

vs.

foo.setBaz( foo.getBaz() + foo.getBar() );

Re:Java 9 features announced by HanyouHottie on Monday August 18, 2014 @04:57PM (#8194634)
That example reminds me of this recent post on The Old New Thing: http://blogs.msdn.com/b/oldnewthing/archive/2014/08/14/10549...

Interesting behavior.

Re:Java 9 features announced by Tloewald on Tuesday August 19, 2014 @09:35AM (#8197162)
Of course, setters don't protect you from this either.
Re:Java 9 features announced by aikah on Monday August 18, 2014 @02:59PM (#8193997)
C# introduces the concepts of fields and properties. I dont remember which is which but I think properties are in fact getters and setters,without the verbose "object.getProperty()" syntax , you just write "object.property" and it's call a getter function or a setter function.

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.

Re:Java 9 features announced by pjmlp on Monday August 18, 2014 @03:36PM (#8194178)
> C# introduces the concepts of fields and properties.

This goes back to at least Eiffel (1985).

Re:Java 9 features announced by muchabi on Monday August 18, 2014 @04:02PM (#8194329)
To add another example to the list, Ruby lets you list which attributes can be read/written and which ones can only be read on top. Something like.

  class Car
      attr_reader :model, :company # only read
      attr_accessor :color # read and write
  end
Re:Java 9 features announced by dopamean on Tuesday August 19, 2014 @11:19AM (#8197760)
It's worth noting that in Ruby the difference between attr_reader and attr_writer is not the same as read only and write only. You can write to something set with attr_reader. All attr_writer does is allow complete reassignment of that particular instance variable.

This 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.