Confusion about type stability: functions or methods?

Hi!

Reading the documentation about type stability actually made me unsure if I understood the concept correctly.

The documentation states that

When possible, it helps to ensure that a function always returns a value of the same type.

(emphasis mine)

By that definition, even + is not type stable, since 1 + 1 and 1 + 1.0 do not return a value of the same type.
Is it just the case that + is not type stable or should the definition actually talk about methods instead of functions?

Or maybe I’m totally misunderstanding the bigger picture?

2 Likes

The documentation can probably be updated to say method rather than function.

5 Likes

I think it’s both.
Functions and Methods (of functions) should be type stable or in both type instability should be avoided.

I think it’s both.

No, if a function has methods that return different types but, in some context, the Julia compiler knows which method will be called then there is no type instability.

There is no sense in avoiding type instability of functions (as opposed to methods). If things worked that way, DataFrames.jl should not extend Base functions like sort for their dataframes, but this is actually harmless for the type-stability of other contexts that use Base.sort.

1 Like

I think the cleanest correct version of it is that given a function and a fixed set of input types.

2 Likes

I guess “function” is often used in a loose sense to mean either function or method. Otherwise we should write

function f end

but

method f(x)
    return 2x
end
2 Likes

Maybe this interpretation works: “…it helps to ensure that a function always returns a value of the same type for a given set of input types.” This should be the case for both functions and methods.

Something like foo(a::A, b::B) where {A,B} should consistently return a consistent type, but if you use a different {A2,B2} it can return something of a different type, and do that consistently. If the compiler can’t infer the return type, then bar(foo(a,b)) can be problematic, because bar may not know what types to compile for until run-time, and/or compile complex code that will work for any type. (Just my interpretation as an amateur.)

1 Like

Isn’t that how multiple dispatch in Julia works? If so it would be equivalent to saying method instead of function in the documentation.

I could be wrong, though.

What would be the next step to make this happen?
I can offer my help if required!

No, that’s up to the user. For example, f(x) = x>0 ? true : -1.0 doesn’t return a consistent type. Note that Julia doesn’t have a formal distinction for functions vs. methods, and you can do methods(f) for anything. The only difference is in your mindset and intention, and even that isn’t formal. It’s unlike object-oriented programming in that regard.

2 Likes

Reading my post you are referring to made me realize it’s not very clear. What I meant was the last part of the quote: “a given set of input types”. Isn’t the function name (and module name) together with the types of it’s arguments enough to specify method dispatch? If so, replacing the word function with the word method in the documentation section would mean the same thing as “given a set of input types”.

Are you sure? I though the difference is that functions are callable objects you define in the code and consist of just a name, while methods are the thing that is the result of (multiple) dispatch and contains the actual code that gets evaluated.

methods are the thing that is the result of (multiple) dispatch

I can define

julia> function g(x); x>0 ? true : -1.0; end
f (generic function with 1 method)

Did I define a method or a function? In my delusion, I defined a function and never thought about how many methods (one, I am told). Nevertheless, that is type-unstable, and the docs should help us avoid that. So I believe the clarification that really matters is that the same type be “for a given set of input types”, which applies to both methods and functions, with the latter being the more general term and what you actually write.

At the top of the manual page you linked there is an Edit on Github button which takes you to the source markdown file. You can either edit the file in Githubs interface or change it locally in a fork of the Julia repository. Then make a pull request and wait for feedback.

3 Likes

You are right, I guess I conflated the word method with general code specialization made for argument types by the compiler.

I can do that, however, I think after this discussion I actually prefer the wording from @apo383:

@apo383, do you want to create a PR or are you fine with me using your wording?

Edit:
Interestingly, the FAQ section of the documentation has a much clearer explanation of type stability, which is also quite similar to what @apo383 suggested.

From Methods · The Julia Language :

The choice of which method to execute when a function is applied is called dispatch. Julia allows the dispatch process to choose which of a function’s methods to call based on the number of arguments given, and on the types of all of the function’s arguments

The meaning of “function” seems to be a bit overloaded (pun intended) in general for Julia. The example given in the FAQ section above shows a single function being defined with unstable return type. The text says “… Julia can’t predict the return type of this function at compile-time …”. Perhaps it would be more correct to say it can’t predict the type of this function or “method”.

As aren’t methods the only thing that actually have anything to do with type-stability? I.e. although you write function calls in your code and use function to add methods to a Julia function, but the only thing that ever actually gets executed with a concrete set of values is a method. Plus, having two type-stable methods for the same function return different types is not type-unstable, as only one is called based on the concrete types used at the call site.

Edit: arggh, I missed some of the posts above, where these points were already made. Sorry for the noise.

Hello Fedario

It took me a long time to understand type stability…

Maybe this Writing type-stable Julia code - #SINTEFblog will be useful?

:grinning:

Philippe

1 Like

Thanks for the input!