This simple iterator example I expect to return '99 99 99', but it returns '99 99 0' no matter I do. I am using dev version of nim.
proc filter[T](it: (iterator : T), f: proc(x: T): bool): (iterator : T) =
iterator filtered: T {.closure.} =
for x in it():
if f(x): # commenting out this line has no effect on the output
yield x
result = filtered
proc len[T](it : iterator : T) : Natural =
for i in it():
result += 1
proc simpleSeqIterator(s :seq[int]) : iterator : int =
iterator it: int {.closure.} =
for x in s:
yield x
result = it
let a = newSeq[int](99)
let iter = simpleSeqIterator(a)
echo len(a)
echo len(iter)
echo len(filter(iter, proc(x : int) : bool = true))
Am I doing something wrong? or is it a nim bug? Feels like capturing issues in the filter proc.Ok, I got it working with low level iterator code:
proc len[T](it : (iterator : T)) : Natural =
for i in it():
result += 1
proc filter[T](it: (iterator : T), f: proc(x: T): bool): (iterator: T) =
return iterator(): T =
while (let x = it(); not finished(it)):
if f(x):
yield x
proc simpleSeqIterator[T](s :seq[T]) : (iterator : T) =
iterator it: T {.closure.} =
for x in s:
yield x
return it
let a = toSeq(1 .. 99)
echo len(a)
echo len(simpleSeqIterator(a))
echo len(filter(simpleSeqIterator(a), proc(x : int) : bool = true))
I also once tried to do functional programming in Nim, but there is a lot of friction to do so at the moment. One thing I did that could also be useful for you was a lifting template that allowed me to transform an inline iterator into a closure iterator, so that I could use all those iterators that were only defined as inline iterators in the standard library more useful.
Many thanks Krux02,
With while loop it works somehow.
Silly mistake with double usage of iterator was introduced as I was preparing a reduced code snippet to post on the forum. Should I file a bug report on github for the for loop case?