Discuss Scratch
- Discussion Forums
- » Advanced Topics
- » Workarounds for script-local variables
- rdococ
-
Scratcher
1000+ posts
Workarounds for script-local variables
This is a list of workarounds for the idea of adding script-local variables. These would be variables that are local to one thread instead of one sprite, so that a particularly complicated script or custom block can perform calculations without interference. This was inspired by this topic.
1. Sprite-local variables
You can try to use sprite-local variables to emulate script-local variables, but this has a number of caveats. If the same variables are used in multiple scripts at the same time, there will be interference between them which you may not want - but you can fix this if your scripts don't need screen refresh. This may also clutter the variable list.
Here is an example:
2. Use a list as a stack
This method is perfect if your scripts don't need screen refresh, but it requires a bit of extra work.
3. Use a system of first-class-ish lists
This requires a system that allows you to store many lists at once in one or two lists, that contain all of the items, and the starting item numbers and lengths of each list. Then when you want to make a change to one of the stored lists, you'd run a block to load the stored list in a Scratch list, make some changes, and then update the stored list with those changes. However, it should work perfectly if done correctly.
4. Use recursion
This is my favorite method, because it only uses one variable, it's simpler than the other methods I've found, and it works. The basic idea is that instead of changing any variables, you run the next part of the script as a custom block, with the changed value of the variable as a custom block. It reminds me of functional programming, which is probably because you're working with custom block inputs, which are basically variables you can't change.
1. Sprite-local variables
You can try to use sprite-local variables to emulate script-local variables, but this has a number of caveats. If the same variables are used in multiple scripts at the same time, there will be interference between them which you may not want - but you can fix this if your scripts don't need screen refresh. This may also clutter the variable list.
Here is an example:
define fibonacci (n)
set [a v] to [0]
set [b v] to [1]
set [c v] to [0]
repeat (n)
set [c v] to (a)
set [a v] to (b)
set [b v] to ((c) + (b))
end
set [fibonacci result v] to (a)
when gf clicked
forever
ask [Number?] and wait
fibonacci (answer)
say (fibonacci result) for (2) secs
end
2. Use a list as a stack
This method is perfect if your scripts don't need screen refresh, but it requires a bit of extra work.
define fibonacci (n)
add [0] to [stack v]
add [1] to [stack v]
add [0] to [stack v]
repeat (n)
replace item (last v) of [stack v] with (item ((length of [stack v]) - (2)) of [stack v])
replace item ((length of [stack v]) - (2)) of [stack v] with (item ((length of [stack v]) - (1)) of [stack v])
replace item ((length of [stack v]) - (1)) of [stack v] with ((item (last v) of [stack v]) + (item ((length of [stack v]) - (1)) of [stack v]))
end
delete (last v) of [stack v]
delete (last v) of [stack v]
when gf clicked
delete (all v) of [stack v]
forever
ask [Number?] and wait
fibonacci (answer)
say (item (last v) of [stack v]) for (2) secs
delete (last v) of [stack v]
end
3. Use a system of first-class-ish lists
This requires a system that allows you to store many lists at once in one or two lists, that contain all of the items, and the starting item numbers and lengths of each list. Then when you want to make a change to one of the stored lists, you'd run a block to load the stored list in a Scratch list, make some changes, and then update the stored list with those changes. However, it should work perfectly if done correctly.
define (stack) fibonacci (n)
add [0] to (stack) :: custom
add [1] to (stack) :: custom
add [0] to (stack) :: custom
repeat (n)
get items of (stack) :: custom
replace item (last v) of [stack v] with (item ((length of [stack v]) - (2)) of [stack v])
replace item ((length of [stack v]) - (2)) of [stack v] with (item ((length of [stack v]) - (1)) of [stack v])
replace item ((length of [stack v]) - (1)) of [stack v] with ((item (last v) of [stack v]) + (item ((length of [stack v]) - (1)) of [stack v]))
update items of (stack) :: custom
end
delete last of (stack) :: custom
delete last of (stack) :: custom
when gf clicked
clear [ask for number] :: custom
forever
ask [Number?] and wait
[ask for number] fibonacci (answer)
get items of (stack) :: custom
say (item (last v) of [stack v]) for (2) secs
delete last of (stack) :: custom
end
4. Use recursion
This is my favorite method, because it only uses one variable, it's simpler than the other methods I've found, and it works. The basic idea is that instead of changing any variables, you run the next part of the script as a custom block, with the changed value of the variable as a custom block. It reminds me of functional programming, which is probably because you're working with custom block inputs, which are basically variables you can't change.
define fibonacci (n)
fibonacci.loop (0) (1) (n)
define fibonacci.loop (a) (b) (n)
if <(n) > [0]> then
fibonacci.loop (b) ((a) + (b)) ((n) - (1))
else
set [return v] to (a)
end
when gf clicked
start.ask
define start.ask
ask [Number?] and wait
fibonacci (answer)
start.say (return)
define start.say (fib)
say (fib) for (2) secs
start.ask
- SimpleScratch
-
Scratcher
500+ posts
Workarounds for script-local variables
All good stuff but if at this stage of programming - its time to move onto to Snap! or GPBlocks 

- LuckyLucky7
-
Scratcher
1000+ posts
Workarounds for script-local variables
All good stuff but if at this stage of programming - its time to move onto to Snap! or GPBlocksI could agree with this, unless the OP was trying to create a challenge. Although a pretty advanced concept, it would well suit Snap or GPBlocks.
- Discussion Forums
- » Advanced Topics
-
» Workarounds for script-local variables


