# Implementation of itertools.count

**URL:** <https://discourse.julialang.org/t/implementation-of-itertools-count/3785>\
**Category:** New to Julia\
**Created:** [May 18, 2017, 11:08am UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785 "2017-05-18T11:08:38Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [May 18, 2017, 11:08am UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/1 "2017-05-18T11:08:39Z")

</div>

I’m trying to emulate python’s itertools.count. Seems like it should be simple, but I’m having trouble with it:

```julia
struct count
    n:: Int64
end

import Base: start, next, done
function start(c::count)
    return c.n
end

function next(c::count, i)
    return i+1, i+1
end

done(c::count, i) = false

```

```julia
julia> [i for i in take(count(1), 10)]
WARNING: Base.take is deprecated.
  likely near no file:0
ERROR: MethodError: no method matching length(::count)
Closest candidates are:
  length(!Matched::SimpleVector) at essentials.jl:257
  length(!Matched::Base.MethodList) at reflection.jl:558
  length(!Matched::MethodTable) at reflection.jl:634
  ...
Stacktrace:
 [1] _min_length(::count, ::UnitRange{Int64}, ::Base.HasLength, ::Base.HasLength) at ./iterators.jl:14
 [2] _array_for at ./array.jl:416 [inlined]
 [3] collect(::Base.Generator{Base.Iterators.Take{count},##3#4}) at ./array.jl:430
 [4] macro expansion at ./REPL.jl:97 [inlined]
 [5] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 18, 2017, 1:19pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/2 "2017-05-18T13:19:30Z")

</div>

`Base.iteratorsize(::Type{count}) = Base.SizeUnknown()`

[https://docs.julialang.org/en/stable/manual/interfaces/](https://docs.julialang.org/en/stable/manual/interfaces/)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 18, 2017, 1:19pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/3 "2017-05-18T13:19:59Z")

</div>

Note [Base.Iterators.countfrom](https://docs.julialang.org/en/latest/stdlib/iterators.html#Base.Iterators.countfrom). If you want to reimplement it (for learning), look at its source, and [the iteration interface](https://docs.julialang.org/en/latest/manual/interfaces.html), particularly `iteratorsize`.

---

<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:** [May 18, 2017, 1:26pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/4 "2017-05-18T13:26:54Z")

</div>

Is there any case in which you couldn’t use a `UnitRange` object for this? These can be constructed with `start:interval:stop` or simply `start:stop` (yes, the fact that a colon serves as a constructor for these as well as everything else it does in Julia is confusing).

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 18, 2017, 1:59pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/5 "2017-05-18T13:59:39Z")

</div>

What else does a colon do?

---

<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:** [May 18, 2017, 2:11pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/6 "2017-05-18T14:11:11Z")

</div>

Colons have the following uses in Julia:

- To declare a `Symbol` like `:symbol`. (A `Symbol` is an interned string, or rather a string that gets tokenized by the compiler.)
- As a constructor for ranges like `1:10` or `1.0:0.5:5.0`. These are most commonly used for slicing arrays, but are general iterators.
- In implication constructs `rand(Bool) ? :win : :lose`.
- Double colons are used in type assertions `:x::Symbol`.
- A colon is also its own object: a singleton instance of the `Colon` type. This is often used as an argument for slicing arrays, or, for example, a dataframe `df[:, (rand(Bool) ? :c1 : :c2)::Symbol]`

(These examples were deliberately silly.)

Yeah… honestly this is the one major thing that bugs me about the Julia syntax. It certainly makes sense to use it for slicing and conditional constructs and the double colons aren’t so bad because those are all things that are fairly common in other languages. I really wish they had used something else for the symbols though, like maybe `%`. Too late now. Obviously it’s all logically consistent, or it wouldn’t be possible to compile, it’s just a bit ugly to look at in some cases

---

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [May 18, 2017, 2:12pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/7 "2017-05-18T14:12:53Z")

</div>

Oh, thanks! I missed Base.Iterators.countfrom

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 18, 2017, 6:57pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/8 "2017-05-18T18:57:03Z")

</div>

Great list, thanks! Is there somewhere in the Julia docs, or maybe the StackOverflow Julia docs, that this could be added?

---

<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:** [May 18, 2017, 7:05pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/9 "2017-05-18T19:05:48Z")

</div>

Well, all of those things are certainly extensively documented. I don’t believe there’s a place that compiles all the uses of `:` specifically. In a way that makes sense: `:symbol`, `:`, `1:3` and `x::Int` all have completely different, even unrelated semantics, so they don’t really bear any relation to each other other than that they all happen to have the character `:`. I’d think the proper thing to do would be to simply search for `:`, although I don’t think the documentation search is quite that good.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 18, 2017, 10:09pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/10 "2017-05-18T22:09:59Z")

</div>

Agreed. But maybe it would be useful to have a summary page somewhere on “use of punctuation symbols in Julia”, where each use of each symbol is succintly listed in one place, as you exemplified.

---

<div class="post-metadata">

**Author:** ![swt30](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swt30/32/4667_2.png) [@swt30](https://discourse.julialang.org/u/swt30)\
**Post date:** [May 19, 2017, 8:12am UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/11 "2017-05-19T08:12:22Z")

</div>

You mean the (rather under-advertised) [punctuation page](https://docs.julialang.org/en/release-0.5/stdlib/punctuation/)?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 19, 2017, 9:20am UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/12 "2017-05-19T09:20:05Z")

</div>

Ah yes, thanks!

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 19, 2017, 2:12pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/13 "2017-05-19T14:12:37Z")

</div>

Shouldn’t this be a fallback (i.e. default) for any type that hasn’t told us that it has known size?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 19, 2017, 2:13pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/14 "2017-05-19T14:13:45Z")

</div>

I was thinking the same thing but perhaps it is a performance trap?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 19, 2017, 2:16pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/15 "2017-05-19T14:16:17Z")

</div>

Two options then:

1. Make `SizeUnknown` the fallback so it works by default but may be slower than optimal.
2. Improve the error when `length` fails and iteratorsize is `SizeUnknown` indicating that the user needs to either change `iteratorsize` or define `length`.

This is why we need interfaces/protocols.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 19, 2017, 2:17pm UTC](https://discourse.julialang.org/t/implementation-of-itertools-count/3785/16 "2017-05-19T14:17:57Z")

</div>

1 is what I meant with a performance trap. I would say most iterators have known length. 2 seems like a good idea.
