SandCastleIcon.png This page has links to websites or programs not trusted by Scratch or hosted by Wikipedia. Remember to stay safe while using the Internet, as we can't guarantee the safety of other websites.
Archive.png This article or section documents something not included in the current version of Scratch (3.0). It is only useful from a historical perspective.
Squeak had been used in Scratch since the first version of Scratch was released in 2007 until the release of Scratch 2.0 in 2013. Squeak is the programming language that creates the Scratch world, blocks, sprites, and everything the Scratcher sees when they use the application.

Many Scratchers wanted to get into the Scratch browser and tinker with the source code, and a whole host of modifications sprang up as a result. These modifications sometimes allow users to edit Squeak code as part of their features, such as Panther, where users can create their own blocks using Squeak. With this sudden craze of modifying Scratch, a great many guides and questions have been posted all over the Advanced Topics teaching various aspects of editing Scratch and using Squeak. This Squeak "library" allows all the creators of these guides to pool their resources and compile a large collection of easy to understand tutorials in using Squeak to modify Scratch.

Note Note: In this tutorial, the format multipleWordsWithoutSpaces is used a lot. This is standard Smalltalk practice to write many words without spaces, and is called camel case.

How a Scratch block comes to be

A block consists of two parts: the block specification and the method. The block spec tells Scratch how the block should appear and what it should do. It has four parts: the title, which contains the text of the block label along with its argument specifications; the block type, which is a symbol indicating what kind of block (stack, reporter, predicate, etc.) it should be; the message selector, which tells Scratch what code the block must run; and any default arguments. (An argument is a block input.) The method is the sequence of Smalltalk code the block runs.

Block arguments

See also: Arguments#Scratch internals

In Scratch, an argument is added to a block spec title using a percent sign followed by a letter indicating the type of argument. For example, the block spec title of move (10) steps is "move %n steps"; the "%n" indicates that the block should have a number argument. Here is a list of commonly used argument types, followed by the specification for Scratch and Panther and a description:[note 1]

Argument Specification Panther specification Description
String %s $String$ Accepts any characters
Number %n $Number$ Accepts digits, decimal points, and the minus sign
Boolean %b $Boolean$ Accepts Boolean (diamond) blocks
Sprite %m $Sprite$ A dropdown with a list of sprites
Variable %v $Variable$ A dropdown with a list of variables
Attributes %a $Attributes$ A dropdown with a list of attributes (direction etc.)
Color picker %C $Color$ A color picker with a popout pallet
Color picker %c $ScreenColor$ A color picker without a popout pallet
Directions %d $Directions$ A dropdown with a list of directions
Drums %D $Drums$ A dropdown with a list of drum sounds
Events %e $Event$ A dropdown with a list of broadcasts
Math functions %f $MathFunctions$ A dropdown with a list of math functions (abs, sin etc.)
Effects %g $Effects$ A dropdown list of effects such as color and brightness
Sensors %h $SensorNames$ A dropdown list of sensor names such as slider (for a PicoBoard)
Sensor booleans %H $SensorBooleans$ A dropdown list of PicoBoard booleans such as "A connected?"
Instruments %I $Instruments$ A dropdown list of instruments
List options %i $ListIndex$ A dropdown of list indexes (1, last, any)
Key options %K $Keys$ A dropdown list of keyboard keys
Lists %L $List$ A dropdown list of lists
Costumes %l $Costumes$ A dropdown list of costumes
Motors %W $MotorNames$ A dropdown list for the Motor Blocks
Notes %N $Notes$ A note space with popout keyboard
Sounds %S $SoundNames$ A dropdown list of sounds

Block type

These are the block types:

Block type Symbol Description
Stack - The shape of a Stack Block.png
Boolean b The shape of a Boolean block.png
Reporter r The shape of a Reporter Block.png
C c The shape of one of the C blocks.png[note 2]
Color (Panther only) g The Shape of a Color Panther Block.png
Timed t These blocks do something over a given period of time. For example: Wait () Secs, Play Note () for () Beats
Special form s A special form is any block does not behave as an ordinary block does. For example, Wait Until () must repeatedly check its argument to find out whether or not it should stop; if it were an ordinary block, its argument would only be ran once.

Each hat block has its own block type symbol, not listed here.

Finding the block specs

To find the block specs, first shift-click the R in the Scratch logo and select "turn fill screen off". Then click in the space that appears around Scratch to open the world menu and select "open…" followed by "browser". A large green window with four columns along the top and a large empty space below should pop up.

In the leftmost column, select "Scratch-Objects", which should be the first item. Then, if you want the block specs for both the stage and sprites, select "ScriptableScratchMorph"; if you want the block specs for the stage, select "ScratchStageMorph"; if you want the block specs for sprites, select "ScratchSpriteMorph". Now click "class", select "block specs" in the second column from the right, and select "blockSpecs" in the rightmost list.

Expressions, objects, and messages

Smalltalk code consists mostly of expressions. Each expression is evaluated to produce a value, or datum. The simplest kind of expression is called a literal expression; numerals and single-quoted strings are both literal expressions. For example, 42 is an expression whose value is the number 42.

Smalltalk is an object-oriented programming language. Every value in Smalltalk is an object; objects include numbers, strings, lists, blocks, the stage, and sprites. In OOP, rather than having a set of blocks to operate on data of each type (numbers and strings are two examples of types), the behavior becomes part of the data itself; objects communicate with each other by message passing. For example, the expression ((3) * (4)) in Scratch applies (() * ()) to two arguments, both of which are numbers, and reports their product; but 3 * 4 in Smalltalk, on the other hand, sends a message to 3, the receiver, with two parts: the message selector, *, and an argument, 4. (The receiver and argument expressions may be expressions of any kind.)

A workspace is a window that may be used to evaluate expressions. To open a workspace, open the world menu, select "open…", and select "workspace". Then hover the mouse-pointer over the workspace, type an expression, right-click (on Microsoft Windows) or hold down Control and click (otherwise) on the workspace to bring up a context menu, and select "print it".

Methods

When 3 receives the * 4 message, it responds by finding the corresponding method, which answers with the product, 12. Methods are written in the wide area at the bottom of the System Browser. A method definition has three parts: the message selector, the temporary definitions, and the statements. It looks like this:

message selector and argument names
	"comment stating purpose of message"

	| temporary variable names |
	statements

Smalltalk, like Scratch, uses keyword arguments, meaning that the message selector is written combined with the argument expressions. (There are two exceptions to this: messages with no arguments and a few infix message selectors, like + and *.) Each part of the message selector is followed by a colon. For example, the message selector of go to x: (0) y: (0) is "gotoX:y:". An argument expression should follow each colon, so it could be used as follows:

aSprite gotoX: 0 y: 0

In Smalltalk, a comment is enclosed in double quotation marks ("). Comments are not evaluated, but can be used to explain what is happening. It is considered good practice to give an explanation of the method (and credits, etc.) in a comment right below the message selector, if it is not clear.

The final part of a method definition is a sequence of statements, which is for the most part a sequence of expressions seperated by fullstops (with the exception given below).

Temporary variables

Temporary variables are variables the method can use within itself but are not visible or usable anywhere else.

Temporary variables are listed below the message selector (see above) between two pipes (|). They are restricted to letters and digits, and cannot be reserved (i.e., "self").

If the Scratch Source Code is not present, you will see many names like t1, t2, t3, etc., but this is not necessary; it is almost always better to give variables self-descriptive names.

Assignment

A variable, temporary or otherwise, is set using the syntax variable _ value. (The new value is said to be assigned to the variable.) For example:

modifyAVariable
	| aVar |
	aVar _ 10
Note Note: In the Squeak editor, the underscore is depicted as an arrow pointing left (←). ":=" means the same as an underscore.

Reporting values

A method can report a value, as the method for * does above. In Smalltalk, this is done by writing ^ value at the end of the method definition. For example:

report: aValue
	^ aValue
Note Note: In the Squeak editor, "^" becomes an arrow pointing up (↑).

Strings

A string is an object which represents some text. In Smalltalk, string literal expressions are written within single quotes, for example: 'hello'. To put a single quote in a string, use two single quotes in a row: 'it''s fine'.

Strings are joined with a comma message:

'Hello, ', 'John, ', ' what''s ', 'up?' "Hello John, what's up?"

Blocks

A block is similar to a C shape in Scratch — it may or may not be evaluated, or may be run many times. It is just code which the program can do anything with. Blocks are written like normal code, but in square brackets:

[t1 _ 33.
^ 'hey, there']

In Smalltalk, there are many uses of blocks. Here are some:

| t1 t2 |
t1 _ (1 = 0). "t1 contains the value false"
t2 _ (1 = 1). "t2 contains the value true"

t1 ifTrue: [^ 1]. "report 1 if t1 is true"
t1 ifFalse: [^ 2]. "report 2 if t1 is false"
t1 ifNotNil: [^ 3]. "report 3 if t1 is not nothing"
3 timesRepeat: [t1 _ t2] "set t1 to t2 three times"

The Smalltalk messages ifTrue:, ifFalse:, etc. are not special: any message could have a block as an argument.

Classes and instances

In Smalltalk, types are represented by objects called classes; each object is an instance of a particular class. A class has a name; a set of instance variables, which are variables local to each instance of the class; and a set of instance methods, which are methods that define the behavior of its instances. For example, 6 is an instance of the class SmallInteger; when 6 is sent the * message, the corresponding instance method in SmallInteger is evaluated.

When an object is assigned to a variable, a copy of it is not created. The variable only stores a new pointer to the object, which may be used to send the object messages. For example, if the variable cat points to a sprite which is then assigned to aSprite, cat and aSprite both point to the same object, so if cat is rotated, aSprite will answer the new direction. Thus, classes should implement a copying protocol, a message which returns a copy of the object by actually assembling the copy attribute by attribute. A copying protocol example will be given in a following section.

Inheritance

Every class inherits from another. An inheriting class, called a subclass, is given all the variables and methods of the parent class. For example, if "Mini Cooper" is a class that inherits from "Car", the "Car" class could implement the "drive" message, and all Mini Coopers would be able to drive.

Morphs inherit from the Morph parent class. Morph inherits from Squeak's Object class. Object is the root class. Most object-oriented programming languages provide a root class which is more or less blank. All classes are (directly or indirectly) subclasses of the root class. For example, in Objective-C, the root class is NSObject. All other classes must inherit from either NSObject or a class which inherits from NSObject. Thus, NSString inherits from NSObject, and NSAttributedString inherits from NSString. The inheritance is depicted with colons. Inheritance is shown right to left:

NSAttributedString : NSString : NSObject
NSOpenGLView : NSView : NSObject

In Squeak

In Squeak, the code of a class is extremely similar to natural language. In fact, Squeak is known as the most natural programming language.

Creating a class

First, open the System Browser. Above the scroll bar in the list on the left side, click on the button with the dash (–) on it. Then select "add item…". When prompted, type in the name of the category to which your class belongs. A category can have many classes, like vehicles can have car and helicopter. For this tutorial, name it "Vehicles".

In the editing pane, you should have this code:

Object subclass: #NameOfClass
	instanceVariableNames: 'instVarName1 instVarName2'
	classVariableNames: 'ClassVarName1 ClassVarName2'
	poolDictionaries: ''
	category: 'Vehicles'

Replace it with this. Read the annotations carefully.

Object subclass: #Car "Class name"
	instanceVariableNames: 'driver color'
	classVariableNames: '' "ignore for now"
	poolDictionaries: '' "ignore for now"
	category: 'Vehicles'

You have created a class! The class name is "Car", the instance variables are driver and color, and category is "Vehicles".

Now right-click (on Microsoft Windows) or control-click (on Mac or another operating system) on the pane and select "accept". If prompted, type in your initials.

Next, we will add a simple method. Click on "Car" in the list second from the left in the System Browser. In the next list, click "-- all --". In the editing pane, you will get a sample method:

message selector and argument names
	"comment stating purpose of message"

	| temporary variable names |
	statements

Highlight all of it, and replace it with this:

drive
	Transcript show: 'Vroom!'

Again, right-click or control-click and select "accept".

Now open the world menu, select "open…", and select "transcript". The transcript is a log where programs in Squeak can log values for debugging purposes. Also open a workspace.

myFamilyCar _ Car new.
myFamilyCar drive.

Right-click or control-click the workspace and select "accept". In the transcript, you should see the text "Vroom!"

Using a class

Instances are created by sending the class a "new" message:

myFamilyCar _ Car new.

Messages may be sent to the new instance with the syntax object message. For example:

myFamilyCar drive

To be able to find or decide the color or driver of a car, it is necessary to write accessor methods and mutator methods. For example:

color
	^ color

driver
	^ driver

color: aColor
	color _ aColor

driver: aDriver
	driver _ aDriver

These can be used like this:

myFamilyCar color: 'black'.
myFamilyCar driver: 'Dad'.
myFamilyCar color.

A copying protocol can be written as follows:

copy
	| myCopy |
	myCopy _ Car new.
	myCopy color: self color.
	myCopy driver: self driver.
	^ myCopy

Self is a special variable in Smalltalk which references the object. (This allows the method for copy to send color and driver to the existing car; in this particular case it could be omitted because of the color and driver instance variables.) Now to copy a car, you can just say:

anotherFamilyCar _ myFamilyCar copy

Morphic classes

Morphic classes define Morphs. To create a Morph, make a subclass of Morph, rather than the root class Object. Here is the class definition (create a category called "My-Morphs"):

Morph subclass: #MyMorph
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'My-Morphs'

This morph can already be drawn, with the following code (in a workspace):

MyMorph new openInWorld

A blank blue rectangle will appear. A more interesting Morph can be created by implementing the drawOn: method:

drawOn: aCanvas
	"Draw a randomly colored oval."
	| aColor |
	aColor _ Color random.
	aCanvas fillOval: self bounds color: aColor

Morphs can react to events, such as clicks. Two methods are required: one to listen for clicks and one to act on the event:

handlesMouseDown: evt
	^ true "Listen."

mouseDown: evt
	self position: self position + (0@10)

Morphs can also be animated. Here, three methods are required:

startAnimation
	"Initialization."
	self startStepping

stepTime
	"Answer the period in milliseconds."
	^ 75

step
	"Move slightly left and downwards."
	self position: self position + (1@1)

Of course, to use a morph effectively, it must be assigned to a variable, or it will not be editable. For example:

aMorph _ MyMorph new openInWorld

Errors

When an error occurs in a script, if you are not in fill screen mode, or have turned error catching off, Squeak displays popups instead of the block turning red.

A block without an existing method running out of fill screen mode.

In the System Browser, syntax errors can not be accepted.

A syntax error in Squeak.

See Also

External Links

Notes

  1. In Panther, an argument is added to a block title by writing the name of the argument type between dollar signs. This allows any number of argument types to be created, whereas in Scratch only 26×2 = 52 types of arguments can be made.
  2. All C blocks are also special forms, though they do not use s.