October 2009


Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Sean Luke <[log in to unmask]>
Reply To:
MASON Multiagent Simulation Toolkit <[log in to unmask]>
Thu, 29 Oct 2009 11:12:01 +0100
text/plain (154 lines)
So the problem with (B) is this.  Let's say that M (and M0) is a  
MutableDouble2D and D (and D0) is a Double2D.

If I say:

Double2D Q = D.add(M)
Double2D Q = D.add(D0)

This will put into Q the result of D+M (or D+D0), but neither D, nor  
D0, nor M will be modified.

However if I say

MutableDouble2D Q = M.add(D)
MutableDouble2D Q = M.add(M0)

This will put into Q the result of D+M (or M0+M), but also set M to  
that result.

I would imagine this would be... fairly surprising.  Wouldn't you?   
That's what concerns me.


On Oct 29, 2009, at 10:49 AM, Matthew Berryman wrote:

> Sean,
> I agree with your points on (B), and this would be personally least  
> surprising to me, given the other existing methods (it is mutable,  
> after all :)
> I'm just a sample size of one, though.
> Cheers,
> Dr Matthew Berryman
> Defence and Systems Institute
> SPRI Building
> University of South Australia
> Mawson Lakes  SA  5095
> t +61 8 8302 5882
> f +61 8 8302 5344
> m +61 413 458 594
> CRICOS Provider Number: 00121B
> On 29/10/2009, at 7:40 PM, Sean Luke wrote:
>> Not hearing a peep from the peanut gallery :-( I'm inclined to make
>> the (B) modifications.  Going once, going twice?
>> Sean
>> On Oct 27, 2009, at 7:41 PM, Sean Luke wrote:
>>> I'm facing a tough decision on Double2D which could affect the
>>> entire community and so I'm interested in some feedback.
>>> I've been going through the physics2d engine and doing some cleanup
>>> and one thing that could really help in that cleanup is to add some
>>> functions to Double2D which are presently only in MutableDouble2D,
>>> but to do so in such a way that Double2D's version would have
>>> somewhat different semantics.
>>> MutableDouble2D has four kinds of ways of "adding":
>>> MutableDouble2D m1, m2, m3;  // 2d vectors
>>> double v;  // a scalar
>>> m1.addIn(m2);   // m1 <- m1 + m2, return m1
>>> m1.addIn(v);    // m1 <- m1 + v (at all slots in m1), return m1
>>> m1.add(m2, m3); // m1 <- m2 + m3, return m1
>>> m1.add(m2, v);  // m1 <- m2 + v (at all slots in m1), return m1
>>> The use of "add" in this context is unfortunate, I know.  It's going
>>> to cause problems in a second.  But originally my idea was to enable
>>> stuff like this:
>>> m1 = new MutableDouble2D().add(m2, m3).multiplyIn(v).normalize();
>>> Which does
>>> 	m1 <- normalize((m2 + m3) * v)
>>> ... but doesn't do any new allocations at all, because at each step
>>> we just overwrite the variables inside the MutableDouble2D we  
>>> created.
>>> Okay, so that's cute.  The problem comes when I want to add similar
>>> functionality to Double2D.  I can't implement an "addIn" method
>>> because Double2D is IMMUTABLE.  Instead, I'd do something like this:
>>> Double2D d1, d2, d3;
>>> double v;
>>> d1 = d2.add(d3).mutiply(v).normalize();
>>> This does the same thing but at each step a new Double2D is
>>> created.  For example,
>>> d1.add(d2);	// new d <- d1 + d2, return d
>>> That's a good, easy to understand functional style which is much
>>> less convoluted than the MutableDouble2D approach, BUT it allocates
>>> lots of Double2Ds, which isn't particularly efficient, though it's
>>> not horrible.  So it's a useful functionality to have in Double2D.
>>> The problem is that the semantics are somewhat different than
>>> MutableDouble2D's semantics, in which the original object is
>>> OVERWRITTEN.  This is particularly obvious in the normalize()
>>> method, which in MutableDouble2D normalizes the actual
>>> MutableDouble2D, but for Double2D would produce a new Double2D (it's
>>> have to).
>>> Also MutableDouble2D's add(...) method, for example, takes two
>>> arguments and has totally different semantics than Double2D's
>>> add(...) method would.
>>> I'm trying to nail down what options I have.  One choice I have been
>>> mulling over is to add methods to Double2D like add(d) [note one
>>> argument], multiply(v), etc., and then also create similar
>>> MutableDouble2D methods with the same names.  But the question is
>>> how the MutableDouble2D methods should work.  Should they (A)
>>> produce NEW MutableDouble2D instances or (B) overwrite the existing
>>> MutableDouble2D instance, like other MutableDouble2D methods
>>> presently do?
>>> (A) is more semantically consistent with the proposed new Double2D
>>> methods.
>>> (B) is semantically consistent with the existing MutableDouble2D
>>> methods.
>>> I'm trying to follow the principle of least surprise but I don't
>>> know which of these would have less surprise.   normalize() in
>>> particular will *have* to be case (B).  There's no way around it.
>>> Which has been nudging me to wards doing (B).   A third option would
>>> be to just create Double2D methods and not create ANY equivalent
>>> MutableDouble2D methods.
>>> The decision made here will have a long-standing effect on use of
>>> these classes, and they're so integral to MASON that I want to be
>>> very very careful.  Backward compatability will be retained but I am
>>> concerned about making things weird in the future.
>>> So I'd really appreciate some opinions on the matter.
>>> Sean