Yes I agree to the heap allocated thing. That is indeed what Java does but I think in C++ you usually wrap it in a struct and pass it by value to function templates, so no real overhead.
What do I have to do in Julia to avoid heap allocation in such a case? Does the "state" value have to be a primitive type, like Int? Is the "start" function supposed to be applied to a container type or to an iterator. In the former case, does that mean container should provide one default iteration way. In the latter case, does returning an iterator uses heap allocation? Thanks, Phil On Thursday, June 12, 2014 1:54:17 PM UTC-4, Stefan Karpinski wrote: > > I'm saying that using a heap-allocated mutable object to store your > iterator state is going to be slow no matter what language you use. Where > "slow" means "not fast enough to be how you count from 1 to n" – which is a > very high performance requirement. In Java, C++, for loops are fast but > require you to explicitly manage state, whereas iterators hide state > management inside a mutable object but are relatively slow. In particular, > they have quite different interfaces and syntax. We wanted a single > protocol that could be fast enough to be how your basic `for k = 1:n` loop > works, but general enough to implement all kinds of iterable things. The > way to do this is to use external state in a functional way, allowing state > to be kept in registers instead of having it live in a mutable, > heap-allocated object like C++ and Java do. The for loop syntax hides this > explicit state, so that you don't actually have to be aware of it, but the > for loop is just sugar for calling start, done and next in the appropriate > ways. > > > On Thu, Jun 12, 2014 at 1:37 PM, Philippe Lavoie <philippe...@gmail.com > <javascript:>> wrote: > >> Hi, >> Thanks for you answer. I am still hung up on a couple of details: >> Are you saying that, in Julia, in order for an iterator to be efficient, >> it has to be an immutable type? >> Would it be possible to just use it like this: >> iter = getacomplicatediter(myCollection) >> (elt, current ) = next(myImmutableIter) >> stopCondition = done(iter) >> >> I guess I don't understand what the additional argument/return value >> "state" is for? >> >> Thanks, >> Phil >> >> >> On Thursday, June 12, 2014 12:09:22 PM UTC-4, Stefan Karpinski wrote: >> >>> Mutable state is lousy for performance. Since the iteration protocol is >>> used for things as basic as a for loop count up from 1 to n, it has to be >>> very fast. If it used a mutable iterator object, getting that to be fast >>> enough would be a nightmare. Using explicit external state makes it easy to >>> translate a for loop into very fast, efficient code, equivalent to what you >>> would write by hand with a while loop. >>> >>> >>> On Thu, Jun 12, 2014 at 11:59 AM, Philippe Lavoie <philippe...@gmail.com >>> > wrote: >>> >>>> Hi, >>>> So I was seduced by a lot of things Julia had to offer and I found the >>>> documentation really fun and helping. >>>> >>>> However, I do have some questions, one of them would be: "why iterator >>>> functions pass state?". >>>> In a more traditional language, you would address an iterator as such: >>>> iter.next(), iter.done(), iter.popFront(), iter.front(), iter.empty(), >>>> etc... >>>> >>>> I am curious to know why, in Julia, iterator functions pass around >>>> state: >>>> init = start(iter) >>>> (i, current) = next(iter, init) >>>> done = (iter, current) >>>> >>>> First of all, I am not sure why a method called "start" would exist, >>>> given the iterator might be provided by another function, like >>>> "ascendingValues(myRedBlackTree)", which would return an iterator for >>>> values in ascending order for example. >>>> Second, given you have an iterator, why pass its state around instead >>>> of just modifying it at every functional call, like traditionally (java, >>>> c++, etc...). IMHO, the iterator interface should/could borrow from other >>>> programming languages and could be something like: >>>> done = isDone(iter) >>>> next = next(iter) >>>> >>>> >>>> >>> >