# Can \`eltype()\` deduce the element type of a generator?

**URL:** <https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429>\
**Category:** Internals & Design\
**Tags:** data\
**Created:** [October 13, 2017, 8:01pm UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429 "2017-10-13T20:01:52Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![Alexander\_Belopolsky](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_belopolsky/32/4882_2.png) [@Alexander\_Belopolsky](https://discourse.julialang.org/u/Alexander_Belopolsky)\
**Post date:** [October 14, 2017, 2:50am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/21 "2017-10-14T02:50:40Z")

</div>

> [@yuyichao](#):
>
> Adding a ::T in an expression to change the behavior is about as much surprise as you can get.

```julia
julia> π
π = 3.1415926535897...

julia> π::Int
ERROR: TypeError: typeassert: expected Int64, got Irrational{:π}

```

Surprise!

---

<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 14, 2017, 2:57am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/22 "2017-10-14T02:57:20Z")

</div>

That’s not at all what I’m saying! (but yeah, bringing that as an example is quite surprising)

Each expression has it’s semantics and just as you wouldn’t expect `f(a)` for arbitrary `a` to not call `f`, `a::T` will always do type assertion as that’s what its defined meaning is.  
What I **am** saying though, is that there mustn’t be any non-local behavior change to expressions around it or basically anthing that wouldn’t have happened if this is added **anywhere else**. The expression gives you an output (error included) from an input. **NOTHING** more.

---

<div class="post-metadata">

**Author:** ![Alexander\_Belopolsky](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_belopolsky/32/4882_2.png) [@Alexander\_Belopolsky](https://discourse.julialang.org/u/Alexander_Belopolsky)\
**Post date:** [October 14, 2017, 3:09am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/23 "2017-10-14T03:09:26Z")

</div>

> [@yuyichao](#):
>
> (but yeah, bringing that as an example is quite surprising)

OK, what about this:

```julia
julia> using IterableTables

julia> eltype(TableTraits.getiterator(x::Float64 for x in []))
Float64

julia> eltype(TableTraits.getiterator(x::Int for x in []))
Int64

```

Is this another example of people not liking predictable behavior?

---

<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 14, 2017, 3:15am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/24 "2017-10-14T03:15:22Z")

</div>

Yes, because this appearing is arbitrary context will not work. And to repeat what I said, again,

1. `(error()::Int for x in [])`
2. `(x::Integer for x in [1])`
3. `(2.3::Int for x in [])`
4. `T=Int; ((T=Float64; 1.0)::T for x in [1])`

---

<div class="post-metadata">

**Author:** ![Alexander\_Belopolsky](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_belopolsky/32/4882_2.png) [@Alexander\_Belopolsky](https://discourse.julialang.org/u/Alexander_Belopolsky)\
**Post date:** [October 14, 2017, 3:41am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/25 "2017-10-14T03:41:24Z")

</div>

> [@yuyichao](#):
>
> because this appearing is arbitrary context will not work.

Let’s see

```julia
julia> eltype(@typed (error()::Int for x in [])) # 1
Int64

julia> eltype(@typed (x::Integer for x in [1])) # 2
Integer

julia> eltype(@typed (2.3::Int for x in [])) # 3
Int64

julia> T=Int; eltype(@typed ((T=Float64; 1.0)::T for x in [1])) # 4
ERROR: UndefVarError: #4#T not defined

```

I don’t see why having an abstract type as in (2) be a problem given

```julia
julia> collect(Integer, [2.0, 3])
2-element Array{Integer,1}:
 2
 3

```

The error in (4) was not planned for, but does seem like the right thing to do.

---

<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 14, 2017, 3:44am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/26 "2017-10-14T03:44:42Z")

</div>

> [@Alexander\_Belopolsky](#):
>
> julia\> eltype(@typed (error()::Int for x in )) # 1  
> Int64

Wrong, should be `Union{}`

> [@Alexander\_Belopolsky](#):
>
> julia\> eltype(@typed (x::Integer for x in [1])) # 2  
> Integer

Wrong, should be `Int`

> [@Alexander\_Belopolsky](#):
>
> julia\> eltype(@typed (2.3::Int for x in )) # 3  
> Int64

Wrong, should be `Union{}`

> [@Alexander\_Belopolsky](#):
>
> julia\> T=Int; eltype(@typed ((T=Float64; 1.0)::T for x in [1])) # 4  
> ERROR: UndefVarError: #4#T not defined

Scoping issue, put all in a function.

---

<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 14, 2017, 3:46am UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/27 "2017-10-14T03:46:56Z")

</div>

> [@Alexander\_Belopolsky](#):
>
> I don’t see why having an abstract type as in (2) be a problem given
> 
> julia\> collect(Integer, [2.0, 3])  
> 2-element Array{Integer,1}:  
> 2  
> 3

And this is exactly what I said you should do instead of what your want your macro to guess, i.e.

> [@yuyichao](#):
>
> For example, just give the type to your TableTraits.getiterator function.

---

<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 14, 2017, 1:01pm UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/28 "2017-10-14T13:01:36Z")

</div>

> [@yuyichao](#):
>
> instead of what your want your macro to guess

Actually I should say more precisely that having your macro to guess is fine, having Base to guess is not. (other than some hygene issue in your macro).  
Both because what you have here is **NOT** a correct answer to the real eltype of the generator by any mean (correct answer given above, which is generally uncomputable without running the generator) and because the syntax is very surprising (explained above). However, as I said above, having a generator wrapper type that carries an eltype is perfectly fine (just don’t make it the default generator). Having a macro to provide some syntax sugar for creating that type is also fine since macros are understood to do transformations that otherwise make no sense (i.e. having a macro breaking down expression and give significance to the structure of an expression is OK).

---

<div class="post-metadata">

**Author:** ![Alexander\_Belopolsky](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander_belopolsky/32/4882_2.png) [@Alexander\_Belopolsky](https://discourse.julialang.org/u/Alexander_Belopolsky)\
**Post date:** [October 17, 2017, 9:16pm UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/29 "2017-10-17T21:16:09Z")

</div>

> [@yuyichao](#):
>
> just give the type to your TableTraits.getiterator function.

`TableTraits.getiterator ` is not my function. It comes from a package by @davidanthoff. My package has to specialize it to be able to provide a “source” for the [Query.jl](https://github.com/davidanthoff/Query.jl) queries. I cannot change the signature. Moreover, the return type of a query is rarely known in advance, it has to be inferred from the input.

BTW, I’ve noticed that `BaseGenerator` has a [constructor](https://github.com/JuliaLang/julia/blob/8153470976b056c71b325f3fa1c1e9fe10aa27df/base/generator.jl#L38) that takes a type instead of a function, but it still returns a “typeless” iterator:

```julia
julia> eltype(Base.Generator(Int, 1:5))
Any

```

What is the intended use of `Generator(T, iter)`?

---

<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 17, 2017, 9:25pm UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/30 "2017-10-17T21:25:29Z")

</div>

> [@Alexander\_Belopolsky](#):
>
> Moreover, the return type of a query is rarely known in advance, it has to be inferred from the input.

In this case the caller should be change to be able to not rely on that.

> [@Alexander\_Belopolsky](#):
>
> What is the intended use of Generator(T, iter)?

It’s just a implementation detail due to how types are dispatched. There’s no significant when the callee is a type.

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [December 11, 2019, 8:40pm UTC](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429/31 "2019-12-11T20:40:22Z")

</div>

Sorry for kick-up this thread, but asserting the [concrete] eltype of a generator seems like a great feature, which could be implemented in a package. I realize the iteration protocol has changed, likely since this thread was active. Is there still any need to treat the first call of `iterate` specially?

[Previous page](https://discourse.julialang.org/t/can-eltype-deduce-the-element-type-of-a-generator/6429.md?page=1)
