Type Checks Pt. 1: Statements
Blockly’s type checking system was originally created to model value typing.
For example, it would be pretty confusing if you were allowed to connect an “uppercase” block to a number block.
But Blockly’s type checking system prevents this by giving the different connections a type check:
The uppercase block can only accept strings, while the number block can only connect to connections that accept numbers.
The type checking system makes a lot of sense when you think about it this way, but it gets more confusing when you try to apply it to stacks of blocks.
How would you make it so the blocks are only allowed to connect in that order? Statements don’t really have a value type... so what are we modeling?
Firstly let’s clarify how the type checking system actually works so that we can get a better mental model.
The checking system basically consists of two arrays of types, one array on the female connection and another on the male connection. If any of the types exist in both arrays, then the connections are allowed to connect.
If you think about it this way it’s more like we’re giving the relationship between the blocks a type, rather than typing the blocks themselves.
Also (as a bonus piece of trivia) if an array is empty that means it can connect to anything, no matter if the other connection has type checks or not.
If we think of “typing statement blocks” as “defining the relationship between blocks” instead, that makes it a lot easier to create things.
For example, say we wanted to define the relationships between the blue, yellow, and red blocks so that they always went in that order.
We’d just have to give the relationship between the blue and yellow a type (in this case I chose “greenRel” for the name), and then give the relationship between the yellow and the red a type (in this case “orangeRel”).
Now it is impossible for the red to connect to the blue without the yellow being in the middle.
Nothing else can sandwich itself in there.
And it’s impossible for the yellow to connect to itself.
“But” I hear you saying, “what if I do want the yellow to connect to itself, so that there can be lots of yellow blocks sandwiched between the blue and red ones?”
Well luckily, that’s completely achievable as well.
If we look at the yellow blocks in isolation we have a simple set of relationships, where the top and bottom connections of the yellow block are both typed “yellowRel”.
Then we can combine that with the early set of relationships to give us the functionality we want.
Now we can have as many yellow blocks as we want, but the blue and red blocks are still not allowed to connect.
“But” I hear you saying once again, “what if I do want the blue and red blocks to connect? I mean who likes those yellow ones anyway?”
That’s actually pretty easy, because now the relationship between your blues and your reds has become the same as the relationship between your blues and your yellows (that is, they can connect). We just need to name the relationship to reflect that, in this case I chose “blueRel”.
Now let’s try one last (seemingly) complicated thing. Let’s try and define relationships so that the blue can either have only yellow after it, or only red after it.
We could start by defining the yellow and red blocks to connect to themselves.
And then define the blue block to accept either by setting its connection to have both “yellowRel” and “redRel” types.
Or we could start by defining the blue’s relationship (in this case I picked “blueRel” for the name). And then define the yellows and reds to connect to “blueRel”, as well as themselves:
Either of these options give us the either/or functionality, because it is impossible for the red and yellow to connect.
With this mental model you should be able to create as many complicated connection rules as your heart desires. That is, as long as you’re not worried about surrounding blocks. More about that in the next post!
EDIT: The sequal to this post ran into a bug with insertion markers (#2948), so it has been delayed. - 9/2/19