Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crazy idea: dispatch on return type #19206

Closed
martinholters opened this issue Nov 3, 2016 · 6 comments
Closed

crazy idea: dispatch on return type #19206

martinholters opened this issue Nov 3, 2016 · 6 comments
Labels
compiler:lowering Syntax lowering (compiler front end, 2nd stage) speculative Whether the change will be implemented is speculative types and dispatch Types, subtyping and method dispatch

Comments

@martinholters
Copy link
Member

I couldn't find any discussion of this idea, so I thought I'd bring it up.

The idea is to introduce special syntax for the "desired return type" argument present in some functions along with special handling in dispatch. I haven't completely thought this through, but would like to stir up some discussion. Let me explain by example. I'll abuse function return type/type assert syntax, so please ignore the present meaning for now. (Syntax up for debate, of course.)

function foo()::Int
    return 1
end
function foo()::String
    return "bar"
end
x = foo()::Int # returns 1
x = foo()::Integer # returns 1, too
x = foo()::String # returns "bar"
x = foo()::Array # MethodError (no such method)
x = foo()::Any # MethodError (ambiguous)

Note the reversed subtype matching compared to argument types, in that foo()::Integer invokes foo()::Int.

That is, a function definition including ::T promises that the function will return a value of (any subtype of) type T (and may well imply wrapping the return value in convert(T,...)::T to ensure that). A function call including ::T will invoke a method annotated with ::S such that S<:T. If there is more than one such method, the least specific (in the return type) one will win. So continuing the example:

function foo()::Number
    return 2.0
end
function foo()::Any
    return nothing
end
x = foo()::Number # returns 2.0
x = foo()::Any # now returns nothing

A function call without ::T annotation is equivalent to ::Any. For function definitions I see two options, i.e. bar() = 0 could be equivalent to

  • bar()::Any = 0
  • bar{T}()::T = 0.

With the first option, bar() returns an Int, while bar()::Int disappointingly errors. With the second option, bar()::Int would work (and bar()::Float64 could either fail a typeassert in 0::Float64 or do convert(Float64, 0)). Dispatch involving type parameters as the return type would require more thought than I have invested up to this point, though.

What would be the benefits? IMO, a dedicated syntax for the desired return type is much clearer than the current "return type or return type's element type or function that could be a constructor as first argument" convention:

map(Float64, 1)
map(Float64, (1, 2))
rand(Float64)
rand(Float64, 1)
zeros(Float64)
zeros(Float64, 1)

(Yes, two of those do return a Float64.) Also, reversing the subtype relation in dispatch for the return type seems logical, although I'm not too sure this translates into any real benefits, as the current return type as argument approach does work.

Note that I am not proposing to automagically infer the required return type of a function depending on the context where it is called.

@jw3126
Copy link
Contributor

jw3126 commented Nov 3, 2016

One less "always first" argument makes also #19150 a bit cleaner.

@yuyichao yuyichao added the compiler:lowering Syntax lowering (compiler front end, 2nd stage) label Nov 3, 2016
@stevengj
Copy link
Member

stevengj commented Nov 3, 2016

See also #10269 and @JeffBezanson's thesis discussion of arrow types.

@stevengj stevengj added types and dispatch Types, subtyping and method dispatch speculative Whether the change will be implemented is speculative labels Nov 3, 2016
@vtjnash
Copy link
Member

vtjnash commented Mar 29, 2022

c.f. OpaqueClosures

@vtjnash vtjnash closed this as completed Mar 29, 2022
@jonas-schulze
Copy link
Contributor

c.f. OpaqueClosures

Do you have a specific issue we could we more about?

@o314
Copy link
Contributor

o314 commented Mar 30, 2022

From #37849 one can read :

Passing an opaque closure to a high order function will specialize
on the argument and return types of the closure, but not on the
closure identity

Any information is welcome :)

@bc0n
Copy link
Contributor

bc0n commented May 12, 2022

I certainly don't appreciate the challenge of automagic output type inference, but that would be a great and natural feature. My particular case is writing functions where the user may provide basic types or Unitful and needs particular return types to avoid type errors in later calculations. Ignoring any performance benefits from #37849, C-style overloading on input and output types keeps implementation details in the function definition and avoids subjecting users to unnecessary arguments or function name permutations for type consistency. imho.

For clarity @vtjnash, is this closed because it is judged the same as #37849, blocked by it, it's old (2016), or just not on any roadmap?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:lowering Syntax lowering (compiler front end, 2nd stage) speculative Whether the change will be implemented is speculative types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

8 participants