# Iterable type signature?

**URL:** https://discourse.julialang.org/t/iterable-type-signature/64550
**Category:** General Usage
**Created:** [July 13, 2021, 6:36am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550 "2021-07-13T06:36:08Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [July 13, 2021, 6:36am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/1 "2021-07-13T06:36:08Z")

</div>

Say I have a function that iterates over some values (e.g., vector, range, iterator):

```julia
function f(xs)
  for x in xs
    println(x)
  end
end

```

Can I give it a type signature that indicates the function requires `xs` to be iterable?

It should work for `f(rand(3))` or `f(1:3)` or `f(Iterators.product(1:2, 1:3)`.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [July 13, 2021, 6:43am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/2 "2021-07-13T06:43:14Z")

</div>

What should it do if `xs` is not iterable?

---

<div class="post-metadata">

### Author: ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)
#### Post date: [July 13, 2021, 6:44am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/3 "2021-07-13T06:44:00Z")

</div>

The most idiomatic way is to not annotate and just let it fail when they are not iterable. But if you want the same function to work for scalars, you have two options:

- Annotate the scalar, and use the iterator one as fallback. This works well if you know what type of scalar you expect
- Annotate the iterator, and make a scalar fallback. This is what you’re asking for. You’ll need to constrain the available iterators. `AbstractArray` will catch quite a few of possibilities. Add `Tuple` and you have a lot.

There is no built-in interface system.

---

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [July 13, 2021, 6:50am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/4 "2021-07-13T06:50:59Z")

</div>

> [@tomerarnon](#):
>
> What should it do if `xs` is not iterable?

I’d like the type checker to throw an error. Just like it would if I passed a scalar to a function argument that was annotated `AbstractVector`.

---

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [July 13, 2021, 6:52am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/5 "2021-07-13T06:52:25Z")

</div>

Thanks. I’m not interested in handling scalar types. I just like to document the types of my functions. Perhaps I’ve used Haskell and Rust too much.

---

<div class="post-metadata">

### Author: ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)
#### Post date: [July 13, 2021, 6:59am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/6 "2021-07-13T06:59:30Z")

</div>

There is no type checker. Any errors you get happen at run-ish time. And when you get to the iteration, you will get one.

Consider writing that the input should be iterable in the docstrings.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [July 13, 2021, 7:31am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/7 "2021-07-13T07:31:13Z")

</div>

You will already get an error from iterate:

```julia
julia> for i in :sym
       end
ERROR: MethodError: no method matching iterate(::Symbol)

```

You could use `applicable(iterate, xs)` to check, and then throw your own custom error if you want, but

> The most idiomatic way is to not annotate and just let it fail when they are not iterable.

is the real answer.

---

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [July 13, 2021, 8:04am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/8 "2021-07-13T08:04:31Z")

</div>

It will fail in this case, but it won’t be obvious whether the problem is:

1. I am misusing the function by passing a scalar argument, or
2. The function itself has an implementation error

Even if Julia doesn’t have a formal type checker, it’s still possible and useful to use static analysis on annotated types with something like lsp-julia. I do the same with python.

---

<div class="post-metadata">

### Author: ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)
#### Post date: [July 13, 2021, 9:52am UTC](https://discourse.julialang.org/t/iterable-type-signature/64550/9 "2021-07-13T09:52:18Z")

</div>

```julia
No method `iterate(::MyType)`

```

(or similar) is pretty clear to me. You can of course define your own catch for this, but you’ll never really know whether the error is pebcac or an error in the package. If I get an error as above, and I read the documentation which says “`xs` is an iterable collection of …” then I can assume it’s on my end.
