Control Structures behaviour

Hello again, sorry for posting so many questions, but I’m in full develop mode right now :smile:
I’m trying to figure out how to remove indexes from a List only if there are any left to remove. I tried to write this:

    h = List.fill(10,{arg i; i});
    (
    Routine {
    	if(h.notEmpty,{
    		inf.do({arg i;
    			h.remove(h.choose);
    			i.postln();
    			if(h.isEmpty,{postln("empty");});
    			1.wait;
    		});
    	});
    }.reset.play;
    )

or this:

h = List.fill(10,{arg i; i});
(
Routine {
	if(h.isEmpty,{}, {
		inf.do({arg i;
			h.remove(h.choose);
			i.postln();
			if(h.isEmpty,{postln("empty");});
			1.wait;
		});
	});
}.reset.play;
)

you can see that the inf.do loop is till going on because on the post window i.postln(); keep posting arg i even if h.isEmpty = true or in the other case h.notEmpty = false.
What I’m doing wrong here? :sweat_smile: Thank you

Add on
I tried this:

    h = List.fill(10,{arg i; i});
    (
    Routine {
    	if(h.size != 0,{
    		20.do({arg i;
    			h.remove(h.choose);
    			i.postln();
    			//if(h.isEmpty,{postln("empty");});
    			0.2.wait;
    		});
    	});
    }.reset.play;
    )

and it seems that even if h.size != 0 or h.isEmpty = true or h.notEmpty = false, it still keep to run the .do function until it’s over (and in the case of inf.do it never ends).
Also tried this:

h = List.fill(10,{arg i; i});
(
r = Routine{
	20.do({arg i;
		h.remove(h.choose);
		i.postln();
		if(h.isEmpty,{postln("empty");});
		0.2.wait;
	});
};

Routine {
	if(h.notEmpty,{
		r.reset.play;
	}, {
		r.stop;
	});
}.reset.play;
)

Translate it into English: you’ve written, “If the list is initially not empty, then do this thing forever.”

I guess what you wanted is “If the list is not empty, do this thing once and go back to the if test.”

That’s while { test } { loop body }.

Note that you’re responsible for updating the index yourself. If you still want to use do, you could use an early-exit structure:

`
block { |break|
inf.do { |i|
if(h.isEmpty) { break.value };

};
};


hjh

That’s it! I always forgot that Routine are not continuosly running by themselves :sweat_smile: I’m using aslo Procesing and I may have misconfused with the draw() behaviour…

So, another trick could be doing something like:

    h = List.fill(10,{arg i; i});
    (
    	Routine {
    		inf.do({
    			if(h.notEmpty,{
    				inf.do({arg i;
    					h.remove(h.choose);
    					i.postln();
    					if(h.isEmpty,{postln("empty");});
    					1.wait;
    				});
    			});
    		});
    	}.reset.play;
    )

Thank you so much!

For the intended code flow, if(something) { infinite loop } (even if the loop contains a wait) just doesn’t mean the thing that you’re trying to express. The condition to exit the loop is outside the loop, so it’s never checked between loop iterations. You really need while or an early exit (block in SC).

hjh

1 Like