# Getting the type of \`f(x)\` at compile time (without evaluating \`f(x)\`), for type-stable functions

**URL:** <https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 9, 2018, 12:45pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069 "2018-10-09T12:45:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 12:45pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/1 "2018-10-09T12:45:54Z")

</div>

I have a type-stable function `f(x)` that is expensive to evaluate. Given an argument `x`, how do I obtain the _type_ of the result `f(x)`, but without actually evaluating `f(x)`?

Ideally this should be elided during compilation and there should be no computation at all, because the type of `f(x)` is known at compile time.

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [October 9, 2018, 1:07pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/2 "2018-10-09T13:07:53Z")

</div>

```julia
julia> Core.Compiler.return_type(gcd, Tuple{Int,Int})
Int64

```

This should generally behave the way that you want, but be aware that it generally has the liberty to return `Any`, return different results, etc. If there’s _any_ other way to do what you want it’s probably a good idea.

---

<div class="post-metadata">

**Author:** ![kdyrhage](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kdyrhage/32/2326_2.png) [@kdyrhage](https://discourse.julialang.org/u/kdyrhage)\
**Post date:** [October 9, 2018, 1:11pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/3 "2018-10-09T13:11:45Z")

</div>

```julia
julia> f(x) = x
f (generic function with 1 method)

julia> @code_typed(f(1)).second
Int64

julia> @code_typed(f(1.)).second
Float64

```

Perhaps?

---

<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:** [October 9, 2018, 1:14pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/4 "2018-10-09T13:14:59Z")

</div>

> [@MikeInnes](#):
>
> If there’s _any_ other way to do what you want it’s probably a good idea.

I second this. These “other ways” are documented mostly in the source of Julia and the standard libraries though. A more specific question would allow suggesting the right one.

Eg if you are collecting things, I would recommend you look at the functions `collect` calls, or [a functional approach](https://discourse.julialang.org/t/functional-implementation-of-collect/15177) I experimented with.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:17pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/5 "2018-10-09T13:17:55Z")

</div>

@Tamas_Papp Specifically I am looking at this line of code:

[https://github.com/JuliaStats/StatsFuns.jl/blob/ae40bc1c6ee63a5624ba6cd168da5bf43f473e59/src/basicfuns.jl#L66](https://github.com/JuliaStats/StatsFuns.jl/blob/ae40bc1c6ee63a5624ba6cd168da5bf43f473e59/src/basicfuns.jl#L66)

In the last branch, `oftype(exp(-x), x)`, I would like to avoid calling `exp`, but still get the correct return type.

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [October 9, 2018, 1:20pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/6 "2018-10-09T13:20:03Z")

</div>

Generally in a case like this I would just write `x/1`.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:23pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/7 "2018-10-09T13:23:24Z")

</div>

> [@MikeInnes](#):
>
> Generally in a case like this I would just write `x/1` .

How can you be sure this always has the same type as `exp(x)`? Consider that someone can write new methods for `exp` for arbitrary types `<: Real`.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 9, 2018, 1:58pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/8 "2018-10-09T13:58:34Z")

</div>

> [@e3c6](#):
>
> Ideally this should be elided during compilation and there should be no computation at all, because the type of `f(x)` is known at compile time.

This concept does not exist in julia.

`Core.Compiler.return_type(gcd, Tuple{Int,Int})` is the only function that is useful for this in the very few case you are allowed to use it. Don’t use `code_typed`.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 2:05pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/9 "2018-10-09T14:05:58Z")

</div>

An alternative solution to the original problem ([https://github.com/JuliaStats/StatsFuns.jl/blob/ae40bc1c6ee63a5624ba6cd168da5bf43f473e59/src/basicfuns.jl#L66](https://github.com/JuliaStats/StatsFuns.jl/blob/ae40bc1c6ee63a5624ba6cd168da5bf43f473e59/src/basicfuns.jl#L66)) is to define:

```julia
log1pexp(x::AbstractFloat) = x < 18.0 ? log1p(exp(x)) : x < 33.3 ? x + exp(-x) : x
log1pexp(x::Real) = log1pexp(float(x))

```

But this stackoverflows when passed dual numbers:

```julia
julia> ForwardDiff.derivative(log1pexp, 1.)
ERROR: StackOverflowError:
Stacktrace:
 [1] log1pexp(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(log1pexp),Float64},Float64,1}) at ./REPL[1]:1 (repeats 80000 times)

```

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [October 9, 2018, 2:45pm UTC](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069/10 "2018-10-09T14:45:51Z")

</div>

In general, you don’t. But it’s reasonable to expect that `exp(x)`, `x/1` and `float(x)` will have the same type, and if someone defines `exp` to return a string or something then I say that’s on them.

(In any case, the worst that happens here is that you get a union, which is no longer that big of a deal for performance anyway.)
