# Feature request: type assertion for compiler-known type

**URL:** <https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305>\
**Category:** General Usage\
**Created:** [April 12, 2018, 3:29pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305 "2018-04-12T15:29:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 3:29pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/1 "2018-04-12T15:29:15Z")

</div>

Suppose I have an assignment statement like this:

```julia
    a = Complex{typeof(b)}(b+1.)

```

Suppose furthermore that I think that the compiler ought to be able to deduce the exact type of `a` (for type stability). But how can I confirm this? A type-assertion doesn’t really help:

```julia
  a = Complex{typeof(b)}(b + 1.)::Complex{typeof(b)}

```

since the type-assertion type is also not necessarily known to the compiler.

One way is to pore over the output of `code_warntype`. But instead, I would like to ask for a new language feature:

```julia
  a = Complex{typeof(b)}(b+1.)::CompilerKnowsType

```

that will yield an error at compilation time if the compiler does not know the type.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 12, 2018, 3:35pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/2 "2018-04-12T15:35:10Z")

</div>

[`@inferred`](https://docs.julialang.org/en/stable/stdlib/test/#Base.Test.@inferred)?

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 3:43pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/3 "2018-04-12T15:43:20Z")

</div>

EDIT: Regarding my previous response below: I pushed the `@inferred` to the right of the assignment statement in the code below like this:

```julia
    b = @inferred Complex{typeof(a)}(a + 1.0)

```

and then it seemed to work. So apparently this solves my problem except for one question: is there a run-time performance hit for using `@inferred`, or does the compiler turn it into a no-op in the compiled code?

* * *

I was not previously familiar with `@inferred`. I just looked at the doc, and I’m not quite sure how it solves the problem . Do I precede the assignment statement with `@inferred`? That didn’t work:

```julia
module test_inferred
import Base.Test.@inferred
function t(a)
    @inferred b = Complex{typeof(a)}(a + 1.0)
    println("b = ", b)
    b
end
t(2.2)
end

```

yields (0.6.2):

```julia
julia> include("test_inferred.jl")
ERROR: LoadError: @inferred requires a call expression
Stacktrace:
 [1] include_from_node1(::String) at .\loading.jl:576
 [2] include(::String) at .\sysimg.jl:14
while loading C:\Users\vavasis\ownCloud\Documents\Katerina\cohesive\conic_jl\test_inferred.jl, in expression starting on line 4

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 12, 2018, 4:05pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/4 "2018-04-12T16:05:11Z")

</div>

You want `b = @inferred Complex{typeof(a)}(a + 1.0)`. Note that `@inferred` is typically used in tests, not in production code; I’m not sure if it has any overhead; I would suggest benchmarking.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 4:27pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/5 "2018-04-12T16:27:56Z")

</div>

There is a big performance hit in 0.6.2 with using `@inferred` in this manner. The running time of invoking `t` repeatedly jumped from .000125 sec to 0.913 sec according to the benchmark I just ran.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [April 12, 2018, 6:19pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/6 "2018-04-12T18:19:35Z")

</div>

I’m actually rather hazy on this but I think that in some cases in 0.7 constant propagation _might_ help with this sort of thing. For example, I _think_

```julia
f(a::Bool) = a ? 1 : 1.0

```

while not formally “type stable” would behave as such in 0.7, i.e. be equivalent to

```julia
f(::Type{Val{true}}) = 1
f(::Type{Val{false}}) = 1.0

```

though I haven’t rigorously checked this. It might be even more complicated than that and depend on how the input `a` is generated in the containing code.

I’d actually be very interested to know if someone can come along and tell me whether that is indeed the case, because I really don’t know what I’m talking about.

By the way, one (perhaps obvious) piece of advice regarding your original question is that you should avoid using `typeof` in favor of using parametric inputs wherever possible. The only cases I commonly run into where this routinely back-fires all have to do with IO and “generic” containers such as DataFrames.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 12, 2018, 6:37pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/7 "2018-04-12T18:37:46Z")

</div>

```julia
const DEBUG = false

@static if DEBUG
    @eval begin
        macro debug_inferred(ex)
            return :(Base.Test.@inferred $(esc(ex)))
        end
    end
else
     @eval begin
        macro debug_inferred(ex)
            return esc(ex)
        end
    end
end

```

When `DEBUG` is `false`:

```julia
julia> f(x) = x > 1 ? x : [x]
f (generic function with 1 method)

julia> x = @debug_inferred f(3.)
3.0

julia> @macroexpand @debug_inferred f(3.)
:(f(3.0))

```

When `true`:

```julia
julia> x = @debug_inferred f(3.)
ERROR: return type Float64 does not match inferred return type Union{Array{Float64,1}, Float64}
Stacktrace:
 [1] error(::String) at .\error.jl:21

```

Note: modified from a similar construct in JuAFEM.jl

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 6:58pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/8 "2018-04-12T18:58:58Z")

</div>

Could somebody expand on the following piece of advice? In my sample code in the original post, the use of `typeof` did indeed lead the compiler to correct inference (at least according to the result of `@inferred`), so what is the danger/disadvantage of using `typeof` in this manner?

> [@ExpandingMan](#):
>
> By the way, one (perhaps obvious) piece of advice regarding your original question is that you should avoid using `typeof` in favor of using parametric inputs wherever possible. The only cases I commonly run into where this routinely back-fires all have to do with IO and “generic” containers such as DataFrames.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 7:31pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/10 "2018-04-12T19:31:55Z")

</div>

Thanks for posting the macro `@debug_inferred`. This does not completely solve my problem for the following reasons.

1. I have to remember to turn DEBUG on and off.
2. My code can run for hours, and some of the `@inferred` declarations might not be encountered during the first few minutes of the run. (So in other words, I have to turn `@inferred` on and off at a fine-grained level.)

I don’t know how `@inferred` works, but there is no obvious reason why it should have ANY run-time overhead. In principle, the compiler can check it and then discard it.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 7:35pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/11 "2018-04-12T19:35:30Z")

</div>

Regarding the two functions `modulus1` and `modulus2`, I’m still not getting the point. Is there any difference between their functionality/performance? Or are you preferring `modulus2` because it is more readable?

In my case, my code already has a plethora of `where` declarations, and only a few of these `typeof` invocations, so the readability tradeoff is not clear-cut.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [April 12, 2018, 7:43pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/12 "2018-04-12T19:43:14Z")

</div>

Sorry, my example was too silly so any inefficiency there gets elided by the compiler.

In general though, there may be a difference between `typeof` and using parameters. For example, using a `Vector{Any}` and taking `typeof` its elements is typically much less efficient than having a `Vector{T}` and using `T`. Again, I don’t know the context your code is appearing in, but I usually find that you don’t need to resort to the type of thing you’re talking about.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [April 12, 2018, 7:58pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/13 "2018-04-12T19:58:10Z")

</div>

IIUC, it is checking the actual (run-time) type of the expression, against what was inferred. If what was inferred is a concrete type, it probably has very little overhead, a single comparison of the two types, and a branch generally not taken.  
However, if the inferred type is not concrete, then I imagine it can make things a lot slower, because it would have to check if the type of the expression is any of the possible types that are \<: the inferred type.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [April 12, 2018, 8:05pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/14 "2018-04-12T20:05:47Z")

</div>

> [@ExpandingMan](#):
>
> For example, using a Vector{Any} and taking typeof its elements is typically much less efficient than having a Vector{T} and using T.

Taking the type of the elements is quite different from taking the type of the elements of the collection.  
`eltype(vec)` will give you the same as `foo(::Vector{T}) where {T} = T`, and seems to generate exactly the same code.  
If you have a `Vector{Any}` or a vector with some other non-concrete type (excepting the small unions which are now optimized on master), every element will be a pointer to a boxed object with the type, so getting the type of each element means following that pointer on each element.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [April 12, 2018, 8:12pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/15 "2018-04-12T20:12:04Z")

</div>

I’m aware, I was just having a really hard time coming up with an example that gets at the gist of what I was saying. Was watching this while doing something else, I really shouldn’t have jumped in today, sorry.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [April 12, 2018, 9:14pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/16 "2018-04-12T21:14:22Z")

</div>

> [@ExpandingMan](#):
>
> By the way, one (perhaps obvious) piece of advice regarding your original question is that you should avoid using typeof in favor of using parametric inputs wherever possible.

The Style Guide suggests the opposite. From the section [Don’t use unnecessary static parameters](https://docs.julialang.org/en/stable/manual/style-guide/#Don't-use-unnecessary-static-parameters-1) :

> Even if T is used, it can be replaced with typeof(x) if convenient. There is no performance difference.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 12, 2018, 11:13pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/17 "2018-04-12T23:13:40Z")

</div>

In my experience, with 0.6.2 there have been cases where replacing `typeof(x)` with a function type parameter resulted in better inference results. I don’t have an example ready though.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [April 12, 2018, 11:32pm UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/18 "2018-04-12T23:32:35Z")

</div>

Is this posting referring to the use of the `@inferred` macro? My benchmark indicates that even if the inferred type is concrete, the overhead for using the `@inferred` macro is huge, which I don’t quite understand.

> [@ScottPJones](#):
>
> IIUC, it is checking the actual (run-time) type of the expression, against what was inferred. If what was inferred is a concrete type, it probably has very little overhead, a single comparison of the two types, and a branch generally not taken.  
> However, if the inferred type is not concrete, then I imagine it can make things a lot slower, because it would have to check if the type of the expression is any of the possible types that are \<: the inferred type.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [April 13, 2018, 12:40am UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/19 "2018-04-13T00:40:23Z")

</div>

> [@greg\_plowman](#):
>
> The Style Guide suggests the opposite

That’s not what they are talking about. What they are saying is that you should not do e.g.

```julia
f(x::T) where {T<:Real} = x + 1

```

but that’s a different use case from those in which you actually want to be able to _utilize_ the type parameter e.g.

```julia
f(x::T) where {T<:Real} = x + one(T)

```

In that case you need to have access to the type `T`, so it makes sense to include it in the function signature. As @tkoolen indicated, it’s usually safer to use type parameters rather than `typeof`. Granted, as the compiler gets better, there will be more and more cases in which there won’t actually be a difference in the compiled machine code (again, constant propagation in 0.7 potentially makes it much more difficult to know what exactly will happen). Still, I suspect using type parameters in cases where types need to be provided as arguments will always be the recommended approach.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [April 13, 2018, 12:58am UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/20 "2018-04-13T00:58:17Z")

</div>

> <https://github.com/JuliaLang/julia/issues/10980>
>
> Given the importance of type stability, I would like to propose a new language c…onstruct that would allow semi-static checking of type stable blocks. In the module I am developing, I am frequently using this type of construct
> 
> \`\`\` julia
> function f(a)
> # Type stability
> @stabilize m::Matrix{Float64} = a.m
> 
> # Compute things with m
> 
> end
> ...
> \`\`\`
> 
> I know there are:
> 1. The possibility to use a function - but this can be cumbersome when there are many types, and in makes the code harder to read (at least for me)
> 2. Tools like Lint or TypeCheck, and the macro \`@code\_warntype\` that are useful to see/check whether the written code is type stable
> 
> but I would really like to have something that prevents code from being instable, e.g. using a "stable block" (I check and this gives a syntax error with julia 0.\[34\]):
> 
> \`\`\` julia
> function f(a)
> # Type stability
> @stabilize m::Matrix{Float64} = a.m
> 
> stable begin
> # Compute things - compilation error (or warning) if there is some type instability within the code
> end
> 
> end
> ...
> \`\`\`
> 
> Another syntactic possibility would be to use pragmas #7449 (if they make it in the language).

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [April 13, 2018, 2:07am UTC](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305/21 "2018-04-13T02:07:37Z")

</div>

> [@ExpandingMan](#):
>
> but that’s a different use case from those in which you actually want to be able to utilize the type parameter e.g.
> 
> f(x::T) where {T\<:Real} = x + one(T)

Maybe there are cases where it makes a difference (in terms of speed, or simplicity of code).

I’m just pointing out what the style guide suggests, and that for _simple_ cases, the function can be re-written without static type parameters and there is no performance difference. I personally do not have a preference.

Your example can be re-written, without loss of performance or generality:

```julia
f(x::T) where {T<:Real} = x + one(T)
g(x::Real) = x + one(typeof(x))

```

`@benchmark` confirms the functions have similar performance.  
`@code_warntype` shows the functions are equivalent.

[Next page](https://discourse.julialang.org/t/feature-request-type-assertion-for-compiler-known-type/10305.md?page=2)
