jmoenig / Snap

a visual programming language inspired by Scratch
http://snap.berkeley.edu
GNU Affero General Public License v3.0
1.52k stars 748 forks source link

Script Variables and Reporters Are Visually Indistinguishable #2988

Open peterstory opened 2 years ago

peterstory commented 2 years ago

Working on BJC Unit 2's Lab 1, one of my students created a very confusing bug: https://snap.berkeley.edu/snap/snap.html#present:Username=peter_story&ProjectName=U2L1-NumberGuessingScriptBug

Reading through the code of the numberguessinggame block, everything seems fine! But the program has very strange behavior:

It turns out, the issue was because the student had created a secret number reporter block, and was using that, instead of the script variable. This seems like a UI design issue – when code is different, it should look different. Why not make script variables gray?

The attached screenshot illustrates the problem.

Screen Shot 2022-02-25 at 3 20 01 PM
jguille2 commented 2 years ago

Hi Peter @peterstory ,

Why not make script variables gray?

This is not a solution. You can create gray (other category) reporters with the same name.

So, the "issue" is variables and reporters has the same shape. But this is not so bad (I think). Because variables are also reporting... then it is a good visual metaphor. And the problems with their (variables) names is also in their design. I mean that you can create a "script variable" with the same name of a "local/global variable". You can also create a reporter with the same name as a "primitive reporter". And then, their evaluation depends on the context!! And you have to take care of names!!

Joan

brianharvey commented 2 years ago

when code is different, it should look different.

This isn't a principle in text languages! You can have a dozen variables named x with different scopes if you want. (Worse, in a sans-serif font you can't visually distinguish a variable named capital I from one named lower case l.)

As for variables and reporters, we do have a visual difference: variables are orange. If you make an orange custom reporter, presumably it's because you've chosen to have it look like a variable, for whatever reason.

DarDoro commented 2 years ago

Function call is usually denoted by "()". In Snap! the only way to distinguish "var x" from reporter "x" is looking at context menu ;) Maybe something like untitled script pic - 2022-02-26T185123 805

jguille2 commented 2 years ago

But Dariusz, as Brian has said, we have a color "orange" for variables. We don't need anything else.

Just don't create reporters on this category that are not really a "variable operator reporting".

peterstory commented 2 years ago

I agree that it is possible to avoid this issue, but the problem when teaching is that students make all kinds of creative mistakes. Thus, the more usable the programming environment, the better. And this is clearly a usability issue.

Typically, in a text-based language, when code references a variable named secret_number, the variable with the closest scope is used. Thus, in the example I gave, the script variable (i.e., instance variable) would be used. The usability issue is that this isn't what happens in Snap – if the reporter block is dragged in, that can be used. The reason this arose in this case was because the student was refactoring code that had originally been written outside the numberguessinggame block. This happened in a class of 20 students, so I can't imagine this occurrence would be very rare.

So in this case, I think a text-based language would be more usable. The closest analogy with a text-based language would be if you had a hidden, non-printable character as part of a variable name. Then, you could get different behavior if you copy-pasted or retyped the variable name. Hence, why good text editors use fixed-width fonts and expand non-printable characters.

I don't know what the best solution would be for this, but it doesn't seem like it should be an insurmountable problem.

gigamonkey commented 2 years ago

Wait! This means that Snap is a Lisp-2. The Scheme gods are likely to smite us all for this blasphemy. ;-) (I'm new here but I agree with @peterstory that needing to know where a thing was dragged from to know what it means is pretty confusing. Here's a highly simplified example:

image

In my actual script this block does not say 42 but rather this:

image

because the test in

image

Is actually this block:

image

I agree that not being able to visually distinguish those two cases is unfortunate. If Snap was a Lisp-1 and the test in the say was evaluated to be the script variable rather than the global block, then I think all would be well.

brianharvey commented 2 years ago

Yes, Snap! is a Lisp-2. This is one of many design decisions we inherited from Scratch that I would change if we were starting fresh, although to be honest I'm not sure how we would represent that change visually. This is why our HOFs have to use CALL: untitled script pic In real Scheme the variable can just be the leftmost expression inside parentheses. To make that work we'd have to have all blocks, including reporters, have the tabs for snapping them into a script, and also the orange variable blocks would have to have arrowheads to add input slots, or else somehow change shape when assigned a procedure as their value. (That would be pretty cool, actually, although in practice the variable gets assigned a value at runtime, not while you're editing your HOF in the Block Editor, and so in the editor we don't know what the arity might be. So we have to have something like arrowheads to let the user tell us.)

But, I think all of this isn't necessary to answer the original question. That answer is, if you don't want your niladic procedure confused with a variable, don't make it orange! Orangeness is how we represent variableness visually. Yes, students do weird things, but when they make niladic orange reporters, ask them why they want their reporter to look like a variable!