zero-functional / zero-functional

A library providing zero-cost chaining for functional abstractions in Nim.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"'yield' only allowed in an iterator" is a feature-blocker

ZoomRmc opened this issue · comments

commented

I vaguely understand the reasons we can only yield inside the loop. This, however, leads to some adapters to being seemingly impossible to implement.

For example, here's a chunks adapter, which captures iteration values and yields sparingly. The limitation, in conjunction with the fact we can't reliably get the number of total iterations to add a condition inside a loop, leads to the "tail" of the iterations being dropped.

zfInline chunks(size):
  init:
    var s = newSeqOfCap[typeof(it)](size)
    var cntIdent = 0
  loop:
    inc(cntIdent)
    s.add(`prevIdent`)
    if cntIdent < size:
      continue
    else:
      let it = s
      cntIdent = 0
      s = newSeqOfCap[typeof(`prevIdent`)](size)
      yield it
  final:
    echo s

static:
  zfCreateExtension()

for s in countUp(0, 10) --> map(it).chunks(3):
  echo s

# Output:
# @[9, 10]
# @[0, 1, 2]
# @[3, 4, 5]
# @[6, 7, 8]

@[9, 10] is what needs to be yielded last.

Interestingly 1. final statement is executed ahead of the loop; 2. map(it) can't be omitted. Is any of these worthy of separate issues?

Would love to hear any ideas. Hope I'm just being stupid and am looking at it from the wrong angle.

Hi @ZoomRmc

Thanks for your input!
What is currently preventing from simply doing yield s inside the final section is that the final section is not part of the for loop and yield is only allowed in an iterator (I do not think that this error messages is from zero_functional, but really from Nim compiler).

Hm - yes - so my idea would be to internally allow yield statement in final section by actually replacing it with a fake call to a function. Later replacing again that fake call by the actual operation (zfAddItemCheck) - which is already done for the usual yield statements inside the loop.
I am not sure what will happen when an actual iterator is generated...

So - that would be the idea.
I have just fixed stuff that I stumbled on, will do this next. Give a me few days to check if that is really possible.

cheers, Michael