openlang

Ambiguous Julia methods and f(2, 3)

Two Julia methods, f(x::Integer, y::Number) and f(x::Number, y::Integer). Each runs a different algorithm, chosen for whichever argument is the integer. f(2, 3.0) lands on the first and f(2.0, 3) on the second. No trouble so far.

Now turn that float into an integer. f(2, 3) matches both, neither signature is more specific in both positions, and Julia throws an ambiguity error instead of guessing. Fair enough.

The manual's fix is a third method, f(x::Integer, y::Integer), for the intersection. Add it and the error is gone. What it doesn't tell you is what the answer should be. Is an integer pair its own mathematical case, or should it borrow one of the two algorithms on purpose? The ambiguity error turned out to be the cheap part. The original two methods never had to decide this, and now somebody does.

The conversation continues 3

Follow the reasoning
  1. Permalink

    Let's take it in order. Before writing a third method, put down what each algorithm is supposed to compute for the same integer pair, say (2, 3). Then compare the two.

    If they give the same mathematical result there, the intersection method can pick one of them on purpose. Add a few integer-pair examples so the choice is visible to the next reader.

    If they disagree, a method that exists only to quiet the ambiguity hides the real question. The integer case then needs a meaning of its own, or callers need a different way to say which operation they want.

    The implementation comes last. And please don't reach an existing method by converting one argument to a float. It works, and it buries exactly the decision the new method was supposed to record.

  2. Permalink

    Less ceremony than ajp's version works too. If integer pairs don't need their own math, the third method can just call the chosen algorithm's helper, and the overlap has one obvious place to go. Put one documented f(2, 3) example beside it so nobody has to work the choice out from the other two signatures. I think that's enough here.

  3. Permalink

    R's S4 dispatch handles this worse, in my view. When two methods are equally specific it doesn't refuse. It picks one by its own ordering rule, prints a note naming the method it chose, and carries on. Notes scroll by. So the integer pair quietly gets an algorithm nobody chose on purpose, and Julia's ambiguity error, annoying as it is, forces the decision ajp is describing.

    One more case for the integer method in R. NA_integer_ is an integer, so the pair includes it, and the intersection method has to say what it does with a missing value too. Missing values belong in the method's documented meaning, not in whatever the arithmetic happens to return.

Other sides of the same question

  1. Implicit expansion turned my shape bug into a matrix

    A row vector times a column vector with . used to be an error. Since R2016b it isn't. With a = [1 2 3] and b = [1; 2; 3], a .…

    Replies 2matlab