As someone who used scratch as a kid starting in 2009, it was my introduction into computer programming, and only exposure to it for almost four years. Most of my memory of it in its early days are about making silly video games and stories that moved. Now over a decade later, at the very beginnings of what will hopefully be a career in code, I’ve decided to take a trip down memory lane to see what scratch taught me, and what kind of language it really is.
What makes Scratch so great to use as a kid is that all of the programming is organized around sprites which are self contained objects that have a visual representation. Once you understand the basics of running a program, you can immediately, by dragging one of the “move” blocks, see something happen on your screen as a result of the code you have written. This kind of concrete objectivity immediately demystified what computers do.
Now that I’m done reminiscing, let’s look at the scratch IDE where instead of writing text you drag literal “blocks” of code that attach to one another.
In scratch, sprites are both the subject of all of the code - where it is written, and the object - what displays the code’s behavior. Sprites can be created and deleted in the development phase, but are permanent in runtime, acting as their own scope.
When I was using scratch in 1.3 and 1.4, sprites acted as single instance classes. All of their code was confined to them, and they could not be replicated. This lead to a lot of painstakingly copying sprites and slightly adjusting their code or “costumes” (their set of visual representations). But when scratch 2.0 came out, the “create a clone” block came out, making sprites now essentially classes that could instantiate new sprites. In this way, scratch is entirely object oriented. In an abstract way it is possibly the most object oriented language out there, with objects that are almost entirely self contained that correspond to objects that you can actually see and hear on your computer.
In scratch code blocks come in 9 (it used to be 8 before the introduction of the block type) types: Motion, Looks, Sound, Events, Control, Sensing, Operators, Variables, and Blocks.
The most fundamental of these blocks are the Events. These are what determines when a chunk of code starts. Most of the time when I was using it, we only used the “When flag clicked” button, which tells a chunk of code to run from execution (which happens by hitting the flag).
The next most fundamental, and definitely most important, group of blocks are the controllers. These are logical expressions the control the workflow of a program: Looping with repeat and forever, conditionals with if and if-else, waiting, and now instantiation with cloning logic!
Now you might have noticed that blocks come in different shapes. These shapes define what a block does. The three that we've seen so far are the start blocks, which can be built under but not over; logic controllers, that can be coded above, below, and within; and general action blocks which can cause behaviors or modify the environment based on the inputs that you give them.
Looking closer at the controllers you might notice that the conditionals have empty spaces for diamond shaped blocks, and that the looping controllers have spaces for rounded blocks.These two shapes are data in scratch, and are best described by the “operators” group:
Here in operators round shaped blocks perform operations on other data to output new data. Data is passed into action blocks and loopers wherever there's a round space for them, to determine the block's behavior. Data in scratch can either be numbers or strings, and the action blocks themselves are responsible for parsing this data.
There are many different data blocks available, most of which output the current state of the sprite.
The diamond blocks that conditionals take are… you guessed it: Booleans! These blocks produce either true or false, sometimes based on input like in the operators group, and sometimes based on program state like with the sensors group:
What is so incredible about the design of these code blocks, is that only now, over ten years later, am I realizing that these diamond blocks are conditionals. As a kid, everyone who used scratch intuitively knew that the diamond shaped blocks go in the diamond shaped spaces that conditionals have, and that when they were true, the conditionals did things. We were never even taught that ‘if’ was called a conditional and that it controlled the ‘workflow’ of our program. Or that ‘booleans’ have two values, true and false, that conditionals use to determine said workflow. It was all intuitive.
That design has been with scratch since day one, and is a testament to the incredible genius of MIT media labs and Mitch Resnick (the creators of scratch). They were able to take something as scary and confusing as logic and computing, and make it so intuitive, that elementary school kids could learn it without having to know anything about computers.
One thing to notice about scratch, is that cannot be ‘truthy’ or ‘falsey’ like we know and love in most modern languages: Conditionals can only evaluate on boolean values, and because of that there are specific blocks designed for conditionals which are strictly boolean.
The groups we have covered so far are the events, controllers, operators, and sensors. The next one to look at is variables, which can either be just ‘variables’ with single values, or ‘lists’, which are arrays with indices (starting at 1). The blocks available are just getters and setters, which are data blocks and action blocks respectively.
The last group of blocks is actually four groups: motion, looks, sounds, and the modifiable green blocks(which can draw things, play music, interact with hardware input, etc (in my day this was just called pen and it could draw things)). These blocks drive the most common behaviors of sprites, and are what make scratch such a great tool for education. Most kids, including me, are immediately drawn to these blocks, because they actually change what your sprite does on screen and what you hear. These are the actual behavior of your program, and they’re why scratch both a code and an art platform for kids, because you can create scratch projects without any logic that are still really cool and amazing to watch.
To recap, there are five block shapes in scratch:
- Start blocks, which have a curved top and a hook at the bottom to execute what comes below them
- Controller blocks which can be put anywhere in the execution of a chunk and can evaluate code inside of them (note that the forever loop can have code added below it because it continues to evaluate, well forever until the code stops)
- Action blocks which cause behavior, i.e. “do things”, or change the state of the sprite / program
- Data blocks, which can (to my knowledge), only be strings or numbers, that are passed into loopers and action blocks to modify their behavior.
- and Boolean blocks, which are strictly true or false, and exist to evaluate conditionals (note these can also be passed where data is wanted, and I believe they will just evaluate to the strings ‘true’ or ‘false’)
**(there are also now definition blocks which are used to create your own blocks. These are analogous to methods)
This post was mostly a trip down memory lane for me, not a proper guide to scratch. But I hope that it can shed some light on the functionality of scratch from a developers perspective.
In truth, Scratch is not a very useful language for adult developers - it has only two scopes (clones of sprites share variables with each other, i.e. no instance variables), it’s only recently received functions, which don’t support recursion, and dragging code a round is much more difficult than just writing it. But the way that the blocks fit together intuitively, and how well it engages kids makes it one of the best educational resources of any kind.
So if you have kids, or know kids, introduce them to scratch - there is no doubt that it's why I am becoming a developer today.