Discuss Scratch

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:

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

SimpleScratch wrote:

All good stuff but if at this stage of programming - its time to move onto to Snap! or GPBlocks

I 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.

Powered by DjangoBB