I've got some math/geometry stuff going on here which has given me a
curious problem. I have some generic stuff, and now need a generic
ball, parametrized by P, which is supposed to be a class of geometric
point from some sort of space or another. Determining if a point lies
in the ball when the ball is centered on the origin will be simple: I
require P to implement an interface or extend a class that defines an
abstract modulus-squared method, and see if the modulus squared fails
to exceed the ball radius squared.
Determining the ball's number of dimensions has me stumped. This needs
to be done where there isn't a preexisting instance of P handy.
Obviously, P can't be guaranteed to implement a no-arguments
constructor that could be used to get a dummy instance. If P is
required to implement an *interface* named Point, I can't specify that
there be a static method getDimensions() or similar. If P is required
to extend an *abstract class* named Point, I can put such a static
method in Point, but not override it in a subclass. Same with a static
method to get a dummy instance.
Of course, I could just have a single concrete Point class built on an
array and a method to return its length, but this is less type-safe
(points of different dimensionalities could get mixed up). I could use
a Point class built on an array, declare it abstract, and only make
concrete subclasses that fix the number of dimensions. That would solve
it, but there's an added complication: complex numbers. Vector spaces
over both R and C may occur, and the dimension over R is twice the
plain dimension in the latter case...and what if I go and add
quaternions or some such later on? Ack! I figured a more open-ended
framework using interfaces as much as possible would be better, but
there seems to be no clean way to get the number of dimensions (over R,
or generally) in that case, short of praying you can use a construction
to turn P into a run-time classname and using a lookup table or
something equally ugly.
Any suggestions?
Twisted - 11 Jun 2006 15:15 GMT
Crap, it's worse than I thought. Even if I force all points to derive
from an abstract class that backs onto an array of reals, I'd still
need an instance of the concrete subclass to extract the dimensions
from. Bah!
Miss Elaine Eos - 11 Jun 2006 15:43 GMT
> Of course, I could just have a single concrete Point class built on an
> array and a method to return its length, but this is less type-safe
> (points of different dimensionalities could get mixed up).
Generic point class stores dimensions as double [], and can have a
length() function, or just a getDimensions() one, to which you query the
.length paramter.
If it's important to keep differently-dimenisoned points separate, then
you'll need a point4d, point5d, point6d, etc. class which extends your
basic point.
Nice thing is: you can pass a point6d to some functions that need the
restriction, and just a pointGeneric to functions that don't care.

Signature
Please take off your pants or I won't read your e-mail.
I will not, no matter how "good" the deal, patronise any business which sends
unsolicited commercial e-mail or that advertises in discussion newsgroups.
Chris Uppal - 11 Jun 2006 18:14 GMT
> I've got some math/geometry stuff going on here which has given me a
> curious problem. I have some generic stuff, and now need a generic
> ball, parametrized by P, which is supposed to be a class of geometric
> point from some sort of space or another.
You may be trying to generalise too narrowly (if you see what I mean ;-)
Rather than parameterise your logic on the points that make up the space (and
what do you do about lines, etc ?) parameterise on the space itself. Thus the
point class is determined by the space, not the other way around.
(Actually, I suspect that you may be trying to use generics for something to
which they are not well adapted. The touchstone is this: could you implement
the /same/ design, in a clear, simple, and easy-to-use form, without using
generics at all (at the cost, perhaps, of some loss of self-documentation and
static type-safety) ? If not, then generics won't buy you anything. They can
turn a decent dynamically-typechecked design into a decent
statically-typechecked design (at the cost, perhaps, of some loss of
transparency); but, unlike C++ templates, they don't extend the range of
available designs).
-- chris
Twisted - 11 Jun 2006 18:53 GMT
> [Generics] can
> turn a decent dynamically-typechecked design into a decent
> statically-typechecked design (at the cost, perhaps, of some loss of
> transparency); but, unlike C++ templates, they don't extend the range of
> available designs).
I know that. I found a (messy) solution: put a dummy Class<P> parameter
in the constructor, which is used to newinstance() a P to ask it its
dimensionality.
I've got a different generics headache now. Check for a similarly
titled new post.
Thomas Hawtin - 11 Jun 2006 20:05 GMT
> I know that. I found a (messy) solution: put a dummy Class<P> parameter
> in the constructor, which is used to newinstance() a P to ask it its
> dimensionality.
I suggest rather than using reflection on class, you use another object.
So, something like:
interface Point { ... }
interface PointMeta<P extends Point> { ...}
class SomeThing<P extends Point> {
private final PointMeta<P> meta;
public SomeThing(PointMeta<P> meta) {
this.meta = meta;
}
...
}
class XyzPoint implements Point { ... }
class XyzPointMeta implements PointMeta<XyzPoint> { ...}
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Twisted - 11 Jun 2006 21:41 GMT
> I suggest rather than using reflection on class, you use another object.
>
[quoted text clipped - 13 lines]
> class XyzPoint implements Point { ... }
> class XyzPointMeta implements PointMeta<XyzPoint> { ...}
Thanks. This avoids the problem that the point class may lack a no-arg
constructor.