Value types and parameter names

John Rose john.r.rose at oracle.com
Sun Dec 7 09:30:48 UTC 2014


On Dec 1, 2014, at 11:02 AM, Lovro Pandzic <lovro.pandzic at gmail.com> wrote:
> 
> On the other hand, without setters, the only way for constructing those
> value types in those frameworks would be to use those constructor if they
> have parameter names available at runtime.

The counterpart of a "setFoo" method for an immutable class would be "withFoo":

    final __ByValue class Point {
        public final int x, y;
        public Point(int x, int y) { this.x = x; this.y = y; }
        public Point withX(int x1) { return new Point(x1, y); }
        public Point withY(int y1) { return new Point(x, y1); }
    }

I think the same clunky tricks as can be done for "setters" can also be done for "with-ers".

(Word note:  "wither" has unpleasant connotations compared to "setter".  A setter is a nice dog, a wether is a sad goat.)

The awkwardness of working with "with-er" methods is well-known.  For example, in a paper I was just browsing:

> Abrahams: I've done a fair amount of programming in LISP, and there is one situation which I feel is symptomatic of the times when you really do want an imperative language. It is a situation that arises if you are planning to do programming in pure Lisp and you find that your functions accumulate a large number of arguments. [1] This often happens when you have a nmnber of variables and you are actually going through a process and at each stage of the process you want to change the state of the world a little bit--say, to change one of these variables. So you have the choice of either trying to communicate them all, or trying to do some sort of essentially imperative action that changes one of them. [2] If you try to list all of the transitions from state to state and incorporate them into one function, you'll find that this is not really a very natural kind of function because the natures of the transitions are too different. [3] [Landin, "The Next 700 Languages", CACM, March, 1966]

[1]: Or, in 2014, Java value types with many fields.
[2]: Perhaps with an auxiliary Java builder class.
[3]: Result:  Lots of little boilerplate Java functions, or use one class but cope with non-final fields.

He's talking about LISP and the difficulty of updating one variable in a coordinated group of several; he wants a notation for changing the variable without getting fouled by side effects.  I imagine him thinking back then, "we will surely figure this out soon enough".  He is feeling after an imperative way of expressing a declarative result, and noticing that expressing all possible state transitions as separate functions is unnaturally verbose, just as in the case of withX/withY. Apparently we are still figuring this out, although more options have been put on the table in the last half century. The "do" blocks of Haskell show one way to bridge the gap between imperative and declarative.  To get this right in Java might require doing some similar trick, but within the native Java "worldview" of classes and "culture" of safe coding.

(As an escape hatch, Java has annotation-driven method generators and Lisp has macros.  I'd prefer to avoid those when possible.)

— John


More information about the valhalla-dev mailing list