(Redirected from Build Your Own Blocks (BYOB) (Scratch Modification))

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.


Snap! (Build Your Own Blocks)
Snap-logo.png
Version 4.2
Operating Systems Any HTML5-compliant Web Browser (including iOS)
Purpose for creation Building your own blocks; everything first class
Developer(s) Jens Mönig, Brian Harvey
Open source? Yes (AGPLv3)
Programming language JavaScript
Released? Yes
Compatible with Scratch 1.3, 1.4, and 2.0
Official Website https://snap.berkeley.edu/
Archived Forum Topic ar-topic:34284
2.0 Forum Topic http://scratch.mit.edu/discuss/topic/4455

Snap! (Build Your Own Blocks) is an extended reimplementation of Scratch featuring first class procedures, first class lists, and first class sprites with inheritance. An earlier version, BYOB, was a modification of the Scratch 1.4 source code, but the current version is an entirely separate program, even though its user interface looks like Scratch 1.4 and it includes almost all of the Scratch 1.4 primitive blocks. BYOB was originally developed by Scratcher Jens; as of BYOB 3.0, Scratcher bharvey joined as co-developer. (The code is still almost all written by Jens; bharvey has contributed to the design, libraries, and documentation, as well as online mentoring of Snap! users.)

Note Note: Scratch has been phenomenally successful at introducing young people to computer programming; part of that success has been the detailed, thoughtful design of each small piece of the language. In particular, they decided to leave out some features, to avoid confusing young users. The tl;dr explanation of Snap! is that it added those missing features. When the article says "In Scratch it is not possible to..." please bear in mind that Snap! was designed to teach computer science courses to teenagers. It's entirely possible that a decision may be good for the Scratch target audience, but not for the Snap! target audience. In every case, the Scratch Team was aware of the possibilities that they decided to omit. Nothing in this article is meant to insult them.
The Snap! interface.


Features

The main features added in Snap! are custom blocks (making user-created blocks), first class procedures, first class lists, first class sprites with object inheritance, first class costumes and sounds, and an enhanced user interface.

This article discusses only the most important features; consult the Snap! Reference Manual for a more canonical guide.

Build Your Own Blocks 1.0 Features

BYOB 1.0 was released October 21, 2008. It was based on Scratch 1.3. Here is a figure from its documentation showing how a block can be made recursive.

BYOB1.png

Custom Blocks

The ability to make custom blocks was the first goal of BYOB, as reflected in its name. A limited version of this capability, allowing only command blocks, later became part of Scratch 2.0. What is described here is the current form of this feature, which changed dramatically in BYOB3.

To begin making a block, use the button at the end of each palette, the semitransparent "+" sign at the top of the palette, or the "make a block" option when right-clicking on the scripting area background.

Make-button.pngPlus-sign.pngContext-menu.png

Block-dialog.png

In the dialog that appears, besides giving the block a name, the user can choose its palette category (color), its shape (command, reporter, or predicate), and whether it is for all sprites or just one.

Clicking OK opens a block editor window, essentially a separate scripting area just for this block definition. In the block editor the user can add inputs to the block, and optionally set the type of an input, as well as adding the script that defines the block's actions. The use of a separate editor window is very different from the Scratch 2.0 design of custom blocks, in which all custom blocks are purple, sprite-local, and visible in the sprite's scripting area. The color isn't so important, but the idea behind it is: The Scratch design treats a custom block as something very different from a primitive block. The Snap! design tries to make custom blocks just as good as primitive blocks; ideally, once a block is written, it might as well be primitive. The fact that Scratch custom blocks are sprite-local is a result of the fact that their definitions have to appear in the scripting area of some particular sprite. Keeping the block definitions visible in the scripting area emphasizes that a custom block is essentially an abbreviation for a script, and ensures that all of the user's code is visible to the user. But keeping the definitions visible partly defeats the purpose of writing procedures, namely, to hide details and program at a higher level of abstraction.

Another difference is the treatment of inputs to a custom block. Inside the Scratch block definition, an input is represented by a purple oval containing the name of the input. These inputs are variables, but Scratch treats a procedure input as something very different from a (global) variable. In Snap!, the inputs are orange ovals, like other variables, and their values can be changed with set blocks. Also, procedures can have local variables that aren't inputs, using the script variables (a) @delInput @addInput ::grey block to create them. Like inputs, these script variables exist only inside the script. Every invocation of the block creates a separate set of script variables; this is particularly important when using recursion, avoiding the need for the user to construct an explicit stack.

Build Your Own Blocks 2.0 Features

BYOB 2.0 was released August 30, 2009. It updated the underlying Scratch code to version 1.4, and added several UI improvements, including Undo.

Nested Sprites

A major feature added in BYOB 2.0 was the ability to make a collection of sprites that move together. The canonical example is a skeleton in which each bone is attached to one closer to the spine; the entire skeleton can rotate together, or a particular bone can rotate relative to the whole.

Swimmer.png

Build Your Own Blocks 3.0 Features

BYOB3 was released April 25, 2010. It introduced first class procedures and lists.

First class procedures

({} @addInput)(() @addInput)(<> @addInput)

A data type is first class in a language if it can be used in all the same ways as any other data type. For example, in Scratch, it's easy to make a list of numbers, but a list of lists is impossible; numbers are first class, but lists aren't. One of the slogans of Snap! is "Everything first class." The biggest, most important difference between BYOB2 and BYOB3 was that the latter introduced first class procedures. The grey rings above are used to allow procedures (blocks and scripts) as data. A picture is worth 1000 words here:

2plus3.png 2plus3ring.png

On the left, clicking the unringed 2+3 gives 5. On the right, putting 2+3 in a ring gives the ((2) + (3)) block itself.

Call.png Call2+3.png

The only reason to create a ringed procedure is that later it will be called.

Users can create their own control structures, e.g., abstracting a repeated call of a function for each item of a list:

Mapdef.png Mapblock.png Mapcall.png

Although making procedures first class was the most important change in BYOB3, it took Jens and bharvey three tries to get the notation right. One of the best things about Scratch is the careful design of each syntax element (e.g., C-shaped blocks) so that the underlying computer science idea (e.g., looping) is obvious to a Scratch learner just from seeing the visual presentation (e.g., the (::control loop) arrow at the bottom of a looping block).

In BYOB3, the representation for an encapsulated block, what's now the grey ring, was the clunky The-block.png for reporters, and The-script.png for commands. The current representation, the grey ring, was perfected by providing a grey ring as the input slot in blocks that expect a procedure as input, such as call and map above. As a result, users almost never have to deal explicitly with the rings. If one is needed, it's already there. Dragging a ringed block into an input slot with a ring "absorbs" the extra ring; dragging a variable into an input slot with a ring removes the ring, since the meaning is almost always that the variable's value is the wanted expression to run.

When reading the map example above, was it immediately obvious that each list item is plugged into the empty slot in the (() + (3)) block? Elementary school teachers all know that if an eight-year-old is presented with "x+3=7" and asked "what's x?" they are likely to get a blank stare, but if the same kid is shown "☐+3=7" and ask "what number goes in the square?" they are likely to answer "four." Snap! uses that knowledge in the design of the notation for functions. When a grey-ringed function with an input is called, call looks for an empty input slot inside the ring, and that's where the input value is inserted. This notation makes simple function calling obvious, in the Scratch spirit of trying to use the visual representation to make ideas obvious. The empty input slot mechanism is not good enough for the complicated cases, such as nesting a map call inside the function input to another map call. For those cases grey rings can be given explicit input names, just like a custom block: (((x::variables)+(3)) input names: (x::variables) @delInput @addInput::grey).

In the computer science literature, the equivalent of a grey ring is a lambda expression: λx . x+3. "Lambda" (λ) is the Greek letter l. In Lisp, the programming language that brought lambda expressions to the attention of a wider range of programmers, they're written this way: (lambda (x) (+ x 3)). "Lambda" is spelled out because they didn't have Unicode back then, although at the Stanford and MIT Artificial Intelligence Labs they used special keyboards that did have λ keys.

First class lists

Adding lambda to Scratch made it possible to invent any control structure; the other big problem with Scratch is that lists can't be items of other lists, so it is not possible to straightforwardly build complex data structures. In Scratch a list is, sort of, a kind of variable: It has a name and a value, just like a variable, but the value has sub-values (the items). Scratch provides a red oval for the list, like the orange one for a variable, but the value it reports isn't the actual list; it's a concatenation of all the items, separated by spaces. This works because only strings and numbers can be items in a list.

Scratch lists combine two capabilities that are logically separate. The main capability of a list is that it can add, change, delete, and report items. The second capability is associating a name with the list, and that should instead be the job of a variable. If a user wants a list with items "Yakko," "Wakko," and "Dot," and wants to call the list "Animaniacs," it should be possible to say set [Animaniacs v] to (list [Yakko] [Wakko] [Dot] @delInput @addInput::list).

The list block is the only completely new capability needed to support lists as first class data. The existing Scratch list blocks do everything else that's needed, but since names are no longer necessarily associated with lists, the dropdown list-name inputs in the Scratch list blocks are replaced with list-type input slots: Listblock.png. The white rectangle with thick orange lines inside is meant to look like a list watcher, with orange items.

Minimal footprint

When BYOB3 was released in 2010, its developers still hoped that the Scratch Team would be persuaded to add its features to Scratch itself. The design therefore minimized the number of new blocks added, creating new user interface features such as variable-arity blocks that might otherwise have been multiple blocks: (call (() @addInput) @addInput::control) versus (call (() @addInput) with inputs: [] @delInput @addInput::control) versus (call (() @addInput) input list: (list [input1] [input2] ...::list) ::control).
In the end, only seven blocks and one button were needed:

Just8.jpg

(Run and launch are the equivalent to call for scripts of command blocks; run is like broadcast and wait while launch is like broadcast, not waiting for the launched script to finish. Report is what a custom reporter or predicate uses to report a value to its caller.)

BYOB 3.0 actually had a few more blocks, just for convenience, not related to these core features. For example, the <true::operators> and <false::operators> Boolean value reporters were added, to avoid some ad hoc idioms in Scratch programs that needed Boolean constants.

Build Your Own Blocks 3.1 Features

First class sprites and prototype-style inheritance were the main changes in BYOB 3.1, officially released May 18, 2011 but with development versions available online for several months before the official release.

First Class Sprites with Inheritance

Object oriented programming is a style based around the abstraction object: a collection of data and methods (procedures, which in Snap! are just more data) that is interacted with by sending it a message (just a name, maybe in the form of a text string, and perhaps additional inputs). The object responds to the message by carrying out a method, which may or may not report a value back to the asker. Some people emphasize the data hiding aspect of OOP (because each object has local variables that other objects can access only by sending request messages to the owning object) while others emphasize the simulation aspect (in which each object abstractly represents something in the world, and the interactions of objects in the program model real interactions of real people or things). Data hiding is important for large multi-programmer industrial projects, but for Snap! users it’s the simulation aspect that’s important. The Snap! approach is therefore less restrictive than that of some other OOP languages; objects are given easy access to each others’ data and methods.

Scratch provides a very natural set of objects, namely, sprites. Object oriented programming rests on three legs:

  1. Persistent local state. An object must be able to remember its history from one action to the next, in variables whose names are private to that object. Scratch sprites have this, in the form of "for this sprite only" variables.
  2. Message passing. One object has to be able to ask another object to do something, by sending it a message. Scratch doesn't exactly have this capability, but a sprite can broadcast a message to all sprites. Snap! adds true message passing, in which the messages take the form of blocks or scripts, which are carried out using the local blocks and variables of the receiver.
  3. Inheritance. It's very common for two or more objects to share some methods (local procedures). Object oriented programming would be hopelessly complicated if the methods had to be duplicated by hand in each object. So object oriented languages provide a way for one object to inherit methods and data from another. Starting in Scratch 2.0, there is a restricted form of inheritance: It's possible to clone a sprite; the resulting sprite is a copy of the original, and is temporary; when the program stops running, the temporary clones are deleted. Temporary clones are good for things like the bricks in a Breakout game; they all have the same behavior, just different positions, and can be recreated at the start of each new game. But sometimes a project needs permanent clones; one example would be the four ghosts in a Pacman game, each of which has a slightly different behavior. Snap! provides both kinds of cloning: Clones created in a program, using the create a clone of [ v]::control block or, since sprites are first class data in Snap!, the new (a new clone of [myself v]::control) reporter, are temporary. Clones created from the user interface, e.g., by right-clicking on a sprite icon in the sprite corral and choosing the "clone" option from the context menu, are permanent; they appear in the sprite corral, are independently editable, and are saved with the project.

A clone is not a copy of its parent; it actually shares the attributes of the parent. So, for example, if a costume of the parent is deleted, it's gone in the child also. However, if something is changed in the child, then the connection of that attribute with the parent is broken, and the child has a separate one of whatever it is. If the child imports a new costume, its entire wardrobe (the list of all its costumes) is copied from the parent, then the new costume is added, and thereafter the two sprites are independent with respect to costumes.

It could be confusing if a child shares some attributes of its parent but not others. To avoid confusion, attributes represented by palette blocks are ghosted in the child's palette and in variable watchers:

Methods.png Vars.png Watchers.png Xypos.png Xywatch.png

A child breaks an attribute's inheritance from its parent by changing its value. If the child's position is inherited, move ( ) steps will break the inheritance of both x any y position. But set x to ( ) will break the inheritance of the x position, leaving the inheritance of the y position intact.

What if a child has broken the inheritance of some attribute and now wants to restore inheriting that attribute from its parent? A new block inherit [x position v]::variables allows that. The dropdown menu includes the standard sprite attributes, but variables and other attribute blocks can be dropped on the menu input slot if enclosed in a ring: inherit ((var::variables) @addInput)::variables inherit ((x position) @addInput)::variables.

Prototyping vs. Class/Instance OOP

Readers who have programmed in class/instance languages may feel that what's described here isn't OOP. But classes aren't necessary, and are actually harmful in a dynamic, interpreted language that encourages tinkering. Class/instance programmers typically design their entire class hierarchy before actually writing code. That's an appropriate discipline for a large group of programmers working on the same program, but not for one kid designing a project on the fly. What the kid wants to do is build, for example, a dog sprite, and program it with behaviors similar to those of his or her pet cocker spaniel. Then the kid decides to add a Rottweiler to the project. It should inherit most of the behaviors of the cocker spaniel, but with a few differences. This OOP structure is called prototyping or prototype-based OOP.

If classes are actually necessary, make a sprite, give it children, then hide the parent. The parent is then effectively a class.

Another way in which this OOP design is nontraditional is that it uses blocks (procedures) as messages, and any block can be used, not just the ones that the receiver has declared as public methods. As explained earlier, in the Snap! design, data hiding is less important than simulation, the use of objects as metaphors for some real system of agents.

Note: OOP does not require a special OOP language. If a language has first class procedures and lexical scope, then it's possible to build an object system in the language. See the Snap! Reference Manual for details.


Details in BYOB 3.1 Inheritance vs. Snap! 4.1

Version 3.1 predated Scratch 2.0, so it didn't include Scratch-style temporary clones; all clones, whether made in the GUI or in a program, were permanent (until explicitly deleted). Also, the developers thought that users would most likely want to inherit certain sprite attributes and not others, and tried to guess which were which. Experience later showed that users found it easier to understand if all attributes were initially inherited, especially since assigning a new value to the child's attribute breaks the inheritance, probably just what the user wants.

Snap! 4.0 Features

Snap! 4.0, released May 1, 2015, was a complete rewrite in JavaScript, to run in a browser, because teachers had complained that their schools wouldn't let them download software. Development started in 2011, about the same time that the Scratch Team started working on Scratch 2.0. They, too, wanted to run in a browser. One difference between the two projects was that Scratch chose to use Adobe Flash, whereas Snap! was built around HTML5 Canvas. Both teams knew that Flash was a moribund technology, and Canvas just beginning, but the Scratch Team felt that they couldn't afford to lose access to the user's camera and microphone, and the ability to use the MIDI musical instrument timbres. None of those were available in HTML5 in 2011. By contrast, the Snap! team, with no budget and one developer, needed 4.0 to be on a platform that would last a long time. BYOB3 was based on the Scratch 1.4 source code, but Snap! is entirely separate from Scratch 2.0 and later.

From the beginning of using BYOB in high schools, there were a few complaints about the inappropriateness of the name. Experience has shown that people outside the USA don't understand why this pun could be considered inappropriate, and even in the USA hardly anyone has seen a problem with it. But the few who did complain were very emphatic about it, saying that their schools would never allow them to use software with that name.

So, reluctantly, the team looked for a somewhat relevant name that wasn't already the name of a programming language. Nobody really loved "Snap," which doesn't suggest much personality, but at least the blocks snap together. Bharvey insisted on adding the exclamation point, for a slight suggestion of personality, and it became italicized after Scratcher nXIII designed the logo, in which it's italicized.

For the most part, Snap! 4.0 reproduces the functionality of BYOB 3.0. In addition, Snap! 4.0 introduced first class continuations, Web access, linked lists, and the ability to write custom blocks in JavaScript.

First Class Continuations

Prior to joining the Snap! project, Bharvey had spent 20 years teaching computer science using what many people consider the best introductory CS textbook, Structure and Interpretation of Computer Programs (SICP). The course uses the Scheme programming language, although it's not about Scheme, because it's the language that provides the greatest versatility in supporting different programming styles with the least amount of syntax to get in the way. Scheme has been the model for BYOB/Snap! language design since BYOB 3.0. One of the team's slogans is "Snap! is Scheme disguised as Scratch."

BYOB 3.0 was perhaps 90% of a Scheme implementation, enough to teach a SICP-based course, but missing two main advanced capabilities. One, macros, is half-implemented since BYOB 3.0, namely the ability for a custom block to have unevaluated inputs. (The other half, the ability to inject code into the caller of the block, is still to come.) The second big advanced capability is first class continuations.

The continuation of a block in a script is the part of the computation that remains to be done when that block has been run. For a command block, this generally means the blocks below it in the script (plus whatever remains of the script that called this block, and so on). For a reporter, it means the block to which this block provides an input, plus whatever comes below it.

Continuations are not a special feature of Scheme. Any part of a computation, in any language, has a continuation -- whatever is left to do after it finishes. But in most languages, the programmer isn't called upon to think of the continuation as a thing, although the implementor of the programming language does think about continuations. What's special about Scheme is that it treats continuations as first class data. Giving the programmer access to continuations allows users to write any control structure; the most common examples are nonlocal exit (catch and throw in the Snap! tools library) and a thread scheduler.

Even SICP doesn't teach first class continuations as an introductory topic, although it does teach a related idea, "continuation passing style." Adding first class continuations to Snap! was more planting a flag than meeting a practical need.

The feature is embodied in two blocks, run ({} @addInput) w/continuation::control and (call ({} @addInput) w/continuation::control).

Web access

Snap! 4.0 introduced the (http:// [snap.berkeley.edu]::sensing) block (later renamed URL to allow https connections), which reads a Web page and reports the contents of the page (typically HTML code). This turned out to be less useful than hoped, because browsers restrict "cross-site" references for security reasons. Sometimes a "CORS proxy" site can be used to get around the problem; details are beyond the scope of this article.

Linked lists

The data structure that Scratch (and therefore BYOB) calls a "list" is actually implemented as a dynamic array, i.e., a contiguous block of memory that is expanded as needed. A linked list is a different data structure made out of pairs; each pair contains one list item plus a pointer to another pair, so the entire list contains as many pairs as items, and they don't have to be contiguous in memory. As it turns out, dynamic arrays are most efficient in sequential, imperative programming, while linked lists are more efficient fot recursive, functional programming.

For example, given a list of numbers (input list::variables), the goal is to make a list in which every item is two times the corresponding item of the input.

Set-to-double.png

Double-iterative.png

Double-recursive.png

In the iterative version, the add command block extends the size of the list by one item each time it's invoked. This kind of list access is fastest with dynamic arrays.

In the recursive version, the in front of block creates a new pair, whose left half is a new item, and whose right half is (a pointer to) the result of the recursive call, namely a sublist of the result. This is fastest with linked lists.

It is a goal of Snap! that users not have to know anything about data structures, but should still have their project run as fast as possible. Therefore, Snap! automatically creates linked lists when the reporters (item, all but first of, in front of) are used, but creates dynamic arrays when the commands (add, insert, replace, delete) are used. The only time the resulting programs aren't as efficient as possible is if the user uses both styles of programming with the same list, which must then be converted from one form to the other. (It should be noted that none of this matters for small lists. It becomes important in "big data" projects that have lists of, perhaps, hundreds of thousands of items.)

JavaScript in custom blocks

Probably the most important new thing in Snap! 4.0 has turned out to be the (JavaScript function \( [] @delInput @addInput \) \{ [] \}::operators) block. In this example, never mind what it actually does; instead, notice how inputs are passed from the Snap! environment to the JavaScript world.

Speak-block.png

This example comes from a text-to-speech library. Many libraries have been written by advanced users; writing libraries is a way users who think they've learned everything Snap! has to teach can explore JavaScript programming while remaining in, and contributing to, the Snap! community.

Snap! 4.1 Features

Snap! 4.1, released Oct. 22, 2017, added first class sprites with inheritance, as in BYOB 3.1, except that the distinction between permanent and temporary clones was added, and all attributes of the parent are initially shared with the child. Also, costumes and sounds are first class.

Snap! 4.2 Features

Snap! 4.2, released June 22, 2018, most notably added automatic backup of projects stored in the cloud, so users can recover from disasters such as saving an empty project with the same name as an important one. It also has the beginning of a vector costume editor.

Many Other Features

Each release added dozens of features not discussed here, because they don't rise to the level of importance of custom blocks, first class procedures, first class lists, first class sprites, and first class continuations. Here are a representative sample:

Generic Hat Block

Generic-when.png

Custom hat blocks have been a frequent user request since the early days of custom blocks. The generic when block, introduced in 4.0, answers that need. The feature required particularly careful design, because the script is in a sense always running an implicit forever if, so it could slow down projects using it, even if the user tries to stop all scripts. To avoid this problem, generic hat blocks, unlike all other hat blocks, are disabled by the red stop button or by a stop all block. Some other script must run, either because an event triggers its hat block or because the user clicks it, to re-enable generic hat blocks.

Zebra Coloring

Zebra.png

This feature, introduced in BYOB 3.0, is representative of the careful attention to the user interface in BYOB/Snap!. When same-color blocks are nested, it's hard to see the borders between them. Zebra coloring assigns two colors to each palette category, the normal color and a lighter color. When same-color blocks are nested, the outermost one has the normal color, and an inner block takes the opposite color from the one just outside it. The text inside light color blocks is black, instead of white as usual.

Detailed Mouse Event Hat Block

Mouse-block.png

Since 4.1, users can detect all mouse events, not just clicks. (The "stopped" option was added in 4.2, to allow physical robot packages to detect clicking the stop button and stop the robot's motors. To prevent runaway scripts, a "when I am stopped" script is allowed to run for only one display cycle.)

Pause and Visual Stepping

Control-buttons.png

Since 3.0, the menu bar has included a pause button, between the green flag and the stop sign. Clicking the button pauses the thread scheduler and replaces the "pause" icon with a yellow "play" icon. Clicking again continues running the project. There is also a Pause-all.png block that can be inserted in a script to set a breakpoint while debugging.

Since 4.0, the visual stepping feature from Scratch 1.4 (in which it's misleadingly named Single Stepping) is controlled by a menu bar button (with the feet icon), and a slider that appears when the button is clicked that controls the speed. If the slider is all the way to the left, true single stepping is used: the pause button must be clicked for each step. If a custom block is edited after enabling visual stepping, then the stepping includes the blocks inside that edit window. (More than one editor can be opened.)

First class costumes and Pen Trails

Since 4.1 there is a (pen trails::pen) block that reports everything currently drawn or stamped on the stage as a costume. Since costumes are first class data, this block can be used as input to any block, e.g., add (pen trails::pen) to (my costumes::variables)::list), switch to costume (pen trails::pen)::looks, or say (pen trails::pen) for (2) secs::looks.

Intellectual Precursors

Custom Blocks

The ability to write and invoke procedures, which is the core idea of Build Your Own Blocks, has been part of almost every programming language (with hardware support in every processor design at least to the extent of an instruction to save the return address somewhere before jumping to the procedure) in the history of computing. (In the original Fortran, the first general-purpose high level programming language, procedures were not reentrant, like Scratch scripts, which break off in the middle if the event that started the script happens again.)

Mapwithexample.png

Glide BYOB.png

Among languages intended primarily for children, there were heated debates between BASIC and Logo advocates because the latter included support for recursive procedures and the former did not, limiting itself instead to something pretty similar to the Scratch Broadcast () and Wait block. There's an irony in this, since the Scratch Team is a descendant of the old MIT Logo Lab. Seymour Papert, one of Logo's inventors and the founder of the MIT Logo Lab, argued for recursion as one of the mathematical big ideas that children should learn from programming computers.

First Class Data

The phrase "first class data" was coined by computer scientist Christopher Strachey, who argued in the 1960s that any data type that exists in a language at all should be first class. This means that data of that type

  • can be the value of a variable.
  • can be an input to a procedure (Scratch: block).
  • can be reported by a procedure.
  • can be a member of an aggregate (Scratch: list).
  • can exist without having a name.

It's easy to see why one might want lists of lists; every data structure (trees, heaps, hash tables, etc.) can be constructed out of lists, but not straightforwardly with only lists of text strings. But why should procedures be first class? This was historically a counterintuitive idea, especially because a procedure can not be recursive unless it has a name by which to call itself.

The idea of first class procedures comes ultimately from the 1936 invention by mathematician Alonzo Church of lambda calculus, which is a formal study of the behavior of functions. In 1936 there were only a handful of experimental computers, and no symbolic programming languages, so the fact that lambda calculus turned out to be of practical use (it is the basis for much of the theory of programming languages today) was a great confirmation of the power of the idea.

Church demonstrated that the ability to create and call functions is universal — it is all that is needed to perform any computation that can be done at all. (He also proved that there are undecidable problems, which is the reason for the qualifying clause above.) In BYOB terms, this means a programming language with nothing but THE BLOCK and CALL could exist, and still be able to compute any function. (See this BYOB project description for an explanation of how to invent arithmetic from that starting point.) The Greek letter lambda (λ) is Church's name for a gray ring.

Compose.png

(Of course lambda does not solve the problem of input/output: capturing mouse clicks, drawing pictures on the screen, and so on. Although obviously of crucial practical importance, such input/output activities are not central to the understanding of what a program or a programming language is.)

Church's work influenced actual programming language design by way of John McCarthy's 1958 invention of the Lisp programming language for artificial intelligence research. Lisp is a direct influence on Logo, and therefore an indirect influence on Scratch. The detailed design of first class procedures in Build Your Own Blocks was strongly influenced by Scheme, a Lisp dialect invented in the late 1970s by Gerald Jay Sussman and Guy Steele, which brought Lisp closer to its roots in lambda calculus by introducing lexical scoping rules.

Prototyping

The clone block reports a new object that inherits properties of the parent object. This allows users to create an object hierarchy, as in other OOP languages such as Smalltalk. But unlike Smalltalk, Build Your Own Blocks does not distinguish between classes and instances; every object can be viewed as an instance of its parent or as the class of its children. This form of inheritance is called "prototyping" because the user builds an example of a category of sprite rather than building the category as an abstract description. The best known prototyping languages are JavaScript and Self. The particular form of prototyping used in BYOB was inspired by the work of Henry Lieberman.

History

Jens's first modification was "Chirp", a program that had improvements to Scratch. He then began to work on Build Your Own Blocks (a much bigger project), which has three versions: 1.0 (based on Scratch 1.3), 2.0 (based on Scratch 1.4), and version 3.1.1, which can be downloaded here.

In 2009, the University of California at Berkeley decided to create a new computer science course for non-majors and wanted to use Scratch as the programming language, but also wanted to teach recursion and higher order functions. This is how bharvey, one of the developers of the new course, joined the BYOB project, working with Jens to design the user interface for first class lists and first class procedures.

Snap! 4 is written in JavaScript, using the HTML5 canvas element. It uses a Morphic library by Jens called Morphic.js.

The current Snap! 4.2 version can be found here to try out.

The Build Your Own Blocks-based Beauty and Joy of Computing curriculum has been converted to Snap!.

Use in Scratch 2.0

Main article: Procedures#Custom Blocks in Scratch

The Scratch Team has incorporated a function based on Build Your Own Blocks into Scratch 2.0. Custom blocks are procedures (also known as functions or methods) in which a script can easily be modified or run without duplicating it entirely. An example of Scratch's custom block is below:

define jump
repeat (10)
change y by (6)
end
repeat (10)
change y by (-6)
end

jump

Scratch Mod Design Aesthetics

It is traditional to measure the power of a Scratch modification in part by the number of blocks it adds to the language. BYOB/Snap! has taken the opposite approach, trying to get a lot of expressive power out of a very small number of new blocks.

One reason for this is that an explicit goal of Build Your Own Blocks was to influence the design of Scratch 2.0, and it was hoped that the Scratch Team might be more amenable to changes with a "small footprint" — ones that will not intrude dramatically on the experience of the traditional Scratch programmer.

Alternative Launch

The alternative launcher in action
One other way that is used for launching Snap! in the offline editor is BirdBrain Robot Server can be used to launch Snap! And further using it's glory. It does require a download, and when opening the application a prompt is given to launch Snap.

Alpha/Beta Testers

The certificate.
Bharvey put a "Certificate of Appreciation" on the BYOB website, consisting of 16 people who helped test BYOB3.

See Also

External Links