This came up in https://github.com/simonster/Memoize.jl/pull/18, what is the correct semantics of functions that declare a return type of Any? Are they exactly the same as not declaring a return type? Since whatever type is returned satisfies T<:Any, I would expect them to have the same meaning. The method definition expression is different as a macro that takes a function definition can see the AST node with ex.args[1].head == :(::) in the case of return types and no such node when there is no return type declared.
Would it be safe to add a return type declaration of Any to all functions that do not declare an return type?
Return type annotation means any value returned will be converted to that type (or an error is thrown). convert(Any, myvar) is a no-op as it dispatches to convert{T}(::Type{T}, x::T) = x. Thus, indeed, return type Any is identical to not declaring one.
Thanks @mauro3. This resolves my question for Memoize. Memoized functions will default to a return type declaration of Any even if the original function has no return type annotation.
FWIW, there’s a few wrong information in this comment…
This is mostly true, though there’s nothing that stops the user from overwriting it (they shouldn’t but still).
No, it dispatches to convert(::Type{Any}, x::ANY).
The behavior is ideally the same if no one have defined. It can in principle also cause performance decrease though the inference seems to be ok at this.