Fluent interfaces for JME3

I'm a huge fan of fluent interfaces and like the idea of being able to call more than one function on an object without having to reference it by its name over and over again. Sometimes I don't even have to give that object a name which makes it even more appealing to me.



http://en.wikipedia.org/wiki/Fluent_interface



Introducing fluent interfaces should not break any existing code[1] and make the usage of all different kind of objects easier.



e.g.:



PointLight light = new PointLight();
light.setLocation(new Vector3f(0, 0, 100));
light.setAmbient(new ColorRGBA(0.3f, 0.3f, 0.3f, 1.0f));
light.setDiffuse(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f));
light.setSpecular(new ColorRGBA(0.5, 0.5f, 0.5f, 1.0f));
LightState ls = new LightState();
ls.attach(light);



could also be written as:


LightState ls = new LightState()
    .attach(new PointLight()
        .setLocation(new Vector3f(0, 0, 100))
        .setAmbient(new ColorRGBA(0.3f, 0.3f, 0.3f, 1.0f))
        .setDiffuse(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f))
        .setSpecular(new ColorRGBA(0.5, 0.5f, 0.5f, 1.0f))
    );



I'm a bit undecided if non-setter functions like attach() should be fluent too. Since the fluent style is not mandatory but can rather be seen as an addition to the "original style" I think this could help JME3 to become even sexier than it already is.

The fluent interface can be used to produce ugly and unreadable code, but that is true for non-fluent interfaces as well so I don't consider this a real issue.


[1] It could break existing code that utilizes reflections to introspect the return value of setters, but that's very unlikely and since JME3 is still alpha should be simple to fix in the applications using JME3 that way.

I do like the fluent language style, I've used it many times in DSLs like JQuery.  My question is would it cause JME3 to become thread unsafe or would that not be an issue?

O.o srysly?

When I see the above example I just think OMG…



But more technicall, I think you might get problems, when you have setters that return if it was succesfull.

SomethingNew said:

I do like the fluent language style, I've used it many times in DSLs like JQuery.  My question is would it cause JME3 to become thread unsafe or would that not be an issue?


Fluent interfaces are just as thread (un)safe as any other interface. In fact even synchronized setters will continue to work as expected.

Empire Phoenix said:

When I see the above example I just think OMG...


When I first touched this kind of interface I didn't like it much either, but it saves a lot of typing effort and makes Java slightly less chatty. It also enables you to generate anonymous objects that you never want to assign to a variable that I find handy sometimes.

Empire Phoenix said:

But more technicall, I think you might get problems, when you have setters that return if it was succesfull.


These kinds of setters are a very special case. Either the setter could be changed to throw an exception on failure (IllegalArgument, IllegalState, etc.) or this setter is simply not eligible for a fluent interface.

Just think of the fluent api as the double-brace style...

new PointLight() {{
    setLocation(new Vector3f(0, 0, 100));
    setAmbient(new ColorRGBA(0.3f, 0.3f, 0.3f, 1.0f));
    setDiffuse(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f));
    setSpecular(new ColorRGBA(0.5, 0.5f, 0.5f, 1.0f));
}};



...without the extra subclasses involved...

new PointLight()
    .setLocation(new Vector3f(0, 0, 100))
    .setAmbient(new ColorRGBA(0.3f, 0.3f, 0.3f, 1.0f))
    .setDiffuse(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f))
    .setSpecular(new ColorRGBA(0.5, 0.5f, 0.5f, 1.0f));


To be honest i don't find it a lot more readable.

And the benefit of it is not that huge imo.



Besides, the work to change the entire API so that every setter returns its instance seems a bit heavy…



But i'm gonna discuss this with Normen and Momoko_fan

The doublebrace style isnt good for a fast code and for a small memory footprint.

http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization



I dont like this style.



Regards

snareoj2 said:

The doublebrace style isnt good for a fast code and for a small memory footprint.


I don't like this style either. It looks like syntactical sugar, but really is not. Although I don't think efficiency is really a problem here. Sane real world code does not create bazillions of these classes.

And yes, there were 1000 .class files generated by compiling the Test1 double brace initialization test program.



made my day :slight_smile:

I do like when an API allows to chain method calls. There’s a bit of masochism in that because my experience with fast prototypes tells me that chaining is the second worst idea I can have (the first being anonimity).



Anyway, introducing the proposed style doesn’t require a change in the current JME API: it could be done in a “tool” library via creator objects.



The PointLight example will be:



PointLight pl = new PointLightCreator()

.setLocation(new Vector3f(0, 0, 100))

.setAmbient(new ColorRGBA(0.3f, 0.3f, 0.3f, 1.0f))

.setDiffuse(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f))

.setSpecular(new ColorRGBA(0.5, 0.5f, 0.5f, 1.0f)).

.get();




It works the same but for the “get” that interrupts the chain of setters, and there is no need to clutter the code of the generated type.

The builder pattern is also quite common, but I fail to see a huge benefit over the fluent interface integrated right into the objects. Having a separate builder class only makes sense for non trivial object construction. Guava (Google Core Libraries for Java) got some nice API for immutable collections and various other things, but I don’t see a real benefit in case of JME objects.



Though I haven’t dug too deep in the new JME3 API. I just started getting my fingers wet with JME after more than one year of not doing anything 3D related.

I think the benefit is that the core api doesn’t have change, so your idea could be implemented right now, as an optional library.

Changing the return value from void to some object does not hurt unless someone is doing some ugly reflections trickery. So I’d consider this a backwards compatible API change. Nothing is changed or removed. Existing code using JME wouldn’t even notice that API change.



I plan on writing a script to change all setters to fluent API style and see if some unit tests fail. I highly doubt it, but one never knows unless it’s tested.

In my view this makes only sense for certain areas of the engine, as for example the math package, where it is already used to some extent. For the rest of the API, I’d consider this a minor, arguable coding improvement with enough implications to step back from it.

Cheers,

Normen

Changing the return value from void to some object does not hurt



ACtually even if it is not used at all in your whole code it means one more low level reference per call (as you could call them per reflection) while seeing harmless, if in a code that runs dozens of times per frame it helps greatly to waste speed(garbagecollect) and ram usage without really any gain other than saving one strg+c strg+v at edit time

EmpirePhoenix said:
Changing the return value from void to some object does not hurt

ACtually even if it is not used at all in your whole code it means one more low level reference per call (as you could call them per reflection) while seeing harmless, if in a code that runs dozens of times per frame it helps greatly to waste speed(garbagecollect) and ram usage without really any gain other than saving one strg+c strg+v at edit time


This is it. I would rather wait and see what Java 7 has to offer in this respect.

After all, this kind of constructs are meant only for changing the feel of the language in the face of the developer, in an artificial way. It is not something you want in any professional library.

I would like this kind of simplification if it were supported natively by the language, without adding any bit of burden to the executable. It would be better to knock the Java 7 guys door than here.

Edit2: I just took a look at the Coin project and is already late for Java 7 to include this. Java 8 it is then ;)...
EmpirePhoenix said:
(...) if in a code that runs dozens of times per frame it helps greatly to waste speed(garbagecollect) and ram usage without really any gain other than saving one strg+c strg+v at edit time


You're neither producing more garbage nor use more RAM.

"new Foo().setX(42).setY(0)" produces just as many garbage as "Foo foo = new Foo(); foo.setX(42); foo.setY(0);". Of course the fluent interface has to push the return value to the stack, but it is popped from the stack right for the next call. It is just some extra stack pushing-popping instead of leaving one "foo" variable on the stack for the entire surrounding scope.

jiyarza said:
This is it. I would rather wait and see what Java 7 has to offer in this respect.


I'm heavily debating with myself if I should switch over to Scala for my own code. Java 7 and Java 8 might be an answer, but unless these "new" Java Versions break backwards compatibility, I'm unable to see where they are going to revolutionize the way we write Java code. Java 5 introduced a lot of sugar (generics, auto boxing, for-each loops, etc.) and every time I think about these new things I have to bang my head against a wall and cry out "why not break backwards compatibility and just do it right?". Java's success comes from the long history of being backwards compatible, but it has reached a point where it should consider a complete language redesign and ditch some stuff that was simply a bad idea in the beginning. Maybe that rewrite I'm talking about is Scala, Clojure, Groovy,... (you name it) - but I'm doubtful that these languages will survive the next 5-10 years. Scala looks promising and when the IDE support continues to evolve it might be the programming language I've been looking for all the time.

Well, I did not intend to hijack my own thread with a language debate so I better stop here. From the overall reaction it looks like people agree that fluent interfaces are a good idea but that they should be part of the language and not realized with some obscure "setter with this-object return value" pattern?

jiyarza said:
After all, this kind of constructs are meant only for changing the feel of the language in the face of the developer, in an artificial way. It is not something you want in any professional library.


I have to disagree here. A lot of "professional libaries" come with a fluent interface. Google does it in Guava, Hibernate and the Java Persistance API are fluent, EasyMock has a fluent interface, ... there are plenty more and I'd call them "professional libraries".

I agree it would be a nice feature to have.



Also you are right about those frameworks. Note that they are all productivity frameworks. That’s all good for most coding monkeys in the IT world (such as myself). My mistake, I should have said realtime graphics libraries.



About switching to Scala… Maybe we will all one day. It’s on Oracle’s roof.





Cheers.

I don’t think this is a good idea.

You usually base your entire jme application on data anyway, so the scene stores the light, you never actually explicitly initialize a light and then set all its parameters like that. This is why being data-driven is good, you can have an easy syntax like

light position=“xyz” color="#FF0000" radius=“123”

etc.

Well actually I initialize my lights that exact way, but from a Database with a small wrapper wich is why i don’t care, i only have to write it once anyway.