(Redirected from Build Your Own Blocks)
This article or section needs additional citations for verification. Its information may not be accurate. Editors can help by adding references. (January 2022) |
This article has links to websites or programs outside of Scratch and Wikipedia. Remember to stay safe while using the internet, as we cannot guarantee the safety of other websites. |
Snap! (Build Your Own Blocks) | |
Current Version | 9.2.18 |
Operating Systems | Any HTML5-compliant Web Browser (including iOS and Android tablets) |
Purpose for creation | Building your own blocks; everything first class |
Developer(s) | Jens Mönig, Brian Harvey, Michael Ball, Bernat Romagosa, others |
Open source? | Yes (AGPLv3) |
Programming language | JavaScript (and HTML as Markup Language) |
Released? | Yes |
Compatible with | Scratch 1.3, 1.4, 2.0 and 3.0 |
Official Website | https://snap.berkeley.edu |
Archived Forum Topic | ar-topic:34284 |
Forum Topic | topic:4455 |
Snap!, previously known as Build Your Own Blocks or BYOB, 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 its 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: | 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, the Scratch Team decided to leave out some features, to avoid confusing young users. The short 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. 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. |
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, hyperblocks, scenes, syntactic introspection, 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 on October 21, 2008.[1] It was based on Scratch 1.3.[1] Here is a figure from its documentation showing how a block can be made recursive.
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 stack 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.
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)::grey) @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 on August 30, 2009.[citation needed] It updated the underlying Scratch code to version 1.4 and added several UI improvements, including Undo.[2]
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.
BYOB Version 3
The most important change in Version 3 was first class procedures, first class lists, and first class sprites.
Build Your Own Blocks 3.0 Features
BYOB3 was released April 25, 2010.[3] It introduced first class procedures and lists.
First class procedures
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:
On the left, clicking the 2+3 block without a ring gives 5. On the right, putting 2+3 in a ring gives the ((2) + (3))
block itself.
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:
➜ | ➜ |
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 :: operators)
for reporters, and 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 rarely 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 a grey-ringed function with 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 ring)
.
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 are written this way: (lambda (x) (+ x 3)). "Lambda" is spelled out because they did not 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 lambdas 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 logically separate capabilities. 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 "1," "2," and "3," and wants to call the list "list," it should be possible to say set [list v] to (list [1] [2] [3] @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: . 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. Bharvey created a project addressed to the Scratch Team for this campaign. 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 (( :: control) @addInput :: grey ring) @addInput::control)
versus (call (( :: control) @addInput :: grey ring) with inputs: [] @delInput @addInput::control)
versus (call (( :: control) @addInput :: grey ring) input list: (list [input1] [input2] ...::list) ::control)
.
In the end, only seven blocks and one button were needed:
(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 (::grey)::operators)::operators>
and <((::grey) 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,[4] but with development versions available online for several months before the official release.[5]
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:
- 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.
- 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.
- 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, but 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 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 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 concerning 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 variable watchers:
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 and 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 :: grey ring)::variables
inherit ((x position) @addInput :: grey ring)::variables
.
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 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! Version 4
Snap! was a complete reimplementation of BYOB. Besides the name change, the main user-visible changes in version 4 were Web access, the ability to use JavaScript in defining custom blocks, and first class continuations.
Snap! 4.0 Features
This article or section needs additional citations for verification. Its information may not be accurate. Editors can help by adding references. (January 2022) |
Snap! 4.0, released May 1, 2015,[6] was a complete rewrite in JavaScript, to run in a browser because teachers had complained that their schools wouldn't let them download software.[citation needed] Development started in 2011, about the same time that the Scratch Team started working on Scratch 2.0.[7] 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,[citation needed] 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.[citation needed] None of those were available in HTML5 and JavaScript 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. BYOB 3.0 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.[citation needed] 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.[citation needed] 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.[citation needed]
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.[citation needed]
For the most part, Snap! 4.0 reproduces the functionality of BYOB 3.0. Also, Snap! 4.0 introduced first-class continuations, Web access, linked lists, and the ability to write custom blocks in JavaScript.
First Class Continuations
Before 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! "Iteration, composition" 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 :: grey ring) w/continuation::control
and (call ({} @addInput :: grey ring) 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 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 for 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.
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 the fastest with linked lists.
It is a goal of Snap! that users not have to know anything about data structures, but still have their project run as fast as possible. Therefore, Snap! automatically creates linked lists when the reporters (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
Another 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.
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,[8] added first-class sprites with inheritance, as in BYOB 3.1, except that the distinction between permanent and temporary clones was added. Also, costumes and sounds are first class.
Snap! 4.2 Features
Snap! 4.2, released June 22, 2018,[9] 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.
Snap! Version 5
Version 5 marked the growth of Jens's interest in media computation, which requires very efficient processing of very large lists. Thus, the higher order functions, which were written in Snap! in a library in version 4, were changed to primitives, even though the user's ability to write higher order functions was one of the main features distinguishing BYOB/Snap! from Scratch.
Although costumes and sounds were already first class in version 4, they were opaque objects. Version 5 added the ability to manipulate the contents of those objects: pixels and samples.
As computer science educators became more interested in data science, Snap! added the ability to import spreadsheets and have them automatically converted to lists of lists.
Finally, and perhaps most important, the previously static web site https://snap.berkeley.edu was replaced with a Scratch-style interactive community hub.
Snap! 5.0 Features
Snap! 5.0, released June 27, 2019,[10] most notably added automatic conversion of text, spreadsheet (CSV), or JSON files that are dragged onto the Snap! window to lists, in a variable named after the filename. An option in the variable watcher allows for conversion in the other direction, from structured list to text.
Many new primitives were added for media computation, allowing manipulation of costumes and sounds, with access to individual pixels or samples, respectively.
Another very notable change was that many blocks previously included in the Tools library became primitives. This change is intimately related to the media computation features, which made it important to be able to process lists with hundreds of thousands of items quickly. The downside of this change is that it robs learners of the experience of writing blocks such as map or for in Snap! itself, with very short, simple scripts. (That is, learners can still do that, but they're less likely to see a need for it when those tools are provided automatically.)
At the same time, the former static home page at https://snap.berkeley.edu was replaced with a dynamic community site with featured projects, recent projects, per-user display of published projects, and so on, similar to the Scratch site but less featureful. A separate but linked Discourse-powered forum was added later.[when?]
Snap! 5.1 Features
Snap! 5.1, released August 8, 2019,[11] had improvements to the media computation primitives, a new paste on block that stamps a sprite onto another sprite rather than onto the stage, and the important ability to change the temporary/permanent status of a clone programmatically (in a script).
Snap! 5.2 Features
Snap! 5.2, released October 24, 2019,[12] added further improvements to media computation, most notably the constructors new costume and new sound to create anonymous media objects from their components (pixels or samples).
Snap! Version 6
The biggest change to the Snap! implementation in version 6 was a complete rewrite of Morphic, but this was invisible to users except for greater reliability and speed.
The major user-visible change was adding support for operations on vectors and matrices, in the form of lists and lists of lists, respectively. The inspiration for this change was the language APL, which was before its time both in vector and matrix support and in its heavy use of characters not in the ASCII character set of its day, such as Greek letters to represent mathematical functions. (This latter characteristic prevented APL from widespread use in the 1960s.) The main APL-inspired feature in Snap! itself is hyperblocks, which are functions of non-lists expanded to accept list inputs; the underlying scalar (non-list) operation is applied to the lists' items term by term, much like an implicit map over the lists. The length primitive was extended to compute other functions of lists, such as interchanging rows and columns. The item primitive was extended to take lists of item numbers to find items in lists of lists to any depth. The full APL feature set is available as a library.
Snap! 6.0 Features
Snap! 6.0, released July 8, 2020,[13] had two very substantial changes. First, the underlying morphic.js graphics engine was entirely rewritten to use a separate canvas to render each morph, instead of editing pixels in one big canvas. This change was a response to a Chrome misfeature that was causing Snap! windows to turn white and freeze, but it has had further advantages in reducing the memory footprint of projects and, in many cases, speeding them up.
Second, the scalar operators (functions of one or two individual numbers or strings, such as + and join, not ones that require lists as inputs) were turned into hyperblocks, meaning that they behave as always for atomic (numeric or text) inputs, but also accept lists as inputs, calling the underlying scalar function for each atom (or each matching pair of atoms, for dyadic operators):
Hyperblocks allow for extremely fast processing of media data. They don't quite do everything you'd like to do with vectors and matrices, though; for example, hyperized multiplication of two matrices just multiplies matching cells by pairs; real matrix multiplication is very different from that. The APL library implements the array primitives of the language APL, which is built around vectors and matrices as data types. See Appendix B of the Reference Manual.
Snap! 6.1 Features
Snap! 6.1, released July 30, 2020,[14] fixed several bugs, added documentation on the migration process for Snap! extensions based on the old Morphic to be able to work with the new one, and added the "fade blocks" options:
Snap! 6.2 Features
Snap! 6.2, released September 7, 2020,[15] translated Snap! into Catalan, German and Norwegian, made changing the custom block from reporter to stack change the prototype, and fixed some bugs.
Snap! 6.3 Features
Snap! 6.3, released November 11, 2020,[16] fixed the "rename costume" dialog title, and fixed some bugs.
Snap! 6.4 Features
Snap! 6.4, released December 11, 2020,[17] improved loading vector graphics in Firefox, added a SIGN function to the arithmetic reporter, and fixed some bugs.
Snap! 6.5 Features
Snap! 6.5, released December 23, 2020,[18] updated the manual, added an "unsaved changes" warning when opening or creating a new project, sped up reporters, WARP and TURBO blocks by 25%, and fixed some bugs.
Snap! 6.6 Features
Snap! 6.6, released February 25, 2021,[19] changed "length of list" to become a general list operations primitive, made 2D lists inside ITEM OF now have the right order of dimensions (rows, columns, planes, etc.), and fixed some bugs.
Snap! 6.7 Features
Snap! 6.7, released March 8, 2021,[20] added an undelete feature for sprites, updated the manual and fixed some bugs.
Snap! 6.8 Features
Snap! 6.8, released May 3, 2021,[21] added first-class colours in the new "Colors" library, sped-up talk bubble positioning by 5x and fixed some bugs.
Snap! 6.9 Features
Snap! 6.9, released June 14, 2021,[22] translated Snap! into Polish and Hindi, error messages in presentation mode were made pop-up messages onstage, and fixed some bugs.
Snap! Version 7
The major planned innovation in version 7 is scenes, allowing multiple projects to be packaged as a single project, to support applications such as levels in a game, slides in a presentation, or chapters in an animated story.
From the beginning of BYOB, some teachers have wanted the ability to hide blocks, so as to present students with a restricted language in which to solve problems.[citation needed] For a long time, Jens and bharvey resisted these requests, on the theory that learners shouldn't have tools withheld from them.[citation needed] This changed when Education Development Center ([www.edc.org]) wanted to base an early childhood (ages 5-7) math curriculum on Snap!, but wanted to provide students with an environment in which all the primitive blocks were hidden, leaving only the custom blocks they would build for each activity.[citation needed] They provided funding to support block hiding and several other needed features for their work. The Snap! developers were less upset about hiding blocks in a math curriculum than about hiding blocks in a programming curriculum.[citation needed] Some of the EDC changes found their way into Version 7: block hiding, a single multicolor palette, and others.
Syntactic introspection, described in more detail below, allows programs to examine and create scripts.
Snap! 7.0 Features
Snap! 7.0, released December 13, 2021,[23] has major changes including scenes (combining several independent projects into one that can switch between sub-projects programmatically), syntactic introspection (conversion between expressions or scripts and tree-structured lists in which input expressions are separated from the block to which they provide input values), and a collection of features to support Parsons problems (extremely limited environments in which a learner is challenged to solve a problem using only a handful of selected blocks): programmatic hiding and unhiding of blocks, an optional single palette with blocks of all categories, and user-defined block categories. Additional changes include updating the manual and readme, translating Snap! into Chinese, support for extensions, and fixing bugs.
Shortly before the release of version 7.0, there was a significant attack on the Snap! community in the form of a project that used the JavaScript function block to introduce malware into users' computers and collect users' passwords. This led to a quick release of version 6.9, in which that block is disabled by default, and users who run projects using it have to enable it explicitly each time the project is loaded.[22] This made it painful to use some of the libraries provided with Snap!, so version 7.0 moves those JavaScript functions into Snap! itself, interfaced via a primitive block available in dev mode.
Syntactic Introspection
The definition of block takes a custom block (in a ring, since it's the block itself that's the input, not the result of calling the block) as input and reports the block's definition, i.e., its inputs and body, in the form of a ring with named inputs corresponding to the block's input names, so that those input names are bound in the body.
The split by blocks block takes any expression or script as input (ringed) and reports a list representing a syntax tree for the script or expression, in which the first item is a block with no inputs and the remaining items are the input values, which may themselves be syntax trees. The inverse function is provided by the join block, which when given a syntax tree as input reports the corresponding expression or script.
Together these features are the beginning of a metaprogramming capability, in which Snap! programs can be treated as data. For example, this debugging aid can be written in Snap! itself:
Snap! Version 8
Snap! Version 8's major feature is the complete metaprogramming support. This made it possible to create blocks from within your scripts to be dragged out of the palette.
Snap! 8.0 Features
Snap! Version 8, released August 4th, 2022 [24], added in complete metaprogramming support and moved the ([definition v] of block (()@addInput)::control)
block to the Control category.
Writing a Block
{square (size #)::motion}::control hat repeat (4) move (size::variables) steps turn cw (90 v) degrees end set [foo v] to (split ([definition v] of block ({square ()::motion}@addInput)::control) by [blocks]::operators) replace item (2 v) of (foo) with [6] replace item (2 v) of (item (2 v) of (item (3 v) of (foo))) with [60] define ((block)::control) [hexagon _] (join input list: (foo)::operators)::control set [category v] of block (block) to [motion]::control set [type v] of block (block) to [command]::control set [scope v] of block (block) to [global]::control set [slots v] of block (block) to (list [number] @delInput @addInput::list)::control
The define ((block)::control) [] (()@addInput)::control
block creates a block, which can then be dragged out of the palette. The first input is the blocks label (the blocks text with inputs as underscores). The second input is the blocks definition. The (block)
upvar reports the block back to the user so that the caller knows what block it just made and can refer back to it. The (block)
variable also serves a purpose in recursion. With no way to refer to itself, you'd be forced into using the Y/Z Combinator for recursion, because that works with just lambdas. By putting the (block)
variable into the definition, it becomes a (this script::control)
block, which reports the currently running script.
The set [label v] of block (()@addInput) to []::control
block sets one of a block's properties. These are:
- label
- definition
- category (as a number)
- type (command, reporter, or predicate)
- scope
- slots (list of input slots as numbers)
- defaults
- menus
- editables (list of if inputs be edited or not)
- translations (added in 8.1.0)
Note that it's important to set the script-breaking ones in the same script that you define it, so you can't do set [type v] of block ({hexagon ()::motion}@addInput) to [reporter]::control
, because the hexagon ()::motion
in the block counts as using it.
The delete block (()@addInput)::control
block will delete a block from the palette.
Snap! 8.1 Features
Snap! Version 8.1, released February 1st, 2023 [25] added in a new When [anything v] is edited::control hat
hat block, and the pipe [] ⇒ (()@addInput)@delInput@addInput::control reporter
from the "Iteration, composition" library was added as a primitive.
Snap! 8.2 Features
Snap! Version 8.1, released March 1st, 2023 [26] made all comparison operators + AND and OR variadic. AND and OR were also made hyper, thus rendering the variadic library as redundant.
Snap! Version 9
This article or section is currently undergoing major changes and may be incomplete. Please avoid largely modifying this page's contents until this template has been removed. (October 2023) |
Snap! Version 9's major feature was an expansion of the metaprogramming support seen in version 8, allowing programs to access its caller.
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, first-class continuations, and metaprogramming. Here is a representative sample:
Generic Hat Block
when <> :: hat control
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 <>:: control
, 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 v]
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
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
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
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 ❚❚ :: control
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
.
Menus
ask (list [confirm] (list [yes] [no] @delInput @addInput::list) @delInput @addInput::list) and wait ask (list [confirm] (list [yes] [no] (list @addInput::list) (list [more] (list [maybe] @delInput @addInput::list)@delInput @addInput::list)@delInput @addInput::list) @delInput @addInput::list) and wait ask (list [normal] (list [also normal] [totally different] @delInput @addInput::list) @delInput @addInput::list) and wait ask (list (list [] [Hey, what's up?] @delInput @addInput::list) (list [Oh, not much. I'm just noodling around.] @delInput @addInput::list) @delInput @addInput::list) and wait ask (list [Pick a sprite] (list (list (list (object [Scratch Cat v]::sensing) [Scratch Cat] @delInput @addInput::list) [Scratch Cat] @delInput @addInput::list) (list (list (object [Alonzo v]::sensing) [Alonzo] @delInput @addInput::list) [Alonzo] @delInput @addInput::list) @delInput @addInput::list) @delInput @addInput::list) and wait
Since 8.0, the ask block, when fed in a list of options, will display them in a menu.
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.)
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.[citation needed] 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.[citation needed]
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.
(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' 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. Bharvey put a "Certificate of Appreciation" on the BYOB website, consisting of 16 people who helped test the alpha versions of BYOB 3.
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.
As of January 2022, Snap! 7.0.3 can be found here to try out.
The Build Your Own Blocks-based Beauty and Joy of Computing curriculum has been converted to Snap!.
Influence on Scratch
- Main article: My Blocks
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.[citation needed] 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.[citation needed]
Alternative Launch
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 its glory. It does require a download, and when opening the application a prompt is given to launch Snap!.
See Also
External Links
- Announcement of BYOB1 on Jens's blog
- Announcement of BYOB2 on Jens's blog
- Announcement of BYOB3 on Jens's blog
- Announcement of BYOB3.1 on Jens's blog
- BYOB Forum Topic
- BYOB 3 Forum Topic
- Snap! Forum Topic
- BYOB1 manual
- BYOB 3.1.1 Reference Manual
- Snap! Reference Manual
- Snap! Website
- Snap! Wiki (Unofficial)
- Snap! on Wikipedia
- Snap! Cloud Website, a mirror of the main website
- Snap! Con Website
References
- ↑ a b [1]
- ↑ ar-post:192005
- ↑ bharvey. (25/04/2010). "Okay, gang, IT'S HERE! http://byob.berkeley.edu" ar-post:375320
- ↑ bharvey. (18/05/2011). "Ta da! Here's the official BYOB 3.1 release." ar-post:766120
- ↑ bharvey. (23/02/2011). "TA DA! The official first alpha test release of BYOB 3.1!" ar-post:682163
- ↑ bharvey. (01/05/2015). "Jens and I are proud to announce, finally, the official release of Snap! 4.0." post:984022
- ↑ Jens. (05/01/2011). "This is the very beginning of what might eventually turn out to be a complete re-write of BYOB..." ar-post:641829
- ↑ bharvey. (18/10/2017). "Snap! 4.1 will be officially released this Sunday, Oct 22." post:2859588
- ↑ bharvey. (23/07/2018). "Snap! v4.2 is out!" post:3151745
- ↑ Jens. (28/07/2019). "Snap! 5 is here [title]" https://forum.snap.berkeley.edu/t/snap-5-is-here/584
- ↑ https://github.com/jmoenig/Snap/releases/tag/v5.1.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v5.2.0
- ↑ Jens. (08/07/2020). "Snap!6 is here, and it's all about scale." https://forum.snap.berkeley.edu/t/snap-6-is-here-and-its-all-about-scale/2274
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.1.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.2.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.3.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.4.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.5.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.6.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.7.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v6.8.0
- ↑ a b bharvey. (14/06/2021). "Snap! version 6.9 and the JavaScript Function block [title]" https://forum.snap.berkeley.edu/t/snap-version-6-9-and-the-javascript-function-block/6970
- ↑ https://github.com/jmoenig/Snap/releases/tag/v7.0.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v8.0.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v8.1.0
- ↑ https://github.com/jmoenig/Snap/releases/tag/v8.2.0