Print

Print



On Oct 29, 2009, at 12:04 PM, Sean Luke wrote:

[Miles's message didn't appear to get through]

Thanks Miles.  A couple points:

- I gather from this that you would find "functional" (non-modifying) style to be surprising.  This is interesting because it's not what I would intuitively expect would be the hope of most coders.

I guess I should say that the semantics of that are pretty much always unclear to me. I'm not surprised because I'm already unsure.. :) I expect that value to be returned, but I also "worry" that the value had been modified.  The problem is that Java has trained me to see any method calls as potentially modifying. See what I mean?


- Deprecation is always an option.  If I went with option (A), I'd probably consider deprecating certain methods in MutableDouble2D.  But I've always tried to be very slow and conservative on MASON so as to avoid having to deprecate much.

Yes, but it happens. Check the Apache libs for example, IIRC there are a few examples of what we are talking about here.


- You mentioned polymorphism, so I thought I'd mention that interestingly Double2D and MutableDouble2D do not derive from one another; and likewise similar other pairs in MASON (Int2D, Double3D, Int3D)  The reason for this is straightforward: in both cases I want users to be able to access the instance variables directly rather than be required to use methods like getX() and setX(), which would *not* be inlinable (indeed, non-inlinability s a major problem for the java.awt.Point family as a result).  The problem is that Double2D needs to have those variables final, while MutableDouble2D can't have them final.  There's no way in Java to derive a class and change the finality of certain instance variables.  It's plausible to make them subclasses of the same interface I suppose.

Right, I forget that you have a goal of absolute performance. But sure, provide a higher level set of getters. Or again, an argument for using static methods.

Or I've been using the Provider pattern a lot recently, probably because Eclipse is so deep into them. But it's kind of cool, because you can just do something like..

interface LocationProvider {
  double getX(Object o);
  double getY(Object o);
  double getZ(Object o);
  boolean is3D(Object o);
}

Assume you know what kinds of locations will be in your space, i.e. they aren't mixed. What you do is provide an adapter that returns a provider appropriate for the set. If they are you're going to have to decode types then you'd have to do instanceof which isn't terribly pretty but just fine for a lot of usages.

MasonMutable2DLocationProvider {
getX(Object o) {
return ((MutableDouble2D) o).getX();
}
...
}

MasonImmutable2DLocationProvider {
getX(Object o) {
return ((Double2D) o).x;
}
...
}

Now this isn't ideal performance, but the idea is that this is for users / extenders of the API, and typically performance isn't dominating concern as it might be for internals. (And folks that do need it will need to take responsiblity for using the underlying API correctly.) Then consumers of your classes just don't have to worry about it but you can make the underlying mechanics as rich and appropriate as you like. And even more neatly, you can interpret,  cache, translate, etc.. And since you're going to have to do the translation somewhere anyway if a view doesn't know what it's going to get, you might as well do it in one place.

This is exactly what I'd do for MASON adapters for AMP just as a little for instance.. ;)

btw, if this one doesn't get through, please forward to list..

Miles T. Parker
President and Chief Software Architect
Metascape, LLC

tel: 509-643-4441
skype: milestravisparker