# Could \`Base.\_return\_type\` ever be inferable?

**URL:** <https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057>\
**Category:** Internals & Design\
**Created:** [December 29, 2017, 12:16pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057 "2017-12-29T12:16:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [December 29, 2017, 12:16pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/1 "2017-12-29T12:16:11Z")

</div>

I’m far from an expert on how Julia inference works, but I ran into a situation where I could more succinctly define some type-stable custom promotion/conversion rules if `Base._return_type` was inferable, and was curious if this was possible theoretically. Basically this:

```julia
foo(::Int) = 3
foo(::Symbol) = :a

# Julia knows here the return type is going to be Int64
foo(3) 

# why can't it know here that the return type of *this* call is Type{Int64} ? 
Base._return_type(foo, (Int,)) 

```

I dug into the code a bit and it seems like the key is whether what the `_methods` function does is inferable, although I haven’t gotten any further and was curious to hear from any experts on this.

EDIT: minor change of `Int` → `Int64` above for clarity.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 29, 2017, 12:30pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/2 "2017-12-29T12:30:14Z")

</div>

I am not sure I understand your question correctly, because the type **is** inferred:

```julia
julia> VERSION
v"0.6.2"

julia> foo(::Int) = 3
foo (generic function with 2 methods)

julia> foo(::Symbol) = :a
foo (generic function with 2 methods)

julia> Base._return_type(foo, (Int,))
Int64

```

And the return type is not `Type{Int}` (which would be the type of the _type_ `Int`), but `Int`.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [December 29, 2017, 12:35pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/3 "2017-12-29T12:35:40Z")

</div>

Sorry, to clarify, I mean inferred in the following sense,

```julia
julia> using Base.Test

julia> @inferred Base._return_type(foo, (Int,))
ERROR: return type Type{Int64} does not match inferred return type Any
Stacktrace:
 [1] error(::String) at ./error.jl:21

```

So the type of what `Base._return_type` returns is indeed `Type{Int64}`, but its not inferred at all (and that’s what I’m curious if it would be possible)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 29, 2017, 1:03pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/4 "2017-12-29T13:03:18Z")

</div>

```julia
julia> foo(::Int) = 3;

julia> foo(::Symbol) = :a;

julia> f() = Base._return_type(foo, Tuple{Int});

julia> @code_warntype f()
Variables:

Body:
  begin
      return Int64
  end::Type{Int64}

```

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [December 29, 2017, 3:11pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/5 "2017-12-29T15:11:38Z")

</div>

Huh, that’s interesting. So its inferred inside another function but somehow not on its own? Is this something special about Base.\_return\_type or is it some other Julia “gotcha” I’m missing?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 29, 2017, 3:22pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/6 "2017-12-29T15:22:32Z")

</div>

I guess the gotcha is to put stuff in functions if you want all optimizations to kick in.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [December 29, 2017, 4:19pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/7 "2017-12-29T16:19:35Z")

</div>

Makes sense, thanks. This is pretty awesome and even somewhat surprising that Julia can actually do this, I gotta say.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [December 29, 2017, 5:42pm UTC](https://discourse.julialang.org/t/could-base-return-type-ever-be-inferable/8057/8 "2017-12-29T17:42:27Z")

</div>

I’m guessing the compiler sees `return_type` as a pure function, and replaces a pure function call with constant arguments by a constant when compiling `f ` ?
