Multimethods are awesome. I think anyone who’s interested in Julia will agree with that. But I would like to ask an “out there” question: are symmetic multimethods - vs non-symmetric ones - worth the trouble?
Reasons I’ve found in the literature to prefer symmetric multimethods:
- They’re more “natural”: why prefer one argument to another?
- Better error messages: since type checking is now solely dependent on relative specificity, we capture more errors rather than tie-breaking to the function with most specific left-most argument.
(That’s all I could find. If anyone else can point me to other explanations, or indeed papers that discuss the issue of symmetric vs. non-symmetric MM, that would be kind.)
Now let’s list the negatives:
- Type checking non-symmetric multimethods is easy and efficient. Just compare specificities between methods argument-by-argument, left to right. Implementing symmetric multimethods is basically still a research topic - although one handled quite admirably by Julia.
- According to some articles - which I’ll admit to not fully grokking - it’s impossible to do separate compilation of modules using symmetric multimethods, but it’s apparently straightforward to do with non-symmetric multimethods.
- Arguably non-symmetric multimethods are more predictable for the programmer in the trenches, for exactly the same reason that the type-checking algorithm is easier to implement: you can basically run the type-checking algo in your head.
- It’s manifestly the case that in the real world, you get several methods that would accept the particular arguments in question. In Julia, my understanding is that in certain ad-hoc cases, specific tie-break rules are inserted, simply to avoid annoying the crap out of users. If you’re going to do this, why not just settle on a clear, easy to remember, rule, regardless of how arbitrary it is?
- Moreover, a generation of programmers have been trained to view the left-most argument as special. Instead of telling them to ditch that thinking, why not expand on it and say, yes, that argument is kinda special but now we’re relaxing things so it’s not the only one that’s special?
What I’m hoping for is some slam dunk example where non-symmetric multimethods just yield a surprising and bad result. I honestly can’t think of any obvious ones, but my imagination is sadly limited and there aren’t a lot of (any, actually) statically-typed languages with non-symmetric multimethods, so it’s hard to find examples.
- artihmetic operations? craziness there? I don’t think so. If think non-symmetric MMs can cope with these just fine – after all, they’re still using the extra arguments. By the way, if you’ve ever written
1.0 * x * ...to make sure that the expression is converted to floating point as soon as possible, you’re kind of thinking like a non-symmetric MM person!
- in the case of “OO” programming it’s hard to see how non-symmetric MMs suffer. Actually they seem to me more natural. Maybe I’m missing something.
I’ll finish off by saying that it appears that a lot of very smart people gravitated quite decisively to symmetric MMs, despite the manifest difficulty for language implementer. Since they’re likely a lot smarter than, I’m probably missing something.
I invite you to set me straight
[Oh, and sorry for asking a question that’s only perhaps tangentially related to Julia. I hope it doesn’t bother the community.]