# Function with Global Variable

Hi all-
Running into a little confusion here, I was hoping someone could help.

I’ve created a function to take a “starting number”. If the starting number drops below 2, it is reassigned a value of 20. There is also a random function, depending on the outcome it will subtract either a 1 or a 2 from the starting number, with each iteration.

``````~func ={ |start|
var rand = 3.rand;
start.postln;
if (start<2, {start = 20;},
{
case
{rand == 0} {start = start - 1;}
{rand == 1} {start;}
{rand == 2} {start - 2;};
});
start;
};
``````

Now, obviously, if I start calling on this function with a start number, it never accumulates the changes.

``````~func.(10);
``````

I could change all of the variables in ~func, so that they were global variables - and that would potentially fix the issue… but then, the function would no longer be flexible to be used in multiple instances.

I’m curious how a problem like this is dealt with in SuperCollider. My apologies if I haven’t explained it well. I can try to fill in some of the details as necessary.

Thank you!

Hi,

It looks like you want to make a function that you can call many times and get a different value out? That isn’t best achieved with a function, but with a routine (or something else).

Does this do what you want?

``````~mkRoutine =  { |initialValue|
fork {
var start = initialValue;
loop {
if(start < 2) {
start = 20;
} {
var r = 3.rand;
case
{r == 0 } { start = start - 1 }
{r == 2 } { start = start - 2 }
};

start.yield;
}
}
}
``````
``````~f = ~mkRoutine.(20);

// repeatedly call this
~f.()
``````

Which produces this output?

``````-> 18
-> 16
-> 15
-> 13
-> 11
-> 10
-> 9
-> 7
-> 7
-> 7
-> 7
-> 6
-> 5
-> 5
-> 5
-> 5
-> 5
-> 5
-> 3
-> 3
-> 1
-> 20
-> 20
``````
1 Like

Well, I was hoping to use it as a function, since I’m using it with the Pattern language… but there is maybe an easy way to wrap it into a Prout, so I will dig around and see what I can come up with. Thanks!

Just remove the fork and put it directly in the `Prout` as a function.

``````~mkRoutine =  { |initialValue|
var start = initialValue;
loop {
if(start < 2) {
start = 20;
} {
var r = 3.rand;
case
{r == 0 } { start = start - 1 }
{r == 2 } { start = start - 2 }
};

start.yield;
}
};

Pbind(\dur, 1, \f, Prout{ ~mkRoutine.(10) }, ).trace.play
``````
1 Like

It’s about as easy as it could possibly be: `Prout { ... }`.

hjh

And in case you do ever want a simple closure, the idiom is:

``````var f = { var x = 0; { x = x + 1; x } };
var g = f.value;
[g.value, g.value]
``````
1 Like

Out of curiosity, if I were dealing with an array in this situation, as opposed to a single number - would there be a way to take the array returned by Prout and apply it to something like a Prand?