Am 28.07.2012 19:59, schrieb Ronan Lamy:
We do need double-dispatch, no matter what, though.
I know it's sometimes unavoidable.
It should be avoided as far as possible.
> We already do it, in
a rather haphazard fashion.
Systematic is of course better.
Well, my implementation doesn't have a disambiguation rule. It raises an
error instead.
Okay, that's good.
What they will get is an exception telling them which rules apply, i.e.
{(C, A), (B, C)}, {(C, B), (A, C)} or {(C, A), (B, B), (A, C)},
respectively. It's then up to the user to fix their code.
That's even excellent :-)
It gets worse. If the type hierarchy gets extended (say, a new class is
inserted between B and C), you'll find that with almost all
disambiguation rules, there will be cases where an existing call will
now disambiguate to different code than it did before.
You can't do that in Python (or, at least, you really shouldn't).
It's essentially unavoidable in the case of disambiguating double
dispatch. (Well, sort of - the design choices that go with
disambiguation tend to come with that price.)
Since Python does not have double dispatch, I think it's out of the loop
here.
One way to deal with this all is to insist that all slots in the grid be
filled explicitly.
To the very least, you'll need to run a full set of tests for every grid
slot, just to make sure that whatever algorithm is chosen for each
combination of parameter types, the result is correct.
We should already be testing every slot of the grid for correctness, so
there isn't much of an additional testing burden. With this
implementation, it's easy to check that every combination dispatches
correctly.
Good.
The quadratic blowup isn't exactly nice, but type hierarchies typically
don't get deep enough to make that a really serious problem (not on
modern hardware anyway). Also, you can cut corners by leaving grid slots
open at the bottom of the hierarchy - but extending a type hierarchy
downwards means that those slots have to be filled, so this needs to be
explained in comments.
sympy has a lot of classes, and runtime class generation doesn't help,
so the quadratic blowup in the number of possible interactions is a
concern.
Well, try to keep the dispatching matrices small.
For arithmetic operators, the usual way out is to convert the more
specialized operand to the more general one.
That's fine for numerical code, but sympy has too many completely
different kinds of objects for this strategy to be applicable.
I was just explaining the various strategies that I have seen applied;
maybe somebody with a better grasp of the class structure of SymPy can
apply them in a useful manner.
I'm most definitely recommending one or the other strategy!
And in fact I'm not sure whether anything but filling in the whole grid
will work for symbolic math.
However, in those cases where a conversion is possible, it's usually
preferrable to convert. For every N types that can be interconverted,
you get rid of N-1 rows and columns in the matrix; if matrix size has
become a concern, that's useful.
I hope this is helping :-)
Regards,
Jo
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy?hl=en.