Strange switch behavior

I’m not sure if this is a bug or if I misunderstand something about switch. I was was mapping MIDI numbers to note names for a string and noticed a strange behavior with switch

switch(60.0, 60.0, {"hi".postln}) prints but
switch(60.0, 60, {"hi".postln}) is nil

the help doc says switch performs == but 60==60.0 and vice versa return true for me

it works in an if though!

(var note=60; var num = note.round(0.5); if(note==60, {"hi".postln})) prints but
(var note=60; var num = note.round(0.5); switch(num, 60, {"hi".postln})) doesn’t

The doc is wrong. It’s by identity. 60.0 === 60 is false.

Floats are not safe for switch anyway. Don’t trust it.


Huh, the doc mentions using floats too, that’s really odd. In switch looks like this

	switch { arg ... cases;
		cases.pairsDo { | test, trueFunc |
			if (this == test.value) { ^trueFunc.value };
		if (cases.size.odd) { ^cases.last.value };

does the == there perform differently than in code I’d type? (honest question! I’m really not up on how things work under the hood)

There are a number of mistakes in the Control Structures help file. The doc should absolutely not recommend floats here.

I just tried to correct those mistakes, but because of the usual github sort of complication, I’m unable to push them to my fork and make a pull request. So currently a fixed version exists only on my hard drive. (I get very very tired of git complications…)

switch is inlined if there are no variable declarations (which is normally the case). In that case it uses a hash lookup which tests for identity.

    { 1 } { "yes" }
    { "no" }

-> no

// 'var x' prevents inlining
    { 1 } { var x; "yes" }
    { "no" }

WARNING: Float:switch is unsafe, rounding via Float:asInteger:switch
-> yes

All of which is beside the point. Floats with either equality or identity tests may exhibit counterintuitive behavior:

a = 2/3;
-> 0.66666666666667

b = 1 - (1/3);
-> 0.66666666666667

a == b
-> false

So, either way, you’re on a bit of thin ice by using floats in the first place.


1 Like



1 Like