< Back to IRCAM Forum

Simple recursion

(Sorry for being clueless about this but I have tried ((for days) LOL)

The attached patch simply transposes a MIDI cents list by a specified number of semitones; so (6000 6200 6300) up 2 semitones becomes (6200 6400 6500).

I’d like to do do this n number of times and append the results, let’s say twice, so that (6000 6200 6300) becomes ((6000 6200 6300) (6200 6400 6500) (6400 6600 6700)). I can’t figure out to do it (recursively, I’d imagine) and have been getting [!!] :: cycles not permitted! messages.

I’d be very grateful for help. Thanks.

Don
mc2mct.opat (4.1 KB)

PS: the attached works perfectly but I’d like a version that will repeat n times and doesn’t have all this repetition; i.e., that uses recursion or a loop.
temp-working.opat (7.5 KB)

Here is a modified version of your patch implementing a loop:

Note that you can also use accum instead of collect, if you want to control exactly how your results are accumulated (not just collected in a list). Since in your working example, the results are appended, you would use append as accumulation function.

Screenshot 2021-05-24 at 17.01.16

Then you don’t need to use flat before the output.

Sorry now re-reading your initial message, if you need a list of the form ((6000 6200 6300) (6200 6400 6500) (6400 6600 6700)) then you shoudl just use collect (with no flat).

I cheated a little bit by avoiding your original problem, which was (I guess) to reuse the last result of an iteration to compute the next one. In a loop, you can work this around, for instance using global variables (GLOBAL)

https://cac-t-u-s.github.io/om-sharp/pages/global-variable

( and yes, recursion is another possibility :slight_smile: )

Thanks so much Jean. The different approaches, including the global variable idea (which I have not tried) are very helpful.

Just thinking about the problem and coming from an Erlang background, I would like to use recursion and I’d be most grateful if you could show me how to do it that way, as I’ve hit a brick wall with the “cycles not permitted” message.

You should think of your patch as if you were building a S-expression. Cyclic graphs are not permitted, as the message says :slight_smile:
The Help-patch “factorial” (in “Core feature”) can be a good start to figure how recursion works.

For your example, I guess you could do something like this:

This patch at step N takes the last three elements of the result from the recursive step N-1 and appends their transposition to it. At N=0 it just returns the input list.

Hi,

Well I got the non-recursive versions working. Thanks!!!

In the recursive version,

  1. I’m not familiar with the LISP 1- box. If I type that, I don’t get a box with an input!?
  2. Do I work up the middle part of the patch, save it, they drag it into this patch?

Thanks.

Don

1- just subtracts 1 to the input. You can also use - with 1 as second input.

In order to embed a patch into itself you can proceed just as you would do with another “external” abstraction (the patch must be saved on the disk before).

  • drag the file from your file system into the patch editor
  • or use the menu “Add box” (or right-click) then “External abstraction” and select a file using a file chooser
  • type ‘p’ and the name of your patch (relative to the current patch)

See also:
https://cac-t-u-s.github.io/om-sharp/pages/abstraction#global-abstraction
https://cac-t-u-s.github.io/om-sharp/pages/recursion

Aaaaaaaaaaaaahh!! (Post must be at least 20 characters long) LOL