or learn more

A Response to Ineffectual Java-NG Proposals

Sep 21, 2010

[sourcecode lang=”java” gist=”591070″]// There is a difference between classes and data

// All classes and data are immutable by default public data Person { String name; Int age;

// return type inference
public toString() {
    return name + " is " + age;


// somewhere else

// Chains replace the need for ordered arg ctors // do we really need new all over the place? Each class // defn defines a factory singleton Person p = Person().age(45).name(“Jimmy Jimmy Jim Jim”);

// accessors appear direct;

// shouldn’t println be a first-class citizen by now? // polymorphic print facility stays because it rocks println(p); //// Jimmy Jimmy Jim Jim is 45

// immutability should be a compile-time check = “froby”; //// Compilation Error: attempting to set an immutable field

/* NOTSET */

// What if we do not set a property?

Person p = Person().name(“Jimmy Jimmy Jim Jim”);

println(p.age); ////

// If a field is not set, then it’s type is NotSet // How do we set it? // Answer: you don’t. You create a new object with the field set Person p2 = p.age <- 45;

// <- is an operator that says, take an instance and return a new instance // with some field set

Person p3 = <- “Frobby”, p.age <- 21;

// You can chain the <- operator if you want with commas

// So what do we have here? // = Sets a reference // <- “mutates” a property, returning a new instance // If a property has not been set, then it’s type is NotSet


// Nothing, almost takes the place of null, except that it is // a bottom type // Nothing is different than NotSet in that it is an actual value // rather than a semantic type meaning, “this thing has not been // set” // // So why have both? The reason is that in Java we are often forced to // overload the meaning of null to stand in for both Nothing and NotSet. // By making them types you can now handle them explicitely along different // code paths:

pubic class Foo { void handle(String o) { println(“got a string”); }

void handle(NotSet o) {
    println("was never set");

void handle(Nothing o) {
    println("got nothing");


/* EXCEPT */

// Checked exceptions are out. Missing catches can instead be compiler warnings // try/catch blocks should be cleaner


public class Foo { @invariant(_ < 10) @invariant(_ > 0) Int x;

@pre(n != 0, n != 1)
@post(_ != 0, _ > x)
Int frob(Int n) {
    return x * n;


// invariant checks occur on construction and mutation


// Maps and sequences should have literal syntax

Map<String, Int> m = {“foo” : 1, “bar” 2};

List l = [1,2,3,4,5];

Set s = |1,2,3,4|;

// But what are the concrete types? There can be a default, or there can be a scoped // ctor, or there could be something like:

List l = ArrayList([1,2,3,4,5]);

// or maybe just

List l = ArrayList(1,2,3,4,5);

Map<String, Int> m = HashMap(“foo” : 1, “bar” 2);

// which is literal-syntax-lite

// The point is… if you’re going to invent a new Java that breaks compatability, then // at least try and fix some of the major issues like verbosity, invariants, inference, // checked exceptions, and mutability. Go wild. Everything presented here could be // compiled directly into Java. Pre-processors are go!

// :f [/sourcecode]

7 Comments, Comment or Ping

  1. Lachlan O'Dea

    I’m not seeing much here that can’t be done right now in Scala.

  2. Hence my closing statement.

  3. Bob Hansen

    How do you enforce atomic multi-variant mutations? If I have an invariant that both firstName and lastName must be set for a Name object to be valid, how can I get a compile-time exception if someone writes Person().firstName <- “Ed”;

    Are Lists immutable? Are you sure that’s a price you’re willing to pay?

    Does this support any analogue of JNI that can break your invariants, or must all of your video transcoding run only in a JIT interpreter?

  4. Bob Hansen

    Of course, considering the source, you probably do understand all of the costs.

    I am concerned whether the armies of corporate programmers who haven’t been allowed adequate time and training will be able to use those patterns for the forces of good.

  5. The invariants are run-time checks. However, that doesn’t answer the spirit of your question (which is a very good one BTW). The secret lies in the chaining construction. That is, a chain acts like a constructor but with the advantage of being argument-order independent. The invariant check would occur after the chain is complete.

    Honestly, I haven’t thought much about JNI-type interactions… maybe I would say they should go to make things easier. ;-) :f

  6. Lists are immutable at the ends of the chain. Inside of the chain however the runtime can play some tricks for performance.


Reply to “A Response to Ineffectual Java-NG Proposals”