Variable value evaluation problem - Is 'nothing' = 'blanks' = 0?

Hello All,

Came across this one:
Make sure to press DELETE and BACKSPACE a few times to make sure 'set myValue to __ ' setting and 'wait until myValue > __ ' setting is set to "NOTHING". I don't know how else to express it: goal is to have nothing (no spaces, blanks etc) in the field.

Then click the FLAG.
The code waits for a change in the myValue var.

Now:

  • myValue reporter on screen shows no value. That's good !

  • if you set myValue to 0, it will not come out of the wait !

  • if you set myValue to 'n spaces', it will not come out of the wait !
    *In this case, the myValue reporter on screen shows value = 0, regardless of number of spaces used ??? *

  • Anything else, it's good to go (well maybe ! Did not test every single possibility :wink: )

  1. What browsers show this problem? Version 78.0.3904.108 (Official Build) (64-bit)
  2. Please share an example project (if possible). Above
  3. Describes the steps to reproduce this issue. Above
  4. What does Snap! currently do? As described
  5. What should Snap! do instead? I was expecting any spaces or numeric 0 input to terminate the wait.

That's interesting.

It would do more nearly what you expect if you used NOT (___ = ___) instead of >. I'm not positive about this, but I think what's happening is this: > uses numeric comparison if its inputs are both numbers, otherwise alphabetical order (that is, Unicode order) comparison. An empty input is a Javascript null, which looks in memory like a 0. So if you compare 0 with an empty input, all three relational primitives report False. This is a suboptimal behavior, but Jens is reluctant to do full type checking because that slows down evaluation. Similarly, and I don't have a theory about why, if you compare space with null, all three operators report False.

You could write your own comparison functions that use the IS (value) A (type) block to ensure that the things to be compared are in fact comparable. That's the best thing I can suggest.

Thanks Brian,
I should not have placed this into BUGs category.
NOT (___ = ___) sure did it.
For some reason, when I look at COMPARISON ops I keep grouping them as similar in operation. But NOT = has special magic.

My Comment on Unicode:
NULL = 0000
SPACE = 0020
ZERO = 0030
Even a comparison without type, but just based on Unicode should have given correct behaviour, no ?
The block "unicode of __" reports NOTHING=0, SPACE=32, ZERO=48.
But variable reporter shows SPACE as 0 value.

Hi @tguneysu,

Only a comment.

The problem is not the variable reporter. When "set "variable reporter" to a SPACE, that variable reporter shows still a SPACE.

Current behavior of these operators with these inputs (spaces, empty strings...) is caused by these operators themselves. More specifically, by the management of their inputs..

  • GreaterThan and LessThan operators try to convert inputs to numbers. Not Unicodes values, just numbers. Then, "empty strings" or "blank spaces" are converted to 0. Just JS conversion (just a = +a). If this conversion is possible (for both inputs), return comparison of those numbers. But if it is not possible, then return comparison of strings (now yes, lexicographic order)

  • EqualTo is different. It check input for "specials" (empty spaces, tabs, line feeds...) and also makes some work on "typology" (booleans, lists...)

Conclusion. This behavior is not only for "speed" performance... this also for types conversion. Snap! values (and also variables value) has not types... but as JS entities has its type and a conversion rules. So, we need to define "type casting" on "slots inputs". Its the same "problem" we have in other blocks (Ex. "switch to costume ()" If () is a number, it changes to custom number (order), although a costume has this name (a number as a name).

The root of the problem, imho (Jens will disagree), is the Scratch convention that an empty input slot means zero, which we inherited. That kind of makes sense if input slots are always text or numbers, although as Joan points out, even in Scratch there are unfortunate edge cases. The interchangeability of digit strings and numbers ultimately comes from Logo, where it was designed to let kids work with text and numbers without having to worry about types at all. It may be the wrong choice for adults; I'd have to think about it more to have an opinion.

I exacerbated the problem by inventing a different meaning for an empty input, namely, an implicit formal parameter into which argument values are placed when a procedure is called.

Someday we'll figure out a perfect way to handle all this...

Unless we are talking about different things, my experience regarding SPACE setting is as captured below:

Hi @tguneysu,

Yes, but this is a watcher issue. Your SPACE is still a white espace (' ')

spaceVar

Watchers are again doing a conversion. Why? The origin is the feature of rounding "big numbers". And this is another issue. I'm sorry, and maybe we can check this behavior, but I want to point that it has not relation with our "operators issue" and show clearly that the "variable content" is not changed ( SPACE is still a space, although the watcher shows a "0")

Joan

OK, I used the wrong term REPORTER. I should have said Watcher.

Yeah, the watcher issue is a known bug that Jens should get around to some day...

wait, no! That's a feature that was actually not all that easy to implement, so watchers behave the same as in Scratch!

Wait, we go to extra effort to put the wrong thing in the watcher for a string of spaces? Feel free to remove that code! There's no reason for us to slavishly follow Scratch's bugs.

While you guys are at it, might as well "FIX" the BLANK watcher as well, so it all looks just like in SCRATCH !
image

4559042

Ha ha. Don't give Jens any ideas.

But Brian @bh, I don't think this requires a quick fix. There are more than one "issues" (or details) around "casting JS types". We can't be changing continuously our behavior. We must write down this and later, open these "design issues" carefully (with time) and, maybe, change to a more "clever" (and global - coherent) solution.

  • I think this issue can help users be clear about current behavior and to keep in mind all these "casting issues". As I pointed, this is present in many input slots (no only comparison operators and watchers)

  • We can write down these "confusing issues".

  • To write down clearer (to reopen later), here the repetitive problem is that some strings cast to numbers (to 0) and maybe we don't want this. For example, the "watcher issue" is:

        if (newValue !== '' && !isNil(newValue)) {
            num = +newValue;
            if (typeof newValue !== 'boolean' && !isNaN(num)) {
                newValue = Math.round(newValue * 1000000000) / 1000000000;
            }
        }

Then, here, white spaces cast to 0. Really, we can fix this easily, adding this exception and avoiding its "casting". But, as I've said, this behavior is living in other functions... and I prefer to wait and implement a global solution (and thing carefully other "strings cases").

Joan
`

Oh, I'm not saying it's urgent. But, for example, if I create a string of digits with one or more leading zeros, the zeros should appear in watchers, inputs, etc. unless and until I, the user, do arithmetic on the value. (One project I like to assign as a teacher is to spell out large numbers, such as 1,003,784. One family of solutions will have "003" as an intermediate value and may treat it as a string.)