openlang

모호한 Julia 메서드와 f(2, 3)

Julia 메서드 두 개가 있어요. f(x::Integer, y::Number)와 f(x::Number, y::Integer)예요. 정수인 인자가 어느 쪽이냐에 따라 각각 다른 알고리즘을 써요. f(2, 3.0)은 첫 번째로, f(2.0, 3)은 두 번째로 가요. 여기까지는 문제없어요.

이제 그 실수 인자를 정수로 바꿔 볼까요? f(2, 3)은 둘 다에 맞고, 두 위치 모두에서 더 구체적인 시그니처가 없으니 Julia는 추측하지 않고 모호성 오류를 내요. 그럴 만하죠.

매뉴얼이 권하는 해법은 교집합을 맡는 세 번째 메서드 f(x::Integer, y::Integer)예요. 추가하면 오류는 사라져요. 그런데 답이 무엇이어야 하는지는 알려 주지 않아요. 정수 쌍은 그 자체로 별개의 수학적 경우일까요, 아니면 두 알고리즘 중 하나를 일부러 빌려 써야 할까요? 모호성 오류는 오히려 쉬운 부분이었어요. 원래 두 메서드는 이걸 정할 필요가 없었는데, 이제는 누군가 정해야 해요.

이어지는 대화 3

서로의 근거를 따라
  1. 고유 링크

    순서대로 가 봐요. 세 번째 메서드를 쓰기 전에, 같은 정수 쌍, 예를 들어 (2, 3)에 대해 각 알고리즘이 무엇을 계산해야 하는지 먼저 적어 봐요. 그다음 둘을 비교해요.

    거기서 수학적으로 같은 결과를 낸다면 교집합 메서드는 둘 중 하나를 의도적으로 고르면 돼요. 다음에 읽는 사람이 그 선택을 알 수 있도록 정수 쌍 예제를 몇 개 붙여 두고요.

    결과가 다르다면, 모호성을 잠재우려고만 만든 메서드는 진짜 질문을 가려 버려요. 그때는 정수 경우에 고유한 의미를 주거나, 호출하는 쪽이 원하는 연산을 다른 방식으로 고를 수 있게 해야 해요.

    구현은 맨 마지막이에요. 그리고 인자 하나를 부동소수점으로 바꿔서 기존 메서드로 보내는 건 피해 주세요. 동작은 하지만, 새 메서드가 기록해야 할 바로 그 결정을 묻어 버려요.

  2. 고유 링크

    ajp 님 방식보다 절차를 줄여도 괜찮을 것 같아요. 정수 쌍에 따로 수학이 필요 없다면, 세 번째 메서드는 고른 알고리즘의 헬퍼를 그냥 호출하면 되고, 겹치는 경우가 갈 곳이 하나로 분명해져요. 옆에 문서화한 f(2, 3) 예제 하나만 두면 다른 두 시그니처를 보고 선택을 짐작할 필요도 없고요. 이 정도면 충분하겠어요.

  3. 고유 링크

    내가 보기엔 R의 S4 디스패치가 이 경우를 더 나쁘게 처리한다. 두 메서드가 똑같이 구체적이면 거부하지 않는다. 자체 순서 규칙으로 하나를 고르고, 고른 메서드를 알리는 노트를 찍고, 그냥 진행한다. 노트는 스크롤되어 지나간다. 그래서 정수 쌍은 아무도 일부러 고르지 않은 알고리즘을 조용히 받게 되고, 귀찮긴 해도 Julia의 모호성 오류는 ajp가 말한 결정을 강제한다.

    R의 정수 메서드에는 경우가 하나 더 있다. NA_integer_도 정수라서 그 쌍에 포함되고, 교집합 메서드는 결측값을 어떻게 다루는지도 정해야 한다. 결측값은 산술이 우연히 돌려주는 값이 아니라 메서드가 문서로 밝힌 의미에 속해야 한다.

같은 질문의 다른 갈래

  1. 암묵적 확장이 내 크기 버그를 행렬로 바꿔 놨다

    행 벡터와 열 벡터를 .로 곱하면 예전엔 오류였다. R2016b부터는 아니다. a = [1 2 3], b = [1; 2; 3]이면 a . b는 모든 쌍의 곱으로 채운 3×3 행렬이 되고, 경고도 없다. 행이라고 생각한 자리에…

    답글 2matlab