VarArgs through out the api

Mainly for creating quick prototypes var args are great.

Var-args have been in Java since 1.6? Var-args are very useful, makes the code consice and cleaner. And it is trivial to add them to the API.

instead of:


Vector3f[] knots = new vector3f[4];
knots[0]= new Vector3f(0,0,0);
knots[1]= new Vector3f(1,2,0);
knots[2]= new Vector3f(0,0,2);
knots[3]= new Vector3f(0,2,0);

Curve curve = new BezierCurve("curve",knots);



couble be:


Curve curve = new BezierCurve("curve",new Vector3f(0,0,0),new Vector3f(1,2,0),new Vector3f(0,0,2),new Vector3f(0,2,0));



Just add the contructor:


BezierCurve(String name, Vector3f... controlPoints){
...
}

varargs have been out since jdk 1.5 and are in several portions of the jme code base.



As for a lot of varargs, it can get quite messy.  I find it is often easier for longer amounts of var args to put them together in an array and pass it in.



it's a matter of preference for the coder, but if it's more than one or two items I pass it in as an array of sometype rather than listing all the items in the method arg.



I agree that in locations where var args are useful should at least be made vararg compatible… however, if you've ever worked with OpenGL… there's nothing compatible there that wasn't written by another implementation.



That sounded better before I typed it, and I think my pain med has kicked in… it's time for me to stop typing before I say something stupid… like I'm going to write a game that fetches beer for me… in a few minutes if that game did exist I'd be licking my monitor.



gotta go

Quote:
Thanks for the tutorial on how varargs worked, though, that was very useful. 
mojomonk said:
mpliment...thank you.  :P

mojomonk said:

My main point is there are many places where you are going to have to maintain the arrays yourself anyways, and therefore, var args is not needed.


To that I agree. :)
I'll go ahead and ignore the eye roll and take that as a compliment...thank you.


You're welcome...  :roll:

:)

Stop with the eye rolling already! 

It's easy to get seduced into using new language features, libraries, frameworks, etc. just because they're new and cool.  As soon as people got their hands on generics, suddenly no-one seemed to be able to write code without generics any more, and I've seen people re-writing existing and working code-bases to introduce new features (with the predictable faults that introrduces).  As an experienced (i.e. old) developer I saw the same thing with templates in C++ when they came out.



If there's a valid case for using a newer feature then go for it, otherwise follow the KISS principle (Keep It Simple Stupid).  Personally I've never actually used a vararg, although generics, extended for loop, autoboxing and annotations I use as a matter of course.



By the way, in your example the API could be modified to use a vararg parameter, but IMHO your code would be less maintainable.  It's a lot easier to modify an array declaration than a parameter list.



Compare:



final Vector3f[] vertices = new Vector3f[]{

    new Vector3f( … ),

    new Vector3f( … ),

    new Vector3f( … ),

    new Vector3f( … ),

};

… = new BezierCurve( vertices );



with your single line method invocation using varargs.



With the array entry declarations on different lines its easy to delete / add entries.



Note that you don't need to declare the size of the array, and the last element has a comma after it (still only four elements, but easier to maintain).

if i remember correctly, there already was a discussion about varargs a while ago (couldn't find the thread anymore). the devs evaluated the option of using varargs and decided against it because of performance reasons.

You can still pass an array to a var arg argument.  But yeah just passing a list of arguments to something called every update would create a new array each time which some people might not realise.



I don't see any reason to update all the existing code to use var args but I also don't see why any new code couldn't use them.

Gentleman Hal said:

I don't see any reason to update all the existing code to use var args but I also don't see why any new code couldn't use them.


you said it yourself: it creates an array for each call. imho that outweighs the fanciness of varargs :P

Only if you pass it a list of arguments, not if you pass it the array yourself.



So therefore it's useful for stuff like quick prototyping as Patmania mentions or for methods that are only called once in a while.

I find varargs can be very useful in many circumstances.



JGN makes use of varargs for things like:


public static final Thread createThread(Updatable ... updatables) { ... }



This is very nice because originally I had it just take one Updatable (and most circumstances that's how it's used) and it didn't require any of the rest of my code to change to make this feature addition.  Further, in new code that only has a single Updatable it doesn't require me to create an array of 1 or create another method to handle it.

Finally, I like the look of:

createThread(server1, server2, server3);


to:

createThread(new Updatable[] {server1, server2, server3});



They can be overused like everything in code, but I personally find it very beneficial to decrease the complexity of my code and make it much more manageable.

Its handy when prototyping. Makes Java less verbose. I cannot see how this should effect performance though as it is a pre-compilation thing. In the end its equivalent to the code it replaces at a byte code level as far as I understand.

Like everything, it has its place. What you have to remember is the API was written with 1.4 in mind, therefore, many of the syntactical sugar introduced in 1.5 is not used. We update to 1.5 when working on classes, and deemed necessary. We did run into garbage generation problems when making uses of var args in a tight loop, but constructors, etc. would be perfectly fine with me.

You asked why var args would create garbage in a tight loop if you were already creating the array. My response is that if you are already creating the array (and therefore SHOULD be creating the array), then var args isn't needed, and probably isn't desired if its usage is negative in performance.



Thanks for the tutorial on how varargs worked, though, that was very useful.  :roll:



My main point is there are many places where you are going to have to maintain the arrays yourself anyways, and therefore, var args is not needed.


mojomonk said:
We did run into garbage generation problems when making uses of var args in a tight loop....


Really? Wouldn't you get the same garbage generation if you're generating a new array yourself in a tight loop?

My feeling is, if you are already creating the array, then there is no need for the var args.



I.e.



Object[] x = {a. b. c};

blah.someMethod(x);



looks the same whether the signature of blah.someMethod() is (Object … ) or (Object[])



The only time var args helps the user of the API is when then don't want to create the array (it is syntactical sugar after all so it is purely used for code clean-up and ease of use).



My opinion.

…I don't think you believe that.  :stuck_out_tongue:


MyObject[] objects = new MyObject[] {one, two, three, four};
doSomething(objects);



or

doSomething(one, two, three, four);



This allows you to remove the need for creating the array.  However, if what you meant was that if you already HAVE to create the array then no need to bother with varargs.  To that I would agree if you can guarantee that no one else will ever call that method/constructor that does not already have an array.  Benefit of varargs is you can just pass it an array and it works just like if it took "MyObject[] args" instead of "MyObject ... args" so you never really lose anything from varargs in the situation of expecting more than one object, but just gain.  However, in a situation where you might just be receiving one object you are creating garbage for that array of one.

The garbage of creating an array for one object is not so much of an issue because presumably there is not a constructor or method to take just one item anyway. And you all know the general guidelines for optimization so I shall avoid eye roll inducing patronage. A tiny amount of garbage for such an event would be at the bottom of the optimization priority heap yet would give more aesthetic code.

The point being made is that we've done it in jME in the recent past, it was in a tight loop, and the garbage created was horrendous.  Constructors, or rarely called methods seem to be the best candidates for this syntax.

Agreed.