Moved from the Teletype 2.3 beta 1 thread
I noticed some issues with variables while I attempted to make a strumming patch for Just Type. Below is a stripped-down version of that script which isolates just the issues. While the issues I’m encountering aren’t strictly bugs, I think part of the current behaviour could be changed to be much more useful. And part of it just raises tricky questions.
Clock goes either into input 1 or 3, adjust strumming rate with param. Strumming is represented on trigger outs.
M:
M RSH PARAM 4
S.POP
I:
M.ACT 1
1:
O 1
L 1 4: SCRIPT 2
2:
S: TR.PULSE O
3:
X 0
L 1 4: SCRIPT 4
4:
X ADD X 1
S: TR.PULSE X
What this scene does is use a loop to add multiple pulses to a stack and then play them out at the metro rate. It does so in two different ways.
Because I has been made local to each script, it’s not possible to use it within scripts called from a loop. This is one of the things that I think could be made much more useful: extend the scope of I to scripts called from loops and while pre statements. (and in the case of a loop within a script called from a loop, make it so the innermost I dominates)
Because relying on I within the called script is not an option, and we have to rig some other less elegant way of keeping track of indices. Script 1-2 and 3-4 do it in two different ways; 1-2 use O, which auto-increments on each read, and 3-4 simply use the X variable, incrementing it manually after pushing to stack. However, these do not yield the same result. Script 1-2 only triggers output D, while script 3-4 strum A-B-C-D. It seems that this is because variables within a command pushed to stack are read only when the stack is executed: and by that time the whole loop has ran it’s course and X = 4. This works with O because it is only incremented after it is read from the stack.
The question is: should we make the stack read values of (simple) variables at the time they are pushed? I understand that for some operators that interact with data it’s more interesting for them to be ran when the stack pops. However, for simple variables this seems like a tricky question because there are good and bad things to both ways of treating them. Maybe applying this to only a subset of the variables would be good, ie X and Y, as this allows both “on pop” and “on push” behaviours, and also makes it possible to extend these two different behaviours to “dynamic” operators like P.NEXT when needed (by storing it in those variables, then running S using those); maybe this is too much complexity. Or maybe this problem is specific to using the stack within loops, and this can be addressed by simply making I read on push (assuming the last proposition regarding I is accpeted).
EDIT: after some thought, maybe the best thing we can do to provide both ways of treating variables while reducing confusion is to make it explicit by having some kind of S.NOW (or perhaps S! for short?) operator that reads the value of the operator passing to it at the moment the command is pushed to the stack. This would also make it possible to extend it from variables to any operator, and wouldn’t break any previous scripts using the stack.
Maybe this is more fitting in the 2.2 beta thread? I’ve read discussions about I's scope somewhere but I can’t remember. And knowing how much thought has been given to the inner workings of Teletype, I’m pretty sure some people have thought about the way the stack operates before. Either way, please let me know what you think.