Data types: Clarifcation needed

After coming back to Snap! after a while of programming in JS, I've come to notice something:

Data doesn't have types here, instead the type is detected as you use the values.

For example, true is interpreted as the number 1 when evaluated in the plus block, but as the text true when evaluated in the join block. Hence, true plus true equals two, but joining true and true gives us true true.

This means that we can convert numbers to text and back quite effortlessly compared to other languages. Data types don't matter, it just chooses the best data type that will work for the job, and goes with that.

But there's some behaviour that I need clarification on:

I have a sprite with two costumes. The first costume has the name 2, and the second costume has the name 1.

The switch to costume block can be given input in one of three ways:

  • Selecting the costume manually: switch to costume, weird drawing
  • Inputting a costume number: set test to 2, then switch to the costume defined in test
  • Inputting a costume name: set test to, weird drawing, then switch to the costume defined in test

The curious behaviour occurs when the costume names themselves are numbers. This is what happens:

  • switch to costume, one plus one switches to costume #2.
  • switch to costume, join two switches to the costume named 2.

Wait a second, that conflicts with what we discovered earlier. one plus one reports two and join, two, also reports two, which is the same. If values did not have data types, then the switch to costume block would not be able to tell if that 2 is a number or some text, and it would have to guess. But somehow, it knows whether the 2 came from a math operation or from a text operation.

The, is value a type, block doesn't seem to want to corroborate this though. I've fed it some questions like so:

  • is, one plus one, a number, reports true.
  • is, one plus one, a text, reports false.
  • is, join two, a number, reports true.
  • is, join two, a text, reports false.

The, is value a type, block says that both one plus one and join two are numbers. It is completely oblivious to whether 2 came from a number or a text operation, or it just doesn't care. I would expect at least the last of those four to report true, but nope!

Yet from the costume tests, it is clear that these values contain associated information of their "type," or at least, what type of operation was used to make them. This even works through variables with the costume method too!

Clearly the, is value a type, block is either lying to me or using a different method of finding the value's "type."

So what's up with data types, and can they be controlled? For example, what if I want some text that is 2?

Well, first of all, our official position is that people who try to use small integers as costume names (or sprite names, or anything names) deserve whatever happens.

For the most part, we don't worry about types, which means in practice that we give you whatever the underlying js code returns. And, you're right, we convert between strings of digits and numbers when necessary to fit the domain of some function.

IS _ A _ ? tries to give you a consistent answer even if some value is convertible between types, and so in particular it errs on the side of calling something a number rather than a text. (But we remember if some value was reported by a predicate, in which case it's a Boolean even though under the hood it's 0 or 1.)

If you really need a string of digits, just say JOIN (X) (foo) and you'll have a string that can't be auto-converted to a number, then at the last moment you chop off the X.

TL;DR: We try to make things easy for users so everthing does what they mean, rather than optimize for users who are carefully studying data types.

That's funny, because that's the same result in javascript.

console.log(true + true);
// result is 2

console.log([true,true].join(''));
// result is 'truetrue'

Snap is written in javascript, so values are the same in javascript.

When I saw that integer-named costumes appear above the divider line in the dropdown menu for costumes, I figured that things were about to get weird. Normally, your costumes are supposed to appear below the divider.

What I gather from everything so far is that number/text datas do have an implicit type that is based on where they come from, but numbers can be converted to and from their text representations on a moment's notice whenever called upon.

The text 5 and the number 5 are virtually indifferent and can both be used in practically any operation involving numbers and/or texts. Here, the underlying "type" does not matter. Hence, is value a type reports it as a number, even if it came from a text operation.

So in a sense, although is 5 a text, that's technically inaccurate: all numbers can be texts if you want to make it so; just input your number into a text operation and boom, done! The only time where the underlying "type" actually does anything is when you do weird things like the costume experiment, which is a good way to measure this hidden "type," although probably not a good solution for real projects.

It appears that I have, in addition to the costume method, found another way to detect the "underlying type." Check this out:

  • Forcibly casting a number to a boolean
  • Forcibly casting some text to a boolean

This is a forced cast, where I am forcing a number or text to be casted into a boolean so that the if block can evaluate its “truthiness.” And here, the underlying data type does make a difference! It uses the casting rules of that underlying type, where 0 => false but "0" => true.

I don't think I'd be far off if I guess that Snap!'s official position on casting numbers and texts to booleans is that they "deserve whatever happens" too.

No, no. Variables do not have types! Values have types. That is, data have types. Variables are just pointers to values, and I guess you could say their type is the type of whatever value they have right now.

The input type indicators suggest that formal parameters have types, but in fact you can put any value into any input slot; those type indicators are just hints. Exception: Procedure-type input slots aren't just hints; they have to have a procedure as their value. (I guess you could unringify a corresponding actual argument expression, but nothing good will happen if you then try to CALL or RUN that input.)

Typo, whoops. Fixed now. Gotta work on being more clear!

I can confirm from my tests. If you put a text into a circle "number" block, you will still get that text. It does not perform an automatic cast just because the circle block is a number, it only casts if the operation of that block requires numerical conversion.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.