< Back to IRCAM Forum

Recursion and Accum Object


I am once again faced with using the (dreaded) accum object. I know that I shouldn’t dread using it, but I just cannot come to grips with it.

What I would like to do;
Input a list - rotate the list by one and increase the value of the last element by 12 - perform this process for all rotations (list length - 1)

For example;
(0 2 5)
Rotation 1 - (2 5 12)
Rotation 2 - (5 12 14)
Rotation 3 - (12 14 17) - This is redundant for my purposes as now the entire list is just +12.

I have created a loop with the working function in a sub-patch set to lambda mode. However, when paired with the accum object I just succeed in getting longer and longer error messages. Any suggestions?

Help With Accum.omp (335 Bytes)

This is actually a rather cool problem, and perhaps not too straightforward if you want to solve it using the 'accum object! (you picked a really hairy one to get rid of the ‘dread’…) Would be a bit more clear using straight recursion, but why not, for the fun!?

There are some errors in your loop-setup, the most immediate is the lambda-function should have 2 inputs (check the docs).

Then there’s the massage of the list on each iteration, before attempting to accumulate the result of applying your lambda-function to the previous iteration.

There are perhaps 2 tricks in the attached patch:

  • it uses a ‘dummy’ iterator - the list-loop just controlling when to end the loop, after iterating as many times as there are elements in your input list.
  • related to this: the 2-input lambda-function disregards any ‘next’ input from the iterator (there is none), and just keeps changing the initial list in the way you specified, finally returning the result:

Check also the ‘eval once’ mode on ‘rotate’. Not sure, but perhaps this is what you were looking for using the ‘clone’-object in your patch?

@anders, thank you very much! It is such a joy to receive feedback and help on these projects. This forum is such an awesome place.

  • I’ve seen the two-inlet lambda function before - could you point me to the documentation that goes over its usage? Your remark on the disregarding of any ‘next’ input is most helpful. Does this essentially tell the accum function to draw the ‘new’ input from the just created values in the previous step?

  • The usage of the ‘dummy’ iterator is also something I have seen before, sometimes I forget that it can be used for this purpose. I often think that I have to pass it through to another object when really it can be used to start and terminate a looping function.

  • Is there any reason your provided patch uses last-elem rather than using the last object?

  • Regarding the usage of the clone object, I guess it comes from my time using pd and MAX/MSP. There are times when I create patches and I use a list that will be routed to many areas, I know that eventually I will delete this list and use an inlet instead (as I incorporate the patch into a larger structure). By using the clone object, I can remove the need to reconnect the new inlet to the correct areas in the patch. I hope this makes sense! Is that a bad practice?

Thank you again for your assistance. I want to better understand these concepts and objects as I work to improve my knowledge of OM.


Concerning some resources on accum, here two tutorials (old):



Concerning the dummy iterator you can substitute it with the for iterator using in the second input the length of your list.

The clone object is in principle to clone factories such as voices, bpf, etc prior to their modification, and this without modifiying the original object.


1 Like

Thank you both,

I now have a follow-up question. I had another project to implement accum into and I almost have it working.

Instead of executing a loop for a number of times equal to the list length, I want to iterate through it until certain conditions are met. I gather this is using the while loop. I have experimented with the while loop and I believe that I have it set up correctly, but I do not know which portion of accum / collection / other object to feed into its inlet.

What I would like to accomplish is to perform the recursive process until all intervals given by the x->dx object are equal to 1. I have provided patch notes to try and explain myself and the overall process.

In connecting the (0 1 4 6) list and evaluating the output, the loop should only run once, as all values in x->dx are then equal to 1.

If I remove the list loop, the patch will run forever, when it is added, of course it enumerates through the loop equal to the length of the input list.

I know it has to be something simple - I just don’t know what!

Accum - learning.omp (12.5 KB)

Does this essentially tell the accum function to draw the ‘new’ input from the just created values in the previous step…

You just want to modif what’s in the accumulator already, so the second inlet - ‘new data’ - is not connected to anything.

last-elem rather than using the last object?

Damn, you’re right! Using om+ (instead of just +) you can just grab the last element as a list using #'last, and return it directly to #'append later. :slight_smile:

You can use the #'every function with a suitable predicate to check if all elements pass
Screenshot from 2023-01-23 22-56-55

1 Like

Very useful function, thank you! I knew there had to be something that was like the member function that evaluated if all items were the same.

Just needed to return to a simpler patch and build from there. I found that by sending output 2 from my accum object into my whileloop construct, I was able to correctly terminate the loop. This tool never ceases to amaze me. Very grateful for it and this community.

@haddad, thank you for sharing the tutorial resources. I have seen singular links to those pages, but had never though to edit the url to allow me to see the entire directory. I’ll work through those patches too.

̶T̶h̶i̶s̶ ̶c̶h̶a̶n̶g̶e̶ ̶s̶t̶i̶l̶l̶ ̶d̶o̶e̶s̶n̶’̶t̶ ̶s̶e̶e̶m̶ ̶t̶o̶ ̶s̶o̶l̶v̶e̶ ̶t̶h̶e̶ ̶e̶n̶d̶l̶e̶s̶s̶ ̶l̶o̶o̶p̶ ̶t̶h̶a̶t̶ ̶I̶’̶m̶ ̶e̶n̶c̶o̶u̶n̶t̶e̶r̶i̶n̶g̶ ̶w̶h̶e̶n̶ ̶t̶r̶y̶i̶n̶g̶ ̶t̶o̶ ̶t̶e̶r̶m̶i̶n̶a̶t̶e̶ ̶t̶h̶e̶ ̶l̶o̶o̶p̶i̶n̶g̶ ̶w̶i̶t̶h̶ ̶a̶ ̶̶w̶h̶i̶l̶e̶l̶o̶o̶p̶̶.̶ ̶I̶ ̶n̶o̶w̶ ̶h̶a̶v̶e̶ ̶m̶y̶ ̶̶o̶m̶i̶f̶̶ ̶c̶o̶r̶r̶e̶c̶t̶l̶y̶ ̶s̶e̶n̶d̶i̶n̶g̶ ̶t̶h̶e̶ ̶’̶n̶i̶l̶’̶ ̶m̶e̶s̶s̶a̶g̶e̶ ̶w̶h̶e̶n̶ ̶a̶p̶p̶r̶o̶p̶r̶i̶a̶t̶e̶ ̶w̶h̶i̶c̶h̶ ̶I̶ ̶t̶h̶o̶u̶g̶h̶t̶ ̶s̶h̶o̶u̶l̶d̶ ̶s̶t̶o̶p̶ ̶t̶h̶e̶ ̶̶w̶h̶i̶l̶e̶l̶o̶o̶p̶̶.̶ ̶I̶s̶ ̶t̶h̶e̶r̶e̶ ̶s̶o̶m̶e̶ ̶c̶o̶m̶b̶i̶n̶a̶t̶i̶o̶n̶ ̶o̶f̶ ̶m̶e̶s̶s̶a̶g̶e̶s̶ ̶a̶n̶d̶ ̶o̶u̶t̶l̶e̶t̶s̶ ̶t̶h̶a̶t̶ ̶I̶’̶m̶ ̶m̶i̶s̶s̶i̶n̶g̶?̶