jmoenig / Snap

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

Unclear what the type coercion rules are #2112

Open ToonTalk opened 6 years ago

ToonTalk commented 6 years ago

I would have expected all of the following to have the same truth value.

image

Sometimes it always converts text to numbers even if there are spaces on either side of the text. But it seems = sometimes corerces while + always does. Is there a general rule?

jguille2 commented 6 years ago

Yes, sometimes this type conversion may confuse. We have a non-typed system, but really we have strings and numbers!

Usually, conversion rules are quite clear, but not always... but we can use "math operators" and "string operators" to force some changes be sure of the result.

In fact, the "comparison operators" seems like a non-stricted comparison... but this is not the truth: you can see snapEquals function and we have an strict comparison after some changes... These changes make a case-insensitive comparison and also a string->number conversion... but this conversion does not allow whitespaces_(I think this is the great confusion here).

Then...

In the first two cases, we have only the comparison operator, and it is running as I've commented. The block try to convert the string into a number. And yes, "12"->12 (1st case). And it would also go well with other cases like "+12"->12, or "12.0"->12. But, as I said, whitespaces are not allowed, and then " 12" is not converted to 12.

But int the third case, we have a math operator and then, it try to convert strings to numbers in the normal way (here whitespaces are allowed). So the conversion is not into the comparison, is into the sum. Then " 12 " + 0 is converted to 12 + 0. And after this, the comparison block has to do nothing else: 12 === 12 is true.

cycomachead commented 6 years ago

The type coercion inherits from Javascript. Plus it includes some stuff Scratch invented. IMO, this is one of the worst aspects of Snap! as a programming language.

In this case, the behavior is definitely confusing. I didn't expect the 3rd to work initially, but it did, and it turns out JS doesn't care about leading or trailing whitespace around numbers.

The second seems to because by Snap! checking for whitespace when dealing with it's numeric conversion in snapEquals. (line 99). To be honest, I don't quite understand why. I get protecting against special values, but I don't see what the extra complexity is preventing.