So in teletype we have several OPs that kinda do the same thing (note that I used x for the parameter in question here):
SCENE x (change scene to x)
P.N x (change working pattern to x)
N.B y x (sightly different, but included here, with x negative set scale to preset with root r)
There are a lot of instances where we rely on the teletype to handle out-of-range input, the above are just three examples.
So the question is, what if I call
SCENE -1? That obviously doesn’t make sense and hence would be a mistake on my part. But the question is how should tt respond:
- clamping: basically “try to comply as much as possible”, so values below 0 are interpreted as 0 and values above 31 are interpreted as 31, so in this case it would result in the same as
- no-change: basically “discard commands with nonsense parameters”, so in this case, don’t change scene at all.
To me, there should a clear logic behind why the teletype behaves as it does in each case, and cases that due to some kind of logic (which we should discuss here) fall in the same “category” should behave the same. I must admit I haven’t thought it through, but I’m tempted to say that all cases should behave the same, since it feels like a philosophical feature of a language if it’s forgiving or strict (although it could be discussed which of those two words apply to clamping and no-change).
So let’s hear it! clamping or no-change???
Excellent question… The answer should take into account the fact that TT strongly motivates concise code, so any feature like this should also be useful when deliberately employed. On that basis, I tend to think no-change would be better. For example, you could use a random number with a range larger than required in order to implement a change of pattern that’s uniform but only happens occasionally. Clamping would lead to the low and high values being hit more often than the rest, which doesn’t seem as useful to me.
What about wrapping/modulo? Python (and plenty of other languages) interprets a -1 I index as “last” and -2 as “second from last” etc and it’s useful!
That way to keep iterating through the patterns or scenes you could do so much more succinctly.
as commented in the PR, in the particular case of
SCENE op i think no action is better than clamping for a couple of reasons:
clamping can hide the fact there is something wrong with the script
i agree teletype philosophy to a certain extent is creating a safe scripting environment, but in this particular case it’s on the side of teletype doing too much for me.
if i want the side effect of clamping, i can do that explicitly with
SCENE LIM ....
if it clamps, and i would prefer it not to, it’s more difficult for me because then i would have to do something like
IF >< 0 X 31: SCENE X
i’m actually not sure clamping vs no action should be uniform for all ops. for some ops clamping does make sense - if i do
CV 1 + V 10 V 1 i would still expect it to output 10V.
for the record, i think pattern ops shouldn’t clamp. if you run
L 0 100: P I I what would you prefer value 63 to be set to? 63 or 100?
I think this is the crux of the issue. Maybe it is better to let go of the need for a “one size fits” all approach.
There are places where the clamping makes sense due to real constraints, e.g. CV output would rather max out instead of not changing.
There are places where the clamping/wrapping/no action behavior could be useful and probably deserves a modal switch, e.g. pattern indexing.
And then there are places where the existence of a numbering scheme doesn’t really imply a continuum at all, e.g. script number. I’d rather those “not on a continuum” instances result in no action if arguments are out of bounds.
The concept of “no action” is trickier for OPs which return a value, though!
If we go with your preferences, does anything have to change at this point (besides the negative and possibly > 31 return values of SCENE)? Is it sufficiently well documented?
i wouldn’t go with my preferences but with what the consensus is.
if we do want to go with the no action option, i’ve already added a check to
tele_scene function, but yeah we should fix the getters and we should document. for the getters we should just remove
variables.scene completely and instead add a new function to
main.c that would simply return
preset_select. this way we don’t have to initialize
variables.scene in multiple places.
This is a nice approach whenever the op is essentially indexing I think.
This is an excellent point, and I think suggests pretty clearly that a one-size-fits-all approach isn’t what we want (despite it appearing attractive in principle).
Also given that ansible is cv 5-8, no action on cv index out of bounds seems clearly right there.