Hacker News new | ask | show | jobs
by lukego 924 days ago
My impression is that this comes down to expectations.

You might have a function:

foo(x,y) = x + y

and multiple dispatch means you can call that with integers, or floats, or arrays, or GPU-resident arrays, or automatically-differentiating numbers, or symbolic algebra terms, or...

Just because you can, does that mean you should? It depends...

1 comments

I think it was more like you have a function over an abstract type like:

foo(x::Number) = x+1

And then someone else creates a new type thats a subtype of Number. And they run foo(x) and get errors or unexpected output.

Problem is the new type they created doesn't follow the assumptions that foo expects. Throw multiple dispatch into the mix and it gets even harder.

> foo(x::Number) = x+1

> Problem is the new type they created doesn't follow the assumptions that foo expects.

If you define that function and someone else (i.e. a user of your lib) defines a subtype of Number and calls your function on it, and it fails, then they haven't respected the interface to Number. There's nothing wrong with that function or type specialization in that case. In that case it's all about defining useful interfaces and respecting, as much of programming is.

E.g. if someone defines a subtype of Number because he has something that's kind of like a number in some respects but not others, maybe that shouldn't be an subtype of Number.

You also shouldn't define functions that have obscure conditions for being properly useable - at least if you expect your code to be useful more broadly. Nothing here is specific to Julia though.

If you have other specific examples we could discuss more.

    using Unitful: m; foo(2.0m)
With the above definition, this will give DimensionError: 2.0 m and 1.0 are not dimensionally compatible.

Probably this means you should define `foo(x::Number) = x + oneunit(x)` to respect the Number interface. But this interface isn't very strictly defined. I believe `Base.oneunit` was added after someone started writing the Unitful package -- building something useful in a legal grey area, and formalising later?

Interesting case! Lets discuss.

I don't know/use Unitful, but if that function didn't fail it's because the guys who wrote Unitful defined a promotion rule from Int to their Unit thingy. So.... that's how their type works. Don't use it. Or better, open an issue on github, they might have an explanation that's escaping us. I suspect it has to do with their mental model of what Unitful is supposed to achieve.

Let me tell you that my intuition agrees with you. As an ex-physicist, if I was designing a lib called Unitful I wouldn't let you sum sum 1 meter plus 1 unitless thing.

EDIT:

Actually, I just tried running your code and I do get DimensionError

    foo(2.0m)
    ERROR: DimensionError: 2.0 m and 1.0 are not dimensionally compatible.
I'm guessing you have some seriously outdated versions of something?

EDIT2: Sorry I misread you. You do get an error. Ok I see your point. Maybe the Julia docs should more explicit about what the Number interface entails. Is `+ 1` allowed? You're assuming the answer is obvious, but it's not to me. In particular, that's not generic at all. You're probably right about `+ oneunit(T)`