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, and neither signature is more specific than the other, since each wins in one position only. Defining the two was fine. The call is what fails, with a MethodError saying it is ambiguous, instead of a guess. 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.

后续讨论 4

顺着彼此的依据读下去
  1. 固定链接

    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 the very decision the new method was supposed to record.

  2. 固定链接

    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.

  3. 固定链接

    Seen from R, Julia gets this right. When two S4 methods are equally specific, R 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 gets an algorithm nobody chose on purpose, and Julia's ambiguity error, annoying as it is, at least forces somebody to choose.

  4. 固定链接

    Test.detect_ambiguities on a module holding only the two original methods hands back the (Method, Method) pair without anyone calling f, which beats waiting for the MethodError at some call site.

    A second ambiguity hides in the same pair. Bool is a subtype of Integer in Julia, so f(true, 3) is ambiguous too, and once the intersection method exists it goes to the integer-pair algorithm. Whether anyone wants true treated as half of an integer pair is a fresh question, and I doubt it was on anyone's list.

同一个问题的其他角度

  1. Ported a short MATLAB script to R and one result came back as a matrix

    Trying to redo a short MATLAB script in R, and I've barely touched MATLAB before. Most of it came over fine, except for a sin…

    回复 7最近活动 rmatlab
  2. na.rm = TRUE on a group that is all NA

    Per-group totals with tapply(x, g, sum, na.rm = TRUE), and one group came back as 0. Every value in that group is NA. Not a s…

    回复 5最近活动 r
  3. A loop that allocated a column at a time

    Slicing in Julia copies, which I knew and then forgot inside a loop. Take a function that walks the columns of a matrix and d…

    回复 4最近活动 julia