please, somebody explain me this [zl queue] issue

    Jun 14 2013 | 2:43 pm
    I think there's something wrong with [zl queue]. Please check the example patch below. I feed the queue with numbers 1 2 3 4 5 6 7 8 9. and I have [select 3] after it that can bang back the [zl queue], so that when zl.queue outputs the number 3, the select bangs the queue again and SHOULD output even the next number (four), but it does instead output another number three (which triggers the select to output another bang to queue, etc etc
    so when sending bangs to the queue, instead of this:
    bang -> 1 bang -> 2 bang -> 3, 4 bang -> 5 ... bang -> 9
    i'm getting
    bang -> 1 bang -> 2 bang -> 3, 3, 3, 3, 3, 3, 3
    PLEASE NOTE THAT I'M NOT LOOKING FOR A SOLUTION, BUT AN EXPLANATION. I know this can be solved putting a [defer] between the output of [select 3] and input of [zl queue], but I would like to understand WHY it doesn't work without it. I haven't found any info about this issue in the ZL reference or help page and I have no idea when the [defer] is really needed. (would love to know when to use [defer] during coding, not during troubleshooting)

    • Jun 14 2013 | 3:30 pm
      It's explained somehow in this article, see chapter 'Feedback Loops'.
    • Jun 14 2013 | 5:43 pm
      broc: they write about stack overflow in the "feedback loops" section and i cannot see any stack overflow going on in my example patch.
      BTW I didn't put the [print] on the right side and [select] on the left side. I did that so that the non-feedback part (print) is fed first, and only when all non-feedback stuff is done, then it gets back into another iteration of the loop. I thought it should be safe this way, but it somehow isn't
      To me it seems like the outlets are holding their values until the bang (the one which made them output that value) is completely computed/over. Which would mean that in this case, the zl queue output is holding the "3" value until processing of the third bang isn't completely over.
      Perhaps, it would be better if the outlet would throwaway it's value when sending it to the last wire (which is the one which we could the use for feedbacks without hassle with defers and pipes)
    • Jun 16 2013 | 9:33 am
      Well it can be considered as a bug in the way zl.queue is written. I'll have a look at it.
      In general something to realize with recursion is that you might still be inside the original object. so what is currently happening is that when select 3 is sending bang to zl.queue, the code in zl.queue which is after the outlet call hasn't been executed yet:
      zl.queue code look like this: outlet_int (right outlet) outlet_somevalue (left outlet) increment the index
      the problem is that when the select object finds the value 3, it sends a bang which ask zl.queue to do that again:
      bang->zl zl's outlet_int zl's outlet_somevalue zl->print zl->select (if that failed) zl's increment the index
      if the select succeed:
      bang->zl zl's outlet_int zl's outlet_somevalue zl->print zl->select zl's outlet_int zl's outlet_somevalue zl->print zl->select ... ... when there's no more things to output zl's outlet_int and zl's output_somevalue no longer output anything so it continues with dequeue what's next aka all the zl's increment index that didn't run (but you don't see this in the patcher, you only see that the index hasn't be incremented). zl's increment the index zl's increment the index zl's increment the index
      well not sure if that makes it any clearer though ;-)