# Wrapper{Type{Int}} really needed?

**URL:** <https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877>\
**Category:** Performance\
**Tags:** question\
**Created:** [August 5, 2021, 12:18pm UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877 "2021-08-05T12:18:32Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [August 5, 2021, 12:18pm UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/1 "2021-08-05T12:18:32Z")

</div>

[Julia’s documentation](https://docs.julialang.org/en/v1/manual/types/#man-typet-type) recommends to wrap types into `Type{...}` for performance considerations

The concrete example in the documentation is

```julia
julia> struct WrapType{T}
       value::T
       end

julia> WrapType(Float64) # default constructor, note DataType
WrapType{DataType}(Float64)

julia> WrapType(::Type{T}) where T = WrapType{Type{T}}(T)
WrapType

julia> WrapType(Float64) # sharpened constructor, note more precise Type{Float64}
WrapType{Type{Float64}}(Float64)

```

However, trying everything with a plain Wrapper which does not do this `Type{...}` support, inference seems to work fully.

```julia
julia> struct Wrapper{T}
           value::T
       end

julia> function f()
           a = Wrapper(Int)
           a.value
       end
f (generic function with 1 method)

julia> Wrapper(Int)
Wrapper{DataType}(Int64)

julia> Base.promote_op(f)
Type{Int64}

```

Is the example in the documentation outdated? Do all Types have by now extra support for type-inference such that they do not need to be marked with `Type{...}` any longer?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 5, 2021, 9:39pm UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/2 "2021-08-05T21:39:41Z")

</div>

That’s likely just constant folding in the specific case. If you add a `Wrapper` argument to `f`, the inference fails as expected:

```julia
julia> function f(b::Wrapper)
           a = Wrapper(Int)
           promote_type(a.value, b.value)
       end
f (generic function with 2 methods)

julia> Base.promote_op(f, typeof(Wrapper(Float64)))
Type{S} where S

```

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [August 6, 2021, 8:25am UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/3 "2021-08-06T08:25:32Z")

</div>

Thank you very much for the concise failing example.

Can you even construct an example where it does not depend on passing in `typeof(Wrapper(Float64))` to promote\_op?  
I mean when does Julia’s constant-folding mechanism stop working and falls back to type-level inference only?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 6, 2021, 6:12pm UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/4 "2021-08-06T18:12:16Z")

</div>

Somewhat contrived

```julia
function foo()
    if rand(Bool)
        a = Wrapper(Int)
    else
        a = Wrapper(Vector{Int})
    end
    a.value
end

```

Now `Base.promote_op(foo)` returns `DataType` and not `Union{Type{Int}, Type{Vector{Int}}}`. If `a` does not have multiple bind sites, I’m unsure how complex the remaining function must be for constant folding not working. However, constant folding and type inference in general is a compiler optimization not affecting the semantics, so it may change from version to version.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 7, 2021, 5:18pm UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/5 "2021-08-07T17:18:26Z")

</div>

A much more concise (and deterministic!) example:

```julia
function foo()
    a = Ref(Wrapper(Int))
    a[].value
end

julia> Base.promote_op(foo)
DataType

```

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [August 10, 2021, 8:35am UTC](https://discourse.julialang.org/t/wrapper-type-int-really-needed/65877/6 "2021-08-10T08:35:09Z")

</div>

thank you both very much for these additional examples.  
It helps a lot to see the inference failing in real simple examples
