Here's the project. It uses a list called "vars", which contains all the pure Snap! variables and their values.
Nice, although in the case in which you're changing the value of an existing variable it's traditional to REPLACE ITEM 2 OF the name-value pair rather than replace the entire pair.
You might be interested in thinking about what would be involved in inventing script variables along the same line (which would be quite a lot harder).
Just on a coding style note, I think it's better to be explicit and test to see if variable exists
rather than just relying on Snap! not giving an error with the replace block
No, that's a good general principle, but your actual code won't work. The case of interest is that we are maybe changing the value of a variable, so (LIST VAR VAL) won't be in the dictionary. It'll be (LIST VAR something-else).
Of course - should have thought it through
Should just check if var is in list
Also, Snap! design says reporters should normally return nothing (Sorry Brian- empty string) if they have nothing to report
We mathematicians don't like the idea that an empty string (or zero, or all the other things people use in that way) is "nothing." You could make a good case for returning FALSE. It's not so terrible to return an empty string, just don't call it "nothing." That would be if we displayed a little speech balloon with a red X over it.
We might need an explicit null value in Snap!, like JS
undefined, or Python
Edit: I can make one, but I need the exact functioning of JS
Done. It isn't exactly the same as the built-in script variables, but it should work. Pics:
Edit: An example:
Edit 2: Strangely:
(Actually, it's because "scrtps" was set to an empty list, but I'm accessing "scrpts". With the fix:
Yes !!! Holy words, it's exactly why I was disgusted with the use of "empty" slots to substitute parameters.
The trouble is that if you give a local variable the same name as a global variable, the global is deleted at the end of the DO. You need a separate list for each procedure invocation. (And, therefore, when looking up a value you need to look in a potentially large number of places. But the places you have to look aren't all pending procedure calls -- that would be dynamic scope -- but rather all the DO invocations inside which this DO appears.)
Ah. Indeed, it'd be much better if the two were distinguished visually, maybe by making empty slots gray and slots with an empty string white, or something. But that would raise the question of how you type in an empty string, etc.
A better visual indication, I think, is that when you put a block inside a gray ring, we visually indicate where we intend to do substitution when that ring is CALLed, which is hard because we have to look at the CALL to find out how many actual inputs are provided. Often this isn't so hard because the ring occurs inside the CALL itself, or inside another higher order primitive such as MAP. But for user-defined higher order functions we may need the user's help in specifying the arity as part of the input type. I'm still trying to talk Jens into this.