# Difference between Type{T} and T when passing type variable inside generated function?

**URL:** <https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121>\
**Category:** General Usage\
**Created:** [April 24, 2020, 2:11am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121 "2020-04-24T02:11:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [April 24, 2020, 2:11am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/1 "2020-04-24T02:11:35Z")

</div>

Why passing type argument into `@generated` function changes its value from T into Type{T}?

```julia
function type_print(T)
  return :(println($T))
end

macro type_print(T)
  return :(println($T))
end

@generated function type_print_gen(T)
  return :(println($T))
end

type_print(Int8) |> eval # Int8
@type_print(Int8) # Int8
type_print_gen(Int8) # Type{Int8} - why???

```

Because of that, I cannot write generated functions that call another functions that use types as input variables, e.g. `read(io::IO, T)`, `typemax(T)` and so on.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [April 24, 2020, 2:27am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/2 "2020-04-24T02:27:55Z")

</div>

Just wondering, why are you using a generated function? It’s almost never the right choice.

---

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [April 24, 2020, 2:36am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/3 "2020-04-24T02:36:31Z")

</div>

I want to generate the most efficient code to read binary stream into given combination of types. Simply generate repeating reads given a tuple of types. See #2 [here](https://discourse.julialang.org/t/macro-for-binary-data-deserialization-into-tuples-of-variable-types/38088), and further performance comparison.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [April 24, 2020, 2:46am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/4 "2020-04-24T02:46:00Z")

</div>

```julia
julia> @generated function type_print_gen(T)
         return :(println(T))
       end
type_print_gen (generic function with 1 method)

julia> type_print_gen(Int8)
Int8

```

EDIT:  
But this is probably more along the lines of what you want:

```julia
julia> foo(::Type{Type{T}}) where {T} = T
foo (generic function with 1 method)

julia> @generated function type_print_gen(T)
         :(println($(foo(T))))
       end
type_print_gen (generic function with 1 method)

julia> type_print_gen(Int32)
Int32

```

---

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [April 24, 2020, 3:21am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/5 "2020-04-24T03:21:32Z")

</div>

Thank you!  
Is there any reason for such specific behaviour?

So my final code looks like this:

```julia
foo(::Type{Type{T}}) where {T} = T

# from Tuple{T1, T2, ...} - generate (read(io, T1), read(io, T2), ...)
@generated function read_gen(io::IOBuffer, types::Type...)
    Expr(:tuple, [Expr(:call, :read, :io, foo(i)) for i in types]...)
end

io = IOBuffer(UInt8[0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00])
types = (Int8, Int16, Int32)
read_gen(io, types...)

```

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [April 24, 2020, 3:29am UTC](https://discourse.julialang.org/t/difference-between-type-t-and-t-when-passing-type-variable-inside-generated-function/38121/6 "2020-04-24T03:29:25Z")

</div>

> [@sairus7](#):
>
> Is there any reason for such specific behaviour?

You can’t interact with values in generated functions, but you can with the types of arguments.  
So it’s often more convenient to use the arguments directly (as types) than have to type every argument to the function. This is especially true with varargs.

```julia
julia> @generated function foo(a, b...)
           @show a b
       end
foo (generic function with 1 method)

julia> foo((1,0xcf,1f0,1.0), "hi", "world", 3.14, :π, π)
a = Tuple{Int64,UInt8,Float32,Float64}
b = (String, String, Float64, Symbol, Irrational{:π})
(String, String, Float64, Symbol, Irrational{:π})

```
