Suppose I have a global variable named foo , and I define the following two blocks:

add 5 to foo      add 20 to (var)

Now I run the following script:

call both blocks

Will the final value of foo be 100? 105? 120? or 125? Try it and see.


Now do the following similar experiment, but with a list as the value of foo :

append 5 to foo      append 20 to (var)

call both append blocks

What items will be in foo after running this script?


Why do these two experiments give different results?

It's not surprising that the two blocks that specifically change the global variable foo succeed. But how come you can add a new item to a list passed into a block as input, whereas you can't change a numeric variable passed in as input?

Snap! is actually behaving consistently in these two cases. To understand why, you have to keep clear in your mind the difference between a value–a number, text string, Boolean (true/false), or list–and a variable, which is essentially a connection between a name and a value. (This is not precisely the definition of "variable" you'd learn in a programming language design course, but it's close enough until you have to implement a programming language yourself.)

As in most programming languages, the inputs you provide to a block in a Snap! program are values. The block doesn't know how the value was provided: typed directly into an input slot, computed by a reporter dragged into the slot, or taken from a variable dragged into the slot.

If that went over your head because it's too abstract, consider this script:

add 20 to (foo+3)

You wouldn't expect that to change the value of foo to— To what? 123? 117? It just doesn't make sense to expect this to change foo at all. The input to the add 20 to block is the number 103–the value of foo+3–not the variable. The same is true in the original experiment; the input to add 20 to is the number 105 (because the add 5 to foo block specifically changed foo ), not the variable foo itself.

The change block in the definition of add 20 to does change a variable: the variable it says it changes, namely var . That variable is local to the block's defining script, so changing it doesn't affect the rest of the program at all. Local variables are temporary; when the block finishes, the variable is gone.

What if the value of foo is a list? Unlike numbers, lists themselves are mutable. (Variables are mutable, too, which is why we're having this discussion, but only when the variable name itself appears in a set or change block.) After the two append blocks in the second experiment are run, the value associated with variable foo is the same list as it was before. But that list now has more elements. We say that it "maintains its identity" even though its contents have changed.