
Call and Run¶
In the for block example above, the input named action has been declared as type “Command (C-shaped)”; that’s why the finished block is C-shaped. But how
does the block actually tell Snap! to carry out the commands inside
the C-slot? Here is a simple version of the block script:

This is simplified because it assumes, without checking, that the ending value is greater than the starting value; if not, the block should (depending on the designer’s purposes) either not run at all, or change the variable by −1 for each repetition instead of by 1.
The important part of this script is the run block near
the end. This is a Snap! built-in command block that takes a
Command-type value (a script) as its input, and carries out its
instructions. (In this example, the value of the input
is the script
that the user puts in the C-slot of the my for block.) There is a
similar call reporter block for invoking a Reporter or Predicate block.
The call and run blocks are at the heart of
Snap!’s first class procedure feature;
they allow scripts and blocks to be used as data—in this example, as an
input to a block—and eventually carried out under control of the user’s
program.
Here’s another example, this time using a Reporter-type input in a map
block (see The map block):

Here we are calling the Reporter multiply by (10) three times, once with
each item of the given list as its input, and collecting the results as
a list. (The reported list will always be the same length as the input
list.) Note that the multiplication block has two inputs, but here we
have specified a particular value for one of them (10), so the call
block knows to use the input value given to it just to fill the other
(empty) input slot in the multiplication block. In the my map
definition, the input function is declared to be type Reporter, and data
is of type List.
Call/Run with inputs¶
The call block (like the run block) has a right arrowhead at the end;
clicking on it adds the phrase “with inputs” and then a slot into which
an input can be inserted:

If the left arrowhead is used to remove the last input slot, the “with inputs” disappears also. The right arrowhead can be
clicked as many times as needed for the number of inputs required by the
reporter block being called.
If the number of inputs given
to call (not counting the Reporter-type input that comes first) is the
same as the number of empty input slots, then the empty slots are filled from left to right with the
given input values. If call is given exactly one input, then every
empty input slot of the called block is filled with the same value:

If the number of inputs provided is neither one nor the number of empty slots, then there is no automatic filling of empty slots. (Instead you must use explicit parameters in the ring, as discussed in Section C below.)
An even more important thing to notice about these examples is the
ring around the Reporter-type input slots in call
and map above. This notation indicates that the block itself, not the
number or other value that the block would report when called, is the
input. If you want to use a block itself in a non-Reporter-type (e.g.,
Any-type) input slot, you can enclose it explicitly in a ring, found at
the top of the Operators palette.

As a shortcut, if you right-click or control-click on a block (such as
the ( ) + ( ) block in this example), one of the choices in the menu that
appears is “ringify” and/or “unringify”. The ring indicating a Reporter-type or
Predicate-type input slot is essentially the same idea for reporters as
the C-shaped input slot with which you’re already familiar; with a
C-shaped slot, it’s the script you put in the slot that becomes the
input to the C-shaped block.
There are three ring shapes. All are oval on the outside, indicating
that the ring reports a value, the block or script inside it, but the
inside shapes are command, reporter, or predicate, indicating what kind
of block or script is expected. Sometimes you want to put something more
complicated than a single reporter inside a reporter ring; if so, you
can use a script, but the script must report a value, as in a custom
reporter definition.
Variables in Ring Slots¶
Note that the run block in the definition of the my for block (see Call and Run) doesn’t have a
ring around its input variable action. When you drag a variable into a
ringed input slot, you generally do want to use the value of the
variable, which will be the block or script you’re trying to run or
call, rather than the orange variable reporter itself. So Snap!
automatically removes the ring in this case. If you ever do want to use
the variable block itself, rather than the value of the variable, as a
Procedure-type input, you can drag the variable into the input slot,
then control-click or right-click it and choose “ringify” from the menu
that appears. (Similarly, if you ever want to call a function that will
report a block to use as the input, such as item (1) of ( ) applied to a list
of blocks, you can choose “unringify” from the menu. Almost all the
time, though, Snap! does what you mean without help.)
Writing Higher Order Procedures¶
A higher order procedure is one that
takes another procedure as an input, or that reports a procedure. In
this document, the word “procedure” encompasses
scripts, individual blocks, and nested reporters. (Unless specified
otherwise, “reporter” includes predicates. When the word is capitalized
inside a sentence, it means specifically oval-shaped blocks. So, “nested
reporters” includes predicates, but “a Reporter-type input” doesn’t.)
Although an Any-type input slot (what you get if you use the small input-name dialog box) will accept a procedure input, it doesn’t automatically ring the input as described above. So the declaration of Procedure-type inputs makes the use of your custom higher order block much more convenient.
Why would you want a block to take a procedure as input? This is actually not an obscure thing to do; the primitive conditional and looping blocks (the C-shaped ones in the Control palette) take a script as input. Users just don’t usually think about it in those terms! We could write the repeat block as a custom block this way, if Snap! didn’t already have one:

The lambda (“λ”) next to action in the prototype indicates that this is a
C-shaped block, and that the script enclosed by
the C when the block is used is the input named action in the body of
the script. The only way to make sense of the variable action is to
understand that its value is a script.
To declare an input to be Procedure-type, open the input name dialog as usual, and click on the arrowhead:

Then, in the long dialog, choose the appropriate Procedure type. The
third row of input types has a ring in the shape of each block type
(jigsaw for Commands, oval for Reporters, and hexagonal for Predicates).
In practice, though, in the case of Commands it’s more common to choose
the C-shaped slot on the fourth row, because this “container” for
command scripts is familiar to Scratch users. Technically the C-shaped
slot is an unevaluated procedure type, something discussed in Section
E below. The two Command-related input types (inline and C-shaped) are
connected by the fact that if a variable, an item ( ) of ( ) block,
or a custom Reporter block is dropped onto a C-shaped slot of a custom
block, it turns into an inline slot, as in the repeater block’s
recursive call above. (Other built-in Reporters can’t report scripts, so
they aren’t accepted in a C-shaped slot.)

Why would you ever choose an inline Command slot rather than a C shape?
Other than the run block discussed below, the only
case I can think of is something like the C /C++/Java for loop, which
actually has three command script inputs (and one predicate input),
only one of which is the “featured” loop body:

Okay, now that we have procedures as inputs to our blocks, how do we use
them? We use the blocks run (for commands) and call
(for reporters). The run block’s script input is an
inline ring, not C-shaped, because we anticipate that it will be rare to
use a specific, literal script as the input. Instead, the input will
generally be a variable whose value is a script.
The run and call blocks have arrowheads at the end that can be used to
open slots for inputs to the called procedures. How does Snap! know
where to use those inputs? If the called procedure (block or script) has
empty input slots, Snap! “does the right thing.” This has several
possible meanings:
If the number of empty slots is exactly equal to the number of inputs provided, then Snap! fills the empty slots from left to right:

If exactly one input is provided, Snap! will fill any number of empty slots with it:

Otherwise, Snap! won’t fill any slots, because the user’s intention is unclear.
If the user wants to override these rules, the solution is to use a ring
with explicit input names that can be put into the
given block or script to indicate how inputs are to be used. This will
be discussed more fully below.
Recursive Calls to Multiple-Input Blocks¶
A relatively rare situation not yet considered here is the case of a recursive block that has a variable number of inputs. Let’s say the user of your project calls your block with five inputs one time, and 87 inputs another time. How do you write the recursive call to your block when you don’t know how many inputs to give it? The answer is that you collect the inputs in a list (recall that, when you declare an input name to represent a variable number of inputs, your block sees those inputs as a list of values in the first place), and then, in the recursive call, you drop that input list onto the arrowheads that indicate a variable-input slot, rather than onto the input slot:

Note that the halo you see while dragging onto the
arrowheads is red instead of white,
and covers the input slot as well as the arrowheads. And when you drop
the expression onto the arrowheads, the words “input list:” are added to the block text and the arrowheads disappear (in
this invocation only) to remind you that the list represents all of the
multiple inputs, not just a single input. The items in the list are
taken individually as inputs to the script. Since numbers is a list of
numbers, each individual item is a number, just what sizes wants. This
block will take any number of numbers as inputs, and will make the
sprite grow and shrink accordingly:

The user of this block calls it with any number of individual numbers as
inputs. But inside the definition of the block, all of those numbers
form a list that has a single input name, numbers. This recursive
definition first checks to make sure there are any inputs at all. If so,
it processes the first input (item (1) of ( )the list), then it wants to make
a recursive call with all but the first number (all but first of ( )). But sizes doesn’t take a
list as input; it takes numbers as inputs! So this would be wrong:

Formal Parameters¶
The rings around Procedure-type inputs have an
arrowhead at the right. Clicking the arrowhead allows you to give the
inputs to a block or script explicit names, instead
of using empty input slots as we’ve done until now.

The names #1, #2, etc. are provided by default, but you
can change a name by clicking on its orange oval in the “input names”
list. Be careful not to drag the oval when clicking; that’s how you
use the input inside the ring. The names of the input variables are
called the formal parameters of the
encapsulated procedure.
Here’s a simple but contrived
example using explicit names to control which input goes where inside
the ring:

Here we just want to put one of the inputs into two different slots. If we left all three slots empty, Snap! would not fill any of them, because the number of inputs provided (2) would not match the number of empty slots (3).
Here is a more realistic, much more advanced example:


This is the definition of a block that takes any number of lists, and
reports the list of all possible combinations of one item from each
list. The important part for this discussion is that near the bottom
there are two nested calls to map, the higher
order function that applies an input
function to each item of an input list. In the inner block, the function
being mapped is ( ) in front of ( ), and that block takes two inputs. The
second, the empty List-type slot, will get its value in each call from
an item of the inner map’s list input. But there is no way for the outer
map to communicate values to empty slots of the ( ) in front of ( ) block. We
must give an explicit name, newitem, to the value that the outer map is
giving to the inner one, then drag that variable into the ( ) in front of ( )
block.
By the way, once the called block provides names for its inputs, Snap! will not automatically fill empty slots, on the theory that the user has taken control. In fact, that’s another reason you might want to name the inputs explicitly: to stop Snap! from filling a slot that should really remain empty.
Procedures as Data¶
Here’s
an example of a situation in which a procedure must be explicitly marked
as data by pulling a ring from the Operators palette and putting the
procedure (block or script) inside it:

Here, we are making a list of procedures.
But the list block accepts inputs of any type, so its input slots are
not ringed. We must say explicitly that we want the block itself as
the input, rather than whatever value would result from evaluating the
block.
Besides the list block in the
example above, other blocks into which you may want to put procedures
are set ( ) to ( ) (to set the value of a variable to a procedure), say ( )and think ( )
(to display a procedure to the user), and report ( )(for a reporter that
reports a procedure):

Special Forms¶
The primitive if else
block has two C-shaped command slots and chooses
one or the other depending on a Boolean test. Because Scratch doesn’t
emphasize functional programming, it lacks a corresponding reporter
block to choose between two expressions. Snap! has one, but we could
write our own:



Our block works for these simple examples, but if we try to use it in writing a recursive operator, it’ll fail:

The problem is that when any block is called, all of its inputs are
computed (evaluated) before the block itself runs. The block itself
knows only the values of its inputs, not what expressions were used to
compute them. In particular, all of the inputs to my if then else block
are evaluated first thing. That means that even in the base case,
factorial will try to call itself recursively, causing
an infinite loop. We need my if then else block to be able to select
only one of the two alternatives to be evaluated.
We have a mechanism to allow that: declare the then variable yes and else variable no inputs to
be of type Reporter rather than type Any. Then, when calling the block,
those inputs will be enclosed in a ring so that the expressions
themselves, rather than their values, become the inputs:



In this version, the program works, with no infinite loop. But we’ve
paid a heavy price: this reporter-if is no longer as intuitively obvious
as the Scratch command-if. You have to know about procedures as data,
about rings, and about a trick to get a constant value in a ringed slot.
(The id ( ) block implements
the identity function, which reports its
input.[6] We need it because rings take only reporters as input, not
numbers.) What we’d like is a reporter-if that behaves like this one,
delaying the evaluation of its inputs, but looks like our first
version, which was easy to use except that it didn’t work.
Such blocks are indeed possible. A block that seems to take a simple
expression as input, but delays the evaluation of that input by wrapping
an “invisible ring” around it (and, if necessary, an id ( )-like
transformation of constant data into constant functions) is called a
special form. To turn our if block into a
special form, we edit the block’s prototype, declaring the inputs yes
and no to be of type “Any (unevaluated)”
instead of type Reporter. The script for the block is still that of the
second version, including the use of call to evaluate either yes or no
but not both. But the slots appear as white Any-type rectangles, not
Reporter-type rings, and the factorial block will look like our first
attempt.
In a special form’s prototype, the unevaluated
input slot(s) are indicated by a lambda (“λ”) next to the input name, just
as if they were declared as Procedure type. They
are Procedure type, really; they’re just disguised to the user of the
block.
Special forms trade off implementor sophistication
for user sophistication. That is, you have to
understand all about procedures as data to make sense of the special
form implementation of my if then else. But any experienced Scratch
programmer can use my if then else without thinking at all about how
it works internally.
Special Forms in Scratch¶
Special forms are actually not a new invention in Snap!. Many of
Scratch’s conditional and looping blocks are really special forms. The
hexagonal input slot in the if block is a straightforward Boolean value,
because the value can be computed once, before the if block makes its
decision about whether or not to run its action input. But the forever if, repeat until ( ), and wait until ( ) blocks’ inputs can’t be Booleans; they
have to be of type “Boolean (unevaluated),” so that Scratch can evaluate them over and over again. Since
Scratch doesn’t have custom C‑shaped blocks, it can afford to handwave
away the distinction between evaluated and unevaluated Booleans, but
Snap! can’t. The pedagogic value of special forms is proven by the
fact that no Scratcher ever notices that there’s anything strange about
the way in which the hexagonal inputs in the Control blocks are
evaluated.
Also, the C-shaped slot familiar to Scratch users
is an unevaluated procedure type; you don’t have to use a ring to keep
the commands in the C-slot from being run before the C-shaped block is
run. Those commands themselves, not the result of running them, are the
input to the C-shaped Control block. (This is taken for granted by
Scratch users, especially because Scratchers don’t think of the contents
of a C-slot as an input at all.) This is why it makes sense that
“C‑shaped” is on the fourth row of types in the long form input dialog,
with other unevaluated types.
There is a primitive
idfunction in the menu of thesqrt ofblock, but we think seeing its (very simple) implementation will make this example easier to understand.