Nested Function as Looping Routine - how to access arguments/variables without using environment variables?

Dear all

I’m stuck with something here. In order to stop a looping Routine, I need to call it as such, which is a trick I found here somewhere.

x = {var dur=4; {dur.postln.wait;}.loop};
y = Routine(x).play
y.stop

that works. now I wanted to change ‘dur’ but since x is a function I pass as a routine, I don’t seem to be able to pass it anything. I’ve tried:

x = {arg dur=4; {dur.postln.wait;}.loop};
y = Routine(x).play // prints a huge number
y = Routine(x.value(1)).play // freaks out because I need to pass the function not its value

I’m sure there is a way but I’m stuck. Help? Thanks

Why not make it a variable?

y = Routine({  
	~delta = 3;
	{~delta.postln.wait;}.loop
}).play

~delta = 1

y.stop

yes I forgot to say : I know I can make it an environment variable but is there another way ?

If you want to decide the wait time once when creating the routine, you can use a routine constructor function:

f = { |dur|
    Routine {
        loop {
            ...
            dur.postln;
        }
    }
};

r = f.value(1).play;

Since you’re playing the routine, argument passing into the routine is under control of the clock – you don’t have any access to those parameters. So there is no way within Routine to pass a new value in.

However, you could create a class which holds a routine, and also manages the wait time. That is, it’s a very common conceptual error to assume that routine should do everything. Often it’s better to use routine as a component of a larger structure.

hjh

1 Like

this is good to understand the limits of the nesting of functions and variables:

So I can get a function to create a routine in your solution but won’t be able to access the value once it is created. so the environement variable solution of @jordan is more what I wanted but hey, this is good for me thanks.

Or see Tdef’s envir property, for a localized solution that’s bound to the routine (which is pretty much always better than free-floating variables).

hjh

Tdef(\t, {|env|
	env[\delta] = 3;
	{ env[\delta].postln.wait }.loop
})

Tdef(\t).play
Tdef(\t).envir[\delta] = 1

This isn’t in the docs, think this makes a good example?

ok, this is great. I need to go and work on my know-how on Task and Routine and Tdef and stuff. I will look at the help file and hopefully, some tutorials to get my head around them, but this solution is great. Thanks both