From 785b319b41890150a054fa5222146672a7823705 Mon Sep 17 00:00:00 2001 From: Victoria Phelps Date: Thu, 31 Oct 2024 13:28:08 -0700 Subject: [PATCH] adding default juypterbook template --- .jekyll-cache/.gitignore | 2 + ...40b622142f1c98125abcfe89a76a661b0e8e343910 | 1 + ...f6214cc7839457ba6edee2c784a891aa91428e4a6a | 2 + ...973943244da457d64114b6defedf8d6c7bed697dc8 | 2 + ...34fac99a67802807fe5c9c2da773cebdb41dd47c85 | 2 + ...1050264480fd73402dbc4c67c467980a775bd45c28 | 150 + ...3aea4d05feb983f4e6e9194bfb044c0a3f711815cc | 2 + ...08348d9cfaf8823d2dda4d5ff13fdb851bd15d29ea | 2 + ...6796b0137877514593543b91af2752d5a17e3d736c | 2 + ...9300b0e4a2f0a98d13982aeacb6ba82e8e3f1f495c | 2 + ...056d001e0aef2afcf9404866d56adec0cb8cb9198b | 8257 ++++++++++++++++ ...ce9c8f35fafea293a026f9ea08317572606fb0a87a | 2 + ...a6744cbac051a68116ea5c19e8a82cf5c22232e386 | 2 + ...f910efe40e4751e30d31dd6ae3fb9cf6a2a77ed5c1 | 2 + ...66ec0a0db0baa16c560a03af8e5d4bdd1a9c10ffc6 | 2 + ...4b63e0da2dcc74ddc80ccb4b78a117647e32c0ee80 | 8265 +++++++++++++++++ ...e3be46e6f372f83302361b1711fc071d82ab9c73b4 | 2 + ...dab5ea521999edb301acb81a170bf19dd71167a7f3 | 8255 ++++++++++++++++ ...32e884412f2503abf2a7a210e4a814ecc9d9344ab7 | 2 + ...5491f2a4c1117ab233f42fdc84c8c69ccb103160f2 | 2 + ...3e3d2c8dc88c2508c77335dda961e090f2e658cdd3 | 2 + ...b3569b141240a8eaff9cf0a8566e6406c0d3f039c1 | 2 + ...b0ddcd0b952fc1a9f086b60980f77f5e36ffb9970b | 2 + ...a414f4af2d46e15e0efdd878d54be937606e23c156 | 2 + ...c8996fb92427ae41e4649b934ca495991b7852b855 | 2 + ...563a7e74dade92ef41a6717f30db6283150833dc86 | 2 + ...d3736f2b4b72f74e80fcf8e4779773e8204230618b | 42 + ...e0dbb7402ba9a700f6f673d8a950148756a21e7666 | 3 + _config.yml | 32 + _toc.yml | 9 + intro.md | 11 + logo.png | Bin 0 -> 9854 bytes markdown-notebooks.md | 53 + markdown.md | 55 + notebooks.ipynb | 122 + references.bib | 56 + requirements.txt | 3 + 37 files changed, 25356 insertions(+) create mode 100644 .jekyll-cache/.gitignore create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/04/50566e99f04635cd51acf6214cc7839457ba6edee2c784a891aa91428e4a6a create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/09/dec65b64ed68b250fc44973943244da457d64114b6defedf8d6c7bed697dc8 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/14/ab4a37f9ceed5f4fe9d334fac99a67802807fe5c9c2da773cebdb41dd47c85 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/1c/fa070950e443c9159a571050264480fd73402dbc4c67c467980a775bd45c28 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/20/deea276e3eceab19d6f23aea4d05feb983f4e6e9194bfb044c0a3f711815cc create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/c3be1198a2fddf18d03608348d9cfaf8823d2dda4d5ff13fdb851bd15d29ea create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/3a/78695388b38b5cceefaf6796b0137877514593543b91af2752d5a17e3d736c create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/47/6b8c158dae8f4993a7c49300b0e4a2f0a98d13982aeacb6ba82e8e3f1f495c create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/4b/1482efac86daa8284e15056d001e0aef2afcf9404866d56adec0cb8cb9198b create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/71/0907dceb30385b3e063ece9c8f35fafea293a026f9ea08317572606fb0a87a create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/7e/5842207401323dd2d96ba6744cbac051a68116ea5c19e8a82cf5c22232e386 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/89/5392f18b81f851903581f910efe40e4751e30d31dd6ae3fb9cf6a2a77ed5c1 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/93/66531cad248164c6a36166ec0a0db0baa16c560a03af8e5d4bdd1a9c10ffc6 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/96/0785eded3775fe4e5a844b63e0da2dcc74ddc80ccb4b78a117647e32c0ee80 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a1/bf183cde58ba42dfd07be3be46e6f372f83302361b1711fc071d82ab9c73b4 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a6/a8f2706298ee1fecbcf1dab5ea521999edb301acb81a170bf19dd71167a7f3 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/b1/2bbda7eb533e54a3715c32e884412f2503abf2a7a210e4a814ecc9d9344ab7 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/bd/b9377cb76b60b872e12f5491f2a4c1117ab233f42fdc84c8c69ccb103160f2 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/cf/8b7a044d4c00cbcbd4af3e3d2c8dc88c2508c77335dda961e090f2e658cdd3 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/df/bc82aa2873f2939f5e88b3569b141240a8eaff9cf0a8566e6406c0d3f039c1 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e1/4cc487a2af687a341cccb0ddcd0b952fc1a9f086b60980f77f5e36ffb9970b create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e2/7b09b63e1dbdb1232c1ca414f4af2d46e15e0efdd878d54be937606e23c156 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 create mode 100644 .jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/f5594703486f7a696894563a7e74dade92ef41a6717f30db6283150833dc86 create mode 100644 .jekyll-cache/Jekyll/Cache/Module/1a/5068b93114de8206f065d3736f2b4b72f74e80fcf8e4779773e8204230618b create mode 100644 .jekyll-cache/Jekyll/Cache/Module/61/4f14a90c1f22d251bd66e0dbb7402ba9a700f6f673d8a950148756a21e7666 create mode 100644 _config.yml create mode 100644 _toc.yml create mode 100644 intro.md create mode 100644 logo.png create mode 100644 markdown-notebooks.md create mode 100644 markdown.md create mode 100644 notebooks.ipynb create mode 100644 references.bib create mode 100644 requirements.txt diff --git a/.jekyll-cache/.gitignore b/.jekyll-cache/.gitignore new file mode 100644 index 0000000..f244efa --- /dev/null +++ b/.jekyll-cache/.gitignore @@ -0,0 +1,2 @@ +# ignore everything in this directory +* diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 b/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 new file mode 100644 index 0000000..766d952 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Cache/b7/9606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910 @@ -0,0 +1 @@ +I"É{"source"=>"C:/Users/victo/snap-manual", "destination"=>"C:/Users/victo/snap-manual/_site", "collections_dir"=>"", "cache_dir"=>".jekyll-cache", "plugins_dir"=>"_plugins", "layouts_dir"=>"_layouts", "data_dir"=>"_data", "includes_dir"=>"_includes", "collections"=>{"posts"=>{"output"=>true, "permalink"=>"/:categories/:year/:month/:day/:title:output_ext"}}, "safe"=>false, "include"=>[".htaccess"], "exclude"=>[".sass-cache", ".jekyll-cache", "gemfiles", "Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"], "keep_files"=>[".git", ".svn"], "encoding"=>"utf-8", "markdown_ext"=>"markdown,mkdown,mkdn,mkd,md", "strict_front_matter"=>false, "show_drafts"=>nil, "limit_posts"=>0, "future"=>false, "unpublished"=>false, "whitelist"=>[], "plugins"=>[], "markdown"=>"kramdown", "highlighter"=>"rouge", "lsi"=>false, "excerpt_separator"=>"\n\n", "incremental"=>false, "detach"=>false, "port"=>"4000", "host"=>"127.0.0.1", "baseurl"=>nil, "show_dir_listing"=>false, "permalink"=>"date", "paginate_path"=>"/page:num", "timezone"=>nil, "quiet"=>false, "verbose"=>false, "defaults"=>[], "liquid"=>{"error_mode"=>"warn", "strict_filters"=>false, "strict_variables"=>false}, "kramdown"=>{"auto_ids"=>true, "toc_levels"=>[1, 2, 3, 4, 5, 6], "entity_output"=>"as_char", "smart_quotes"=>"lsquo,rsquo,ldquo,rdquo", "input"=>"GFM", "hard_wrap"=>false, "guess_lang"=>true, "footnote_nr"=>1, "show_warnings"=>false}, "title"=>"Snap! Reference Manual", "description"=>"reference manual", "theme"=>"just-the-docs", "layout"=>"default", "url"=>"https://jedi-force.github.io/snap-manual/", "aux_links"=>{"Template Repository"=>"https://github.com/just-the-docs/just-the-docs-template"}, "serving"=>false}:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/04/50566e99f04635cd51acf6214cc7839457ba6edee2c784a891aa91428e4a6a b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/04/50566e99f04635cd51acf6214cc7839457ba6edee2c784a891aa91428e4a6a new file mode 100644 index 0000000..aa14eea --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/04/50566e99f04635cd51acf6214cc7839457ba6edee2c784a891aa91428e4a6a @@ -0,0 +1,2 @@ +I"2

Saving and Loading Projects and Media

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/09/dec65b64ed68b250fc44973943244da457d64114b6defedf8d6c7bed697dc8 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/09/dec65b64ed68b250fc44973943244da457d64114b6defedf8d6c7bed697dc8 new file mode 100644 index 0000000..82405cd --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/09/dec65b64ed68b250fc44973943244da457d64114b6defedf8d6c7bed697dc8 @@ -0,0 +1,2 @@ +I"

Typed Inputs

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/14/ab4a37f9ceed5f4fe9d334fac99a67802807fe5c9c2da773cebdb41dd47c85 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/14/ab4a37f9ceed5f4fe9d334fac99a67802807fe5c9c2da773cebdb41dd47c85 new file mode 100644 index 0000000..a17c985 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/14/ab4a37f9ceed5f4fe9d334fac99a67802807fe5c9c2da773cebdb41dd47c85 @@ -0,0 +1,2 @@ +I"

Procedures as Data

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/1c/fa070950e443c9159a571050264480fd73402dbc4c67c467980a775bd45c28 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/1c/fa070950e443c9159a571050264480fd73402dbc4c67c467980a775bd45c28 new file mode 100644 index 0000000..633c8a9 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/1c/fa070950e443c9159a571050264480fd73402dbc4c67c467980a775bd45c28 @@ -0,0 +1,150 @@ +I"J!

I. Blocks, Scripts, and Sprites

+

Hat Blocks and Command Blocks

+

A. Sprites and Parallelism

+

Costumes and Sounds

+

Inter-Sprite Communication with Broadcast

+

B. Nesting Sprites: Anchors and Parts

+

C. Reporter Blocks and Expressions

+

D. Predicates and Conditional Evaluation

+

E. Variables

+

Global Variables

+

Script Variables

+

Renaming variables

+

Transient variables

+

F. Debugging

+

The pause button

+

Breakpoints: the pause all block

+

Visible stepping

+

G. Etcetera

+

H. Libraries

+ +

Saving and Loading Projects and Media

+

A. Local Storage

+

B. Creating a Cloud Account

+

C. Saving to the Cloud

+

D. Loading Saved Projects

+

E. If you lose your project, do this first!

+

Private and Public Projects

+ +

Building a Block

+

A. Simple Blocks

+

Custom Blocks with Inputs

+

Editing Block Properties

+

B. Recursion

+

C. Block Libraries

+

D. Custom blocks and Visible Stepping

+ +

First Class Lists

+

A. The List Block

+

B. Lists of Lists

+

C. Functional and Imperative List Programming

+

D. Higher Order List Operations and Rings

+

E. Table View vs List View

+

Comma-Separated Values

+

Multi-dimensional Lists and JSON

+

F. Hyperblocks

+ +

Typed Inputs

+

A. Scratchā€™s Type Notation

+

B. The Snap! Input Type Dialog

+

Procedure Types

+

Pulldown Inputs

+

Input Variants

+

Prototype Hints

+

Title Text and Symbols

+ +

Procedures as Data

+

A. Call and Run

+

Call/Run with Inputs

+

Variables in Ring Slots

+

B. Writing Higher Order Procedures

+

Recursive Calls to Multiple-Input Blocks

+

C. Formal Parameters

+

D. Procedures as Data

+

E. Special Forms

+

Special Forms in Scratch

+ +

Object Oriented Programming with Sprites

+

A. First Class Sprites

+

B. Permanent and Temporary Clones

+

C. Sending Messages to Sprites

+

Polymorphism

+

D. Local State in Sprites: Variables and Attributes

+

E. Prototyping: Parents and Children

+

F. Inheritance by Delegation

+

G. List of Attributes

+

H. First Class Costumes and Sounds

+

Media Computation with Costumes

+

Media Computation with Sounds

+ +

OOP with Procedures

+

A. Local State with Script Variables

+

B. Messages and Dispatch Procedures

+

C. Inheritance via Delegation

+

D. An Implementation of Prototyping OOP

+ +

The Outside World

+

A. The World Wide Web

+

B. Hardware Devices

+

C. Date and Time

+ +

Continuations

+

A. Continuation Passing Style

+

B. Call/Run with Continuation

+

Nonlocal Exit

+ +

Metaprogramming

+

A. Reading a Block

+

B. Writing a Block

+

C. Macros

+ +

User Interface Elements

+

A. Tool Bar Features

+

The Snap! Logo Menu

+

The File Menu

+

The Cloud Menu

+

The Settings Menu

+

Visible Stepping Controls

+

Stage Resizing Buttons

+

Project Control Buttons

+

B. The Palette Area

+

Buttons in the Palette

+

Context Menus for Palette Blocks

+

Context Menu for the Palette Background

+

C. The Scripting Area

+

Sprite Appearance and Behavior Controls

+

Scripting Area Tabs

+

Scripts and Blocks Within Scripts

+

Controls in the Costumes Tab

+

The Paint Editor

+

Controls in the Sounds Tab

+

D. Keyboard Editing

+

Starting and Stopping the Keyboard Editor

+ +

Editing a Script

+

Running the Selected Script

+

E. Controls on the Stage

+

Sprites

+

Variable Watchers

+

The Stage Itself

+

F. The Sprite Corral and Sprite Creation Buttons

+

G. Preloading a Project when Starting Snap!

+

H. Mirror Sites

+ +

Appendix A. Snap! Color Library

+

Introduction to Color

+

Crayons and Color Numbers

+

Perceptual Spaces: HSV and HSL

+

Mixing Colors

+

tl;dr

+

Subappendix: Geeky Details on Fair Hue

+

Subappendix: Geeky Details on Color Numbers

+ +

Appendix B. APL Features

+

Boolean Values

+

Scalar Functions

+

Mixed Functions

+

Higher Order Functions

+ +

Index

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/20/deea276e3eceab19d6f23aea4d05feb983f4e6e9194bfb044c0a3f711815cc b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/20/deea276e3eceab19d6f23aea4d05feb983f4e6e9194bfb044c0a3f711815cc new file mode 100644 index 0000000..c252c98 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/20/deea276e3eceab19d6f23aea4d05feb983f4e6e9194bfb044c0a3f711815cc @@ -0,0 +1,2 @@ +I"

Reference Manual

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/c3be1198a2fddf18d03608348d9cfaf8823d2dda4d5ff13fdb851bd15d29ea b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/c3be1198a2fddf18d03608348d9cfaf8823d2dda4d5ff13fdb851bd15d29ea new file mode 100644 index 0000000..2f2b89f --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/39/c3be1198a2fddf18d03608348d9cfaf8823d2dda4d5ff13fdb851bd15d29ea @@ -0,0 +1,2 @@ +I"

Index

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/3a/78695388b38b5cceefaf6796b0137877514593543b91af2752d5a17e3d736c b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/3a/78695388b38b5cceefaf6796b0137877514593543b91af2752d5a17e3d736c new file mode 100644 index 0000000..1bbecf8 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/3a/78695388b38b5cceefaf6796b0137877514593543b91af2752d5a17e3d736c @@ -0,0 +1,2 @@ +I"

Home

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/47/6b8c158dae8f4993a7c49300b0e4a2f0a98d13982aeacb6ba82e8e3f1f495c b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/47/6b8c158dae8f4993a7c49300b0e4a2f0a98d13982aeacb6ba82e8e3f1f495c new file mode 100644 index 0000000..b5db703 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/47/6b8c158dae8f4993a7c49300b0e4a2f0a98d13982aeacb6ba82e8e3f1f495c @@ -0,0 +1,2 @@ +I"

Continuations

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/4b/1482efac86daa8284e15056d001e0aef2afcf9404866d56adec0cb8cb9198b b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/4b/1482efac86daa8284e15056d001e0aef2afcf9404866d56adec0cb8cb9198b new file mode 100644 index 0000000..47e1662 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/4b/1482efac86daa8284e15056d001e0aef2afcf9404866d56adec0cb8cb9198b @@ -0,0 +1,8257 @@ +I"©ļ

{width=ā€1.0inā€ +height=ā€0.5492596237970254inā€}

+ +

Build Your Own Blocks

+ +

{#section .TOCHeading}

+ +

{width=ā€5.477777777777778inā€ height=ā€4.501388888888889inā€} Table of Contents {#table-of-contents .TOCHeading}

+ +

I. Blocks, Scripts, and Sprites 5

+ +

Hat Blocks and Command Blocks 6

+ +

A. Sprites and Parallelism 8

+ +

Costumes and Sounds 8

+ +

Inter-Sprite Communication with Broadcast 9

+ +

B. Nesting Sprites: Anchors and Parts 10

+ +

C. Reporter Blocks and Expressions 10

+ +

D. Predicates and Conditional Evaluation 12

+ +

E. Variables 13

+ +

Global Variables 14

+ +

Script Variables 15

+ +

Renaming variables 15

+ +

Transient variables 16

+ +

F. Debugging 17

+ +

The pause button 17

+ +

Breakpoints: the pause all block 17

+ +

Visible stepping 18

+ +

G. Etcetera 18

+ +

H. Libraries 25

+ +

II. Saving and Loading Projects and Media 37

+ +

A. Local Storage 37

+ +

B. Creating a Cloud Account 37

+ +

C. Saving to the Cloud 38

+ +

D. Loading Saved Projects 38

+ +

E. If you lose your project, do this first! 39

+ +

F. Private and Public Projects 39

+ +

III. Building a Block 40

+ +

A. Simple Blocks 40

+ +

Custom Blocks with Inputs 42

+ +

Editing Block Properties 43

+ +

B. Recursion 43

+ +

C. Block Libraries 44

+ +

D. Custom blocks and Visible Stepping 45

+ +

IV. First class lists 46

+ +

A. The list Block 46

+ +

B. Lists of Lists 47

+ +

C. Functional and Imperative List Programming 48

+ +

D. Higher Order List Operations and Rings 49

+ +

E. Table View vs. List View 51

+ +

Comma-Separated Values 54

+ +

Multi-dimensional lists and JSON 54

+ +

F. Hyperblocks 55

+ +

V. Typed Inputs 59

+ +

A. Scratchā€™s Type Notation 59

+ +

B. The Snap! Input Type Dialog 59

+ +

Procedure Types 60

+ +

Pulldown inputs 61

+ +

Input variants 63

+ +

Prototype Hints 64

+ +

Title Text and Symbols 64

+ +

VI. Procedures as Data 65

+ +

A. Call and Run 65

+ +

Call/Run with inputs 65

+ +

Variables in Ring Slots 66

+ +

B. Writing Higher Order Procedures 66

+ +

Recursive Calls to Multiple-Input Blocks 68

+ +

C. Formal Parameters 69

+ +

D. Procedures as Data 70

+ +

E. Special Forms 71

+ +

Special Forms in Scratch 72

+ +

VII. Object Oriented Programming with Sprites 73

+ +

A. First Class Sprites 73

+ +

B. Permanent and Temporary Clones 74

+ +

C. Sending Messages to Sprites 74

+ +

Polymorphism 75

+ +

D. Local State in Sprites: Variables and Attributes 76

+ +

E. Prototyping: Parents and Children 76

+ +

F. Inheritance by Delegation 77

+ +

G. List of attributes 78

+ +

H. First Class Costumes and Sounds 79

+ +

Media Computation with Costumes 79

+ +

Media Computation with Sounds 82

+ +

VIII. OOP with Procedures 85

+ +

A. Local State with Script Variables 85

+ +

B. Messages and Dispatch Procedures 86

+ +

C. Inheritance via Delegation 87

+ +

D. An Implementation of Prototyping OOP 88

+ +

IX. The Outside World 91

+ +

A. The World Wide Web 91

+ +

B. Hardware Devices 92

+ +

C. Date and Time 92

+ +

X. Continuations 93

+ +

A. Continuation Passing Style 94

+ +

B. Call/Run w/Continuation 97

+ +

Nonlocal exit 99

+ +

XI. Metaprogramming 101

+ +

A. Reading a block 101

+ +

B. Writing a block 102

+ +

C. Macros 105

+ +

XII. User Interface Elements 107

+ +

A. Tool Bar Features 107

+ +

The Snap! Logo Menu 107

+ +

The File Menu 108

+ +

The Cloud Menu 113

+ +

The Settings Menu 114

+ +

Visible Stepping Controls 117

+ +

Stage Resizing Buttons 118

+ +

Project Control Buttons 118

+ +

B. The Palette Area 119

+ +

Buttons in the Palette 119

+ +

Context Menus for Palette Blocks 119

+ +

Context Menu for the Palette Background 120

+ +

C. The Scripting Area 122

+ +

Sprite Appearance and Behavior Controls 122

+ +

Scripting Area Tabs 122

+ +

Scripts and Blocks Within Scripts 122

+ +

Controls in the Costumes Tab 126

+ +

The Paint Editor 128

+ +

Controls in the Sounds Tab 130

+ +

D. Keyboard Editing 130

+ +

Starting and stopping the keyboard editor 130

+ +

Navigating in the keyboard editor 130

+ +

Editing a script 131

+ +

Running the selected script 132

+ +

E. Controls on the Stage 132

+ +

Sprites 132

+ +

Variable watchers 134

+ +

The stage itself 135

+ +

F. The Sprite Corral and Sprite Creation Buttons 135

+ +

G. Preloading a Project when Starting Snap! 136

+ +

H. Mirror Sites 137

+ +

Appendix A. Snap! color library 138

+ +

Introduction to Color 138

+ +

Crayons and Color Numbers 139

+ +

Perceptual Spaces: HSV and HSL 142

+ +

Mixing Colors 144

+ +

tl;dr 145

+ +

Subappendix: Geeky details on fair hue 145

+ +

Subappendix: Geeky details on color numbers 146

+ +

Appendix B. APL features 148

+ +

Boolean values 150

+ +

Scalar functions 150

+ +

Mixed functions 151

+ +

Higher order functions 157

+ +

Index ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦. 159

+ +

Copyright Ā© 2020 Jens Mƶnig and Brian Harvey.

+ +

Macintosh
+HD:Users:bh:Desktop:cc.png{width=ā€0.6111111111111112inā€ +height=ā€0.2152777777777778inā€} This work is licensed under a Creative +Commons Attribution-NonCommercial-ShareAlike 4.0 International +License.

+ +

Acknowledgements {#acknowledgements .TOCHeading}

+ +

[W]{.smallcaps}e have been extremely lucky in our mentors. Jens cut +his teeth in the company of the Smalltalk pioneers: Alan Kay, Dan +Ingalls, and the rest of the gang who invented personal computing and +object oriented programming in the great days of Xerox PARC. He worked +with John Maloney, of the MIT Scratch Team, who developed the Morphic +graphics framework thatā€™s still at the heart of Snap!.

+ +

The brilliant design of Scratch, from the Lifelong Kindergarten Group +at the MIT Media Lab, is crucial to Snap!. Our earlier version, BYOB, +was a direct modification of the Scratch source code. Snap! is a +complete rewrite, but its code structure and its user interface remain +deeply indebted to Scratch. And the Scratch Team, who could have seen us +as rivals, have been entirely supportive and welcoming to us.

+ +

Brian grew up at the MIT and Stanford Artificial Intelligence Labs, +learning from Lisp inventor John McCarthy, Scheme inventors Gerald J. +Sussman and Guy Steele, and the authors of the worldā€™s best computer +science book, Structure and Interpretation of Computer Programs, Hal +Abelson and Gerald J. Sussman with Julie Sussman, among many other +heroes of computer science. (Brian was also lucky enough, while in high +school, to meet Kenneth Iverson, the inventor of APL.)

+ +

In the glory days of the MIT Logo Lab, we used to say, ā€œLogo is Lisp +disguised as BASIC.ā€ Now, with its first class procedures, lexical +scope, and first class continuations, Snap! is Scheme disguised as +Scratch.

+ +

Four people have made such massive contributions to the implementation +of Snap! that we have officially declared them members of the team: +Michael Ball and Bernat Romagosa, in addition to contributions +throughout the project, have primary responsibility for the web site and +cloud storage. Joan GuillĆ©n i Pelegay has contributed very careful and +wise analysis of outstanding issues, including help in taming the +management of translations to non-English languages. Jadga HĆ¼gle, has +energetically contributed to online mini-courses about Snap! and +leading workshops for kids and for adults. Jens, Jadga, and Bernat are +paid to work on Snap! by SAP, which also supports our computing needs.

+ +

We have been fortunate to get to know an amazing group of brilliant +middle school(!) and high school students through the Scratch Advanced +Topics forum, several of whom (since grown up) have contributed code to +Snap!: Kartik Chandra, Nathan Dinsmore, Connor Hudson, Ian Reynolds, +and Deborah Servilla. Many more have contributed ideas and alpha-testing +bug reports. UC Berkeley students whoā€™ve contributed code include Achal +Dave. Kyle Hotchkiss, Ivan Motyashov, and Yuan Yuan. Contributors of +translations are too numerous to list here, but theyā€™re in the +ā€œAboutā€¦ā€ box in Snap! itself.

+ +

This material is based upon work supported in part by the National +Science Foundation under Grants No[.]{.smallcaps} 1138596, 1143566, and +1441075; and in part by MioSoft, Arduino.org, SAP, and YC Research. Any +opinions, findings, and conclusions or recommendations expressed in this +material are those of the author(s) and do not necessarily reflect the +views of the National Science Foundation or other funders.

+ +

[
+]{.smallcaps}[Snap! Reference Manual]{.underline}

+ +

Version 8.0

+ +

Snap! (formerly BYOB) is an extended reimplementation of Scratch +([http://scratch.mit.edu]{.underline}) that allows you to Build Your Own +Blocks. It also features ļ¬rst class lists, ļ¬rst class procedures, first +class sprites, first class costumes, first class sounds, and first class +continuations. These added capabilities make it suitable for a serious +introduction to computer science for high school or college students.

+ +

In this manual we sometimes make reference to Scratch, e.g., to explain +how some Snap! feature extends something familiar in Scratch. Itā€™s +very helpful to have some experience with Scratch before reading this +manual, but not essential.

+ +

To run Snap![,]{.smallcaps} open a browser window and connect to +http://snap.berkeley.edu/run. The Snap! community web site at +http://snap.berkeley.edu is not part of this manualā€™s scope.

+ +

Blocks, Scripts, and Sprites

+ +

This chapter describes the Snap! features inherited from Scratch; +experienced Scratch users can skip to SectionĀ B.

+ +

Snap! is a programming languageā€”a notation in which you can tell a +computer what you want it to do. Unlike most programming languages, +though, Snap! is a visual language; instead of writing a program +using the keyboard, the Snap! programmer uses the same drag-and-drop +interface familiar to computer users.

+ +

{width=ā€4.326388888888889inā€ +height=ā€2.689583333333333inā€}Start Snap![.]{.smallcaps} You should see +the following arrangement of regions in the window:

+ +

(The proportions of these areas may be different, depending on the size +and shape of your browser window.)

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.3541666666666667inā€}A Snap! program consists of one or more +scripts, each of which is made of blocks. Hereā€™s a typical script:

+ +

{width=ā€2.2465277777777777inā€ +height=ā€1.4694444444444446inā€}{width=ā€2.2083333333333335inā€ +height=ā€1.1388888888888888inā€}The five blocks that make up this script +have three different colors, corresponding to three of the eight +palettes in which blocks can be found. The palette area at the left +edge of the window shows one palette at a time, chosen with the eight +buttons just above the palette area. In this script, the gold blocks are +from the Control palette; the green block is from the Pen palette; and +the blue blocks are from the Motion palette. A script is assembled by +dragging blocks from a palette into the scripting area in the middle +part of the window. Blocks snap together (hence the name Snap! for the +language) when you drag a block so that its indentation is near the tab +of the one above it:

+ +

The white horizontal line is a signal that if you let go of the green +block it will snap into the tab of the gold one.

+ +

Hat Blocks and Command Blocks {#hat-blocks-and-command-blocks .ListParagraph}

+ +

At the top of the script is a hat block, which indicates when the +script should be carried out. Hat block names typically start with the +word ā€œwhenā€; in the square-drawing example on page 5, the script should +be run when the green flag near the right end of the Snap! tool bar is +clicked. (The Snap! tool bar is part of the Snap! window, not the +same as the browserā€™s or operating systemā€™s menu bar.) A script isnā€™t +required to have a hat block, but if not, then the script will be run +only if the user clicks on the script itself. A script canā€™t have more +than one hat block, and the hat block can be used only at the top of the +script; its distinctive shape is meant to remind you of that.1

+ +

{width=ā€1.1666666666666667inā€ +height=ā€0.25inā€}The other blocks in our example script are command +blocks. Each command block corresponds to an action that Snap! already +knows how to carry out. For example, the block tells the sprite (the +arrowhead shape on the stage at the right end of the window) to move +ten steps (a step is a very small unit of distance) in the direction in +which the arrowhead is pointing. Weā€™ll see shortly that there can be +more than one sprite, and that each sprite has its own scripts. Also, a +sprite doesnā€™t have to look like an arrowhead, but can have any picture +as a costume. The shape of the move block is meant to remind you of a +Legoā„¢ brick; a script is a stack of blocks. (The word ā€œblockā€ denotes +both the graphical shape on the screen and the procedure, the action, +that the block carries out.)

+ +

{width=ā€1.0972222222222223inā€ +height=ā€0.3541666666666667inā€}The number 10 in the move block above is +called an input to the block. By clicking on the white oval, you can +type any number in place of the 10. The sample script on the previous +page uses 100 as the input value. Weā€™ll see later that inputs can have +non-oval shapes that accept values other than numbers. Weā€™ll also see +that you can compute input values, instead of typing a particular value +into the oval. A block can have more than one input slot. For example, +the glide block located about halfway down the Motion palette has three +inputs.

+ +

Most command blocks have that brick shape, but some, like the repeat +block in the sample script, are Cā€‘shaped. Most C-shaped blocks are +found in the Control palette. The slot inside the C shape is a special +kind of input slot that accepts a script as the input.

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.3541666666666667inā€}

+ +

{width=ā€1.40625inā€ +height=ā€0.4895833333333333inā€}In the sample script

+ +

{width=ā€5.697916666666667inā€ +height=ā€1.445138888888889inā€}C-shaped blocks can be put in a script in +two ways. If you see a white line and let go, the block will be inserted +into the script like any command block:

+ +

{width=ā€5.501388888888889inā€ +height=ā€1.2777777777777777inā€}But if you see an orange halo and let go, +the block will wrap around the haloed blocks:

+ +

{width=ā€5.800694444444445inā€ +height=ā€1.2916666666666667inā€}The halo will always extend from the +cursor position to the bottom of the script:

+ +

If you want only some of those blocks, after wrapping you can grab the +first block you donā€™t want wrapped, pull it down, and snap it under the +C-shaped block.

+ +

{width=ā€2.311111111111111inā€ +height=ā€1.3666666666666667inā€}For ā€œE-shapedā€ blocks with more than one +C-shaped slot, only the first slot will wrap around existing blocks in a +script, and only if that C-shaped slot is empty before wrapping. (You +can fill the other slots by dragging blocks into the desired slot.)

+ +

{width=ā€0.3402777777777778inā€ height=ā€0.24305555555555555inā€}Sprites and Parallelism

+ +

Just below the stage is the ā€œnew spriteā€ button . Click the button to +add a new sprite to the stage. The new sprite will appear in a random +position on the stage, with a random color, but always facing to the +right.

+ +

Each sprite has its own scripts. To see the scripts for a particular +sprite in the scripting area, click on the picture of that sprite in the +sprite corral in the bottom right corner of the window. Try putting +one of the following scripts in each spriteā€™s scripting area:

+ +
+

{width=ā€1.5506944444444444inā€ +height=ā€0.99375inā€} +{width=ā€1.5416666666666667inā€ +height=ā€1.1666666666666667inā€}

+
+ +

When you click the green flag, you should see one sprite rotate while +the other moves back and forth. This experiment illustrates the way +different scripts can run in parallel. The turning and the moving happen +together. Parallelism can be seen with multiple scripts of a single +sprite also. Try this example:

+ +
+

{width=ā€1.7291666666666667inā€ +height=ā€0.875inā€} +{width=ā€1.7291666666666667inā€ +height=ā€0.8958333333333334inā€}

+
+ +

When you press the space key, the sprite should move forever in a +circle, because the move and turn blocks are run in parallel. (To stop +the program, click the red stop sign at the right end of the tool bar.)

+ +

Costumes and Sounds

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.2152777777777778inā€}{width=ā€1.7666666666666666inā€ +height=ā€1.875inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}To change the appearance of a sprite, +paint or import a new costume for it. To paint a costume, click on the +Costumes tab above the scripting area, and click the paint button . The +Paint Editor that appears is explained on page 128. There are three +ways to import a costume. First select the desired sprite in the sprite +corral. Then, one way is to click on the file icon in the tool bar , +then choose the ā€œCostumesā€¦ā€œmenu item. You will see a list of costumes +from the public media library, and can choose one. The second way, for a +costume stored on your own computer, is to click on the file icon and +choose the ā€œImportā€¦ā€ menu item. You can then select a file in any +picture format (PNG, JPEG, etc.) supported by your browser. The third +way is quicker if the file you want is visible on the desktop: Just drag +the file onto the Snap! window. In any of these cases, the scripting +area will be replaced by something like this:

+ +

Just above this part of the window is a set of three tabs: Scripts, +Costumes, and Sounds. Youā€™ll see that the Costumes tab is now selected. +In this view, the spriteā€™s wardrobe, you can choose whether the sprite +should wear its Turtle costume or its Alonzo costume. (Alonzo, the +Snap! mascot, is named after Alonzo Church, a mathematician who +invented the idea of procedures as data, the most important way in which +Snap! is different from Scratch.) You can give a sprite as many +costumes as you like, and then choose which it will wear either by +clicking in its wardrobe or by using the or block in a script. (Every +costume has a number as well as a name. The next costume block selects +the next costume by number; after the highest-numbered costume it +switches to costume 1. The Turtle, costume 0, is never chosen by next +costume.) The Turtle costume is the only one that changes color to match +a change in the spriteā€™s pen color. Protip: switches to the previous +costume, wrapping like next costume.

+ +

{width=ā€1.8055555555555556inā€ +height=ā€0.2777777777777778inā€}{width=ā€2.9493055555555556inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.8958333333333333inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.2395833333333333inā€ +height=ā€0.2604166666666667inā€}In addition to its costumes, a sprite can +have sounds; the equivalent for sounds of the spriteā€™s wardrobe is +called its jukebox. Sound files can be imported in any format (WAV, +OGG, MP3, etc.) supported by your browser. Two blocks accomplish the +task of playing sounds. If you would like a script to continue running +while the sound is playing, use the block . In contrast, you can use the +block to wait for the sound's completion before continuing the rest of +the script.

+ +

Inter-Sprite Communication with Broadcast

+ +

Earlier we saw an example of two sprites moving at the same time. In a +more interesting program, though, the sprites on stage will interact +to tell a story, play a game, etc. Often one sprite will have to tell +another sprite to run a script. Hereā€™s a simple example:

+ +

{width=ā€1.71875inā€ +height=ā€0.24938648293963256inā€}{width=ā€0.5694444444444444inā€ +height=ā€1.1111111111111112inā€} +{width=ā€2.78417760279965inā€ +height=ā€1.5104166666666667inā€} +{width=ā€1.2430555555555556inā€ +height=ā€0.8611111111111112inā€} +{width=ā€1.5208333333333333inā€ +height=ā€0.6041666666666666inā€}

+ +

{width=ā€1.7895833333333333inā€ +height=ā€0.2inā€}{width=ā€1.8inā€ +height=ā€0.19166666666666668inā€}In the block, the word ā€œbarkā€ is just an +arbitrary name I made up. When you click on the downward arrowhead in +that input slot, one of the choices (the only choice, the first time) is +ā€œnew,ā€ which then prompts you to enter a name for the new broadcast. +When this block is run, the chosen message is sent to every sprite, +which is why the block is called ā€œbroadcast.ā€ (But if you click the +right arrow after the message name, the block becomes , and you can +change it to Ā to send the message just to one sprite.) In this program, +though, only one sprite has a script to run when that broadcast is sent, +namely the dog. Because the boyā€™s script uses broadcast and wait rather +than just broadcast, the boy doesnā€™t go on to his next say block until +the dogā€™s script finishes. Thatā€™s why the two sprites take turns +talking, instead of both talking at once. In Chapter VII, +ā€œObject-Oriented Programming with Sprites,ā€ youā€™ll see a more flexible +way to send a message to a specific sprite using the tell and ask +blocks.

+ +

Notice, by the way, that the say blockā€™s first input slot is rectangular +rather than oval. This means the input can be any text string, not only +a number. In text input slots, a space character is shown as a brown +dot, so that you can count the number of spaces between words, and in +particular you can tell the difference between an empty slot and one +containing spaces. The brown dots are not shown on the stage if the +text is displayed.

+ +

The stage has its own scripting area. It can be selected by clicking on +the Stage icon at the left of the sprite corral. Unlike a sprite, +though, the stage canā€™t move. Instead of costumes, it has backgrounds: +pictures that fill the entire stage area. The sprites appear in front of +the current background. In a complicated project, itā€™s often convenient +to use a script in the stageā€™s scripting area as the overall director of +the action.

+ +

Nesting Sprites: Anchors and Parts

+ +

Sometimes itā€™s desirable to make a sort of ā€œsuper-spriteā€ composed of +pieces that can move together but can also be separately articulated. +The classic example is a personā€™s body made up of a torso, limbs, and a +head. Snap! allows one sprite to be designated as the anchor of the +combined shape, with other sprites as its parts. To set up sprite +nesting, drag the sprite corral icon of a part sprite onto the stage +display (not the sprite corral icon!) of the desired anchor sprite. +The precise place where you let go of the mouse button will be the +attachment point of the part on the anchor.

+ +

{width=ā€1.6305555555555555inā€ +height=ā€0.9652777777777778inā€}Sprite nesting is shown in the sprite +corral icons of both anchors and parts:

+ +

{width=ā€4.875694444444444inā€ +height=ā€0.9472222222222222inā€}{width=ā€1.4444444444444444inā€ +height=ā€1.5625inā€}{width=ā€5.405555555555556inā€ +height=ā€0.8333333333333334inā€}In this illustration, it is desired to +animate Alonzoā€™s arm. (The arm has been colored green in this picture to +make the relationship of the two sprites clearer, but in a real project +theyā€™d be the same color, probably.) Sprite, representing Alonzoā€™s body, +is the anchor; Sprite(2) is the arm. The icon for the anchor shows small +images of up to three attached parts at the bottom. The icon for each +part shows a small image of the anchor in its top left corner, and a +synchronous/dangling rotation flag in the top right corner. In its +initial, synchronous setting, as shown above, it means that the when the +anchor sprite rotates, the part sprite also rotates as well as revolving +around the anchor. When clicked, it changes from a circular arrow to a +straight arrow, and indicates that when the anchor sprite rotates, the +part sprite revolves around it, but does not rotate, keeping its +original orientation. (The part can also be rotated separately, using +its turn blocks.) Any change in the position or size of the anchor is +always extended to its parts. Also, cloning the anchor (see Section VII. +B) will also clone all its parts.

+ +

Top: turning the part: the green arm. Bottom: turning the anchor, with +the arm synchronous (left) and dangling (right).

+ +

Reporter Blocks and Expressions

+ +

{width=ā€1.47inā€ +height=ā€0.52inā€}{width=ā€0.7291666666666666inā€ +height=ā€0.15625inā€}So far, weā€™ve used two kinds of blocks: hat blocks +and command blocks. Another kind is the reporter block, which has an +oval shape: . Itā€™s called a ā€œreporterā€ because when itā€™s run, instead of +carrying out an action, it reports a value that can be used as an input +to another block. If you drag a reporter into the scripting area by +itself and click on it, the value it reports will appear in a speech +balloon next to the block:

+ +

{width=ā€5.312752624671916inā€ +height=ā€0.9583333333333334inā€}When you drag a reporter block over +another blockā€™s input slot, a white ā€œhaloā€ appears around that input +slot, analogous to the white line that appears when snapping command +blocks together:

+ +

{width=ā€2.111111111111111inā€ +height=ā€0.6180555555555556inā€}Donā€™t drop the input over a red halo:

+ +

Thatā€™s used for a purpose explained on page 68.

+ +

Hereā€™s a simple script that uses a reporter block:

+ +

{width=ā€5.319444444444445inā€ +height=ā€1.3645833333333333inā€}Here the x position reporter provides the +first input to the say block. (The spriteā€™s X position is its horizontal +position, how far left (negative values) or right (positive values) it +is compared to the center of the stage. Similarly, the Y position is +measured vertically, in steps above (positive) or below (negative) the +center.)

+ +

You can do arithmetic using reporters in the Operators palette:

+ +

{width=ā€6.263888888888889inā€ +height=ā€1.4479166666666667inā€}The round block rounds 35.3905ā€¦ to 35, +and the + block adds 100 to that. (By the way, the round block is in the +Operators palette, just like +, but in this script itā€™s a lighter color +with black lettering because Snap! alternates light and dark versions +of the palette colors when a block is nested inside another block from +the same palette:

+ +

{width=ā€4.854166666666667inā€ +height=ā€1.90625inā€}

+ +

{width=ā€1.9166666666666667inā€ +height=ā€0.23958333333333334inā€}This aid to readability is called zebra +coloring.) A reporter block with its inputs, maybe including other +reporter blocks, such as , is called an expression.

+ +

Predicates and Conditional Evaluation

+ +

{width=ā€0.6666666666666666inā€ +height=ā€0.1875inā€}{width=ā€1.2083333333333333inā€ +height=ā€0.1875inā€}Most reporters report either a number, like , or a +text string, like . A predicate is a special kind of reporter that +always reports true or false. Predicates have a hexagonal shape:

+ +

{width=ā€1.9479166666666667inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.0729166666666667inā€ +height=ā€0.15625inā€}The special shape is a reminder that predicates donā€™t +generally make sense in an input slot of blocks that are expecting a +number or text. You wouldnā€™t say , although (as you can see from the +picture) Snap! lets you do it if you really want. Instead, you +normally use predicates in special hexagonal input slots like this one:

+ +

{width=ā€0.6666666666666666inā€ +height=ā€0.5694444444444444inā€}The C-shaped if block runs its input +script if (and only if) the expression in its hexagonal input reports +true.

+ +

{width=ā€1.59375inā€ +height=ā€0.6145833333333334inā€}A really useful block in animations runs +its input script repeatedly until a predicate is satisfied:

+ +

{width=ā€2.2819444444444446inā€ +height=ā€1.46875inā€}{width=ā€2.2916666666666665inā€ +height=ā€0.84375inā€}If, while working on a project, you want to omit +temporarily some commands in a script, but you donā€™t want to forget +where they belong, you can say

+ +

Sometimes you want to take the same action whether some condition is +true or false, but with a different input value. For this purpose you +can use the reporter if block:

+ +

{width=ā€4.208333333333333inā€ +height=ā€0.3854166666666667inā€}The technical term for a true or false +value is a ā€œBooleanā€ value; it has a capital B because itā€™s named after +a person, George Boole, who developed the mathematical theory of Boolean +values. Donā€™t get confused; a hexagonal block is a predicate, but the +value it reports is a Boolean.

+ +

Another quibble about vocabulary: Many programming languages reserve the +name ā€œprocedureā€ for Commands (that carry out an action) and use the +name ā€œfunctionā€ for Reporters and Predicates. In this manual, a +procedure is any computational capability, including those that report +values and those that donā€™t. Commands, Reporters, and Predicates are all +procedures. The words ā€œa Procedure typeā€ are shorthand for ā€œCommand +type, Reporter type, or Predicate type.ā€

+ +

{width=ā€1.375inā€ +height=ā€0.24305555555555555inā€}{width=ā€1.375inā€ +height=ā€0.24305555555555555inā€}If you want to put a constant Boolean +value in a hexagonal slot instead of a predicate-based expression, hover +the mouse over the block and click on the control that appears:

+ +

Variables

+ +

{width=ā€1.5833333333333333inā€ +height=ā€1.4166666666666667inā€}Try this script:

+ +

{width=ā€1.8854166666666667inā€ +height=ā€1.4375inā€}The input to the move block is an orange oval. To get +it there, drag the orange oval thatā€™s part of the for block:

+ +

The orange oval is a variable: a symbol that represents a value. (I +took this screenshot before changing the second number input to the for +block from the default 10 to 200, and before dragging in a turn block.) +For runs its script input repeatedly, just like repeat, but before each +repetition it sets the variable i to a number starting with its first +numeric input, adding 1 for each repetition, until it reaches the second +numeric input. In this case, there will be 200 repetitions, first with +i=1, then with i=2, then 3, and so on until i=200 for the final +repetition. The result is that each move draws a longer and longer line +segment, and thatā€™s why the picture you see is a kind of spiral. (If you +try again with a turn of 90 degrees instead of 92, youā€™ll see why this +picture is called a ā€œsquiral.ā€)

+ +

{width=ā€3.1875inā€ +height=ā€1.5inā€}The variable i is created by the for block, and it can +only be used in the script inside the blockā€™s C-slot. (By the way, if +you donā€™t like the name i, you can change it by clicking on the orange +oval without dragging it, which will pop up a dialog window in which you +can enter a different name:

+ +

ā€œIā€ isnā€™t a very descriptive name; you might prefer ā€œlengthā€ to indicate +its purpose in the script. ā€œIā€ is traditional because mathematicians +tend to use letters between i and n to represent integer values, but in +programming languages we donā€™t have to restrict ourselves to +single-letter variable names.)

+ +

Global Variables

+ +

You can create variables ā€œby handā€ that arenā€™t limited to being used +within a single block. At the top of the Variables palette, click the +ā€œMake a variableā€ button:

+ +

{width=ā€3.1875inā€ +height=ā€1.84375inā€}{width=ā€2.0520833333333335inā€ +height=ā€2.2708333333333335inā€}This will bring up a dialog window in +which you can give your variable a name:

+ +

The dialog also gives you a choice to make the variable available to all +sprites (which is almost always what you want) or to make it visible +only in the current sprite. Youā€™d do that if youā€™re going to give +several sprites individual variables with the same name, so that you +can share a script between sprites (by dragging it from the current +spriteā€™s scripting area to the picture of another sprite in the sprite +corral), and the different sprites will do slightly different things +when running that script because each has a different value for that +variable name.

+ +

{width=ā€1.6583333333333334inā€ +height=ā€2.2916666666666665inā€}If you give your variable the name ā€œnameā€ +then the Variables palette will look like this:

+ +

{width=ā€1.0416666666666667inā€ +height=ā€0.40625inā€}Thereā€™s now a ā€œDelete a variableā€ button, and thereā€™s +an orange oval with the variable name in it, just like the orange oval +in the for block. You can drag the variable into any script in the +scripting area. Next to the oval is a checkbox, initially checked. When +itā€™s checked, youā€™ll also see a variable watcher on the stage:

+ +

When you give the variable a value, the orange box in its watcher will +display the value.

+ +

{width=ā€1.9270833333333333inā€ +height=ā€0.4791666666666667inā€}How do you give it a value? You use the +set block:

+ +

Note that you donā€™t drag the variableā€™s oval into the set block! You +click on the downarrow in the first input slot, and you get a menu of +all the available variable names.

+ +

If you do choose ā€œFor this sprite onlyā€ when creating a variable, its +block in the palette looks like this:

+ +

Macintosh
+HD:Users:bh:Desktop:local-var.png{width=ā€0.6583333333333333inā€ +height=ā€0.14166666666666666inā€} The location-pin icon is a bit of a +pun on a sprite-local variable. Itā€™s shown only in the palette.

+ +

Script Variables

+ +

{width=ā€5.503472222222222inā€ +height=ā€2.3125inā€}In the name example above, our project is going to +carry on an interaction with the user, and we want to remember their +name throughout the project. Thatā€™s a good example of a situation in +which a global variable (the kind you make with the ā€œMake a variableā€ +button) is appropriate. Another common example is a variable called +ā€œscoreā€ in a game project. But sometimes you only need a variable +temporarily, during the running of a particular script. In that case you +can use the script variables block to make the variable:

+ +

As in the for block, you can click on an orange oval in the script +variables block without dragging to change its name. You can also make +more than one temporary variable by clicking on the right arrow at the +end of the block to add another variable oval:

+ +

{width=ā€2.0833333333333335inā€ height=ā€0.3020833333333333inā€}Renaming variables

+ +

There are several reasons why you might want to change the name of a +variable:

+ +
    +
  1. +

    It has a default name, such as the ā€œaā€ in script variables or the +ā€œiā€ in for.

    +
  2. +
  3. +

    It conflicts with another name, such as a global variable, that you +want to use in the same script.

    +
  4. +
  5. +

    You just decide a different name would be more self-documenting.

    +
  6. +
+ +

In the first and third case, you probably want to change the name +everywhere it appears in that script, or even in all scripts. In the +second case, if youā€™ve already used both variables in the script before +realizing that they have the same name, youā€™ll want to look at each +instance separately to decide which ones to rename. Both of these +operations are possible by right-clicking or control-clicking on a +variable oval.

+ +

{width=ā€1.613888888888889inā€ +height=ā€1.507638888888889inā€}{width=ā€2.826388888888889inā€ +height=ā€1.2569444444444444inā€}{width=ā€1.3819444444444444inā€ +height=ā€0.7430555555555556inā€}If you right-click on an orange oval in a +context in which the variable is used, then you are able to rename +just that one orange oval:

+ +

{width=ā€1.7083333333333333inā€ +height=ā€0.8333333333333334inā€}{width=ā€1.4930555555555556inā€ +height=ā€0.7430555555555556inā€}If you right-click on the place where the +variable is defined (a script variables block, the orange oval for a +global variable in the Variables palette, or an orange oval thatā€™s built +into a block such as the ā€œiā€ in for), then you are given two renaming +options, ā€œrenameā€ and ā€œrename all.ā€ If you choose ā€œrename,ā€ then the +name is changed only in that one orange oval, as in the previous case:

+ +

{width=ā€1.4930555555555556inā€ +height=ā€0.7430555555555556inā€}{width=ā€1.7083333333333333inā€ +height=ā€0.8333333333333334inā€}But if you choose ā€œrename all,ā€ then the +name will be changed throughout the scope of the variable (the script +for a script variable, or everywhere for a global variable):

+ +

Transient variables

+ +

{width=ā€1.2916666666666667inā€ +height=ā€1.0555555555555556inā€}So far weā€™ve talked about variables with +numeric values, or with short text strings such as someoneā€™s name. But +thereā€™s no limit to the amount of information you can put in a variable; +in Chapter IV youā€™ll see how to use lists to collect many values in +one data structure, and in Chapter VIII youā€™ll see how to read +information from web sites. When you use these capabilities, your +project may take up a lot of memory in the computer. If you get close to +the amount of memory available to Snap!, then it may become impossible +to save your project. (Extra space is needed temporarily to convert from +Snap! ā€˜s internal representation to the form in which projects are +exported or saved.) If your program reads a lot of data from the outside +world that will still be available when you use it next, you might want +to have values containing a lot of data removed from memory before +saving the project. To do this, right-click or control-click on the +orange oval in the Variables palette, to see this menu:

+ +

You already know about the rename options, and helpā€¦ displays a help +screen about variables in general. Here weā€™re interested in the check +box next to transient. If you check it, this variableā€™s value will not +be saved when you save your project. Of course, youā€™ll have to ensure +that when your project is loaded, it recreates the needed value and sets +the variable to it.

+ +

Debugging

+ +

Snap! provides several tools to help you debug a program. They center +around the idea of pausing the running of a script partway through, so +that you can examine the values of variables.

+ +

The pause button

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The simplest way to pause a program is +manually, by clicking the pause button in the top right corner of the +window. While the program is paused, you can run other scripts by +clicking on them, show variables on stage with the checkbox next to the +variable in the Variables palette or with the show variable block, and +do all the other things you can generally do, including modifying the +paused scripts by adding or removing blocks. The button changes shape to +and clicking it again resumes the paused scripts.

+ +

Breakpoints: the pause all block

+ +

{width=ā€0.8194444444444444inā€ +height=ā€0.2152777777777778inā€}The pause button is great if your program +seems to be in an infinite loop, but more often youā€™ll want to set a +breakpoint, a particular point in a script at which you want to pause. +The block, near the bottom of the Control palette, can be inserted in a +script to pause when it is run. So, for example, if your program is +getting an error message in a particular block, you could use pause all +just before that block to look at the values of variables just before +the error happens.

+ +

{width=ā€1.8833333333333333inā€ +height=ā€0.9111111111111111inā€}The pause all block turns bright cyan +while paused. Also, during the pause, you can right-click on a running +script and the menu that appears will give you the option to show +watchers for temporary variables of the script:

+ +

But what if the block with the error is run many times in a loop, and it +only errors when a particular condition is trueā€”say, the value of some +variable is negative, which shouldnā€™t ever happen. In the iteration +library (see page 25 for more about how to use libraries) is a +breakpoint block that lets you set a conditional breakpoint, and +automatically display the relevant variables before pausing. Hereā€™s a +sample use of it:

+ +

{width=ā€1.1944444444444444inā€ +height=ā€1.3333333333333333inā€}(In this contrived example, variable zot +comes from outside the script but is relevant to its behavior.) When you +continue (with the pause button), the temporary variable watchers are +removed by this breakpoint block before resuming the script. The +breakpoint block isnā€™t magic; you could alternatively just put a pause +all inside an if.2

+ +

Visible stepping

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.5456342957130359inā€ +height=ā€0.1527777777777778inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Sometimes youā€™re not exactly sure where +the error is, or you donā€™t understand how the program got there. To +understand better, youā€™d like to watch the program as it runs, at human +speed rather than at computer speed. You can do this by clicking the +visible stepping button ( ), before running a script or while the +script is paused. The button will light up ( ) and a speed control +slider will appear in the toolbar. When you start or continue the +script, its blocks and input slots will light up cyan one at a time:

+ +

{width=ā€7.498611111111111inā€ +height=ā€1.15inā€}In this simple example, the inputs to the blocks are +constant values, but if an input were a more complicated expression +involving several reporter blocks, each of those would light up as they +are called. Note that the input to a block is evaluated before the block +itself is called, so, for example, the 100 lights up before the move.

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The speed of stepping is controlled by +the slider. If you move the slider all the way to the left, the speed is +zero, the pause button turns into a step button , and the script takes a +single step each time you push it. The name for this is single +stepping.

+ +

If several scripts that are visible in the scripting area are running at +the same time, all of them are stepped in parallel. However, consider +the case of two repeat loops with different numbers of blocks. While not +stepping, each script goes through a complete cycle of its loop in each +display cycle, despite the difference in the length of a cycle. In order +to ensure that the visible result of a program on the stage is the same +when stepped as when not stepped, the shorter script will wait at the +bottom of its loop for the longer script to catch up.

+ +

When we talk about custom blocks in Chapter III, weā€™ll have more to say +about visible stepping as it affects those blocks.

+ +

Etcetera

+ +

This manual doesnā€™t explain every block in detail. There are many more +motion blocks, sound blocks, costume and graphics effects blocks, and so +on. You can learn what they all do by experimentation, and also by +reading the ā€œhelp screensā€ that you can get by right-clicking or +control-clicking a block and selecting ā€œhelpā€¦ā€ from the menu that +appears. If you forget what palette (color) a block is, but you remember +at least part of its name, type control-F and enter the name in the text +block that appears in the palette area.

+ +

Here are the primitive blocks that donā€™t exist in Scratch:

+ +

{width=ā€1.25inā€ +height=ā€0.22916666666666666inā€}{width=ā€1.0520833333333333inā€ +height=ā€0.22916666666666666inā€} reports a new costume consisting of +everything thatā€™s drawn on the stage by any sprite. Right-clicking the +block in the scripting area gives the option to change it to if vector +logging is enabled. See page 116.

+ +

{width=ā€2.0833333333333335inā€ +height=ā€0.375inā€}Print characters in the given point size on the stage, +at the spriteā€™s position and in its direction. The sprite moves to the +end of the text. (Thatā€™s not always what you want, but you can save the +spriteā€™s position before using it, and sometimes you need to know how +big the text turned out to be, in turtle steps.) If the pen is down, the +text will be underlined.

+ +

{width=ā€1.2006944444444445inā€ +height=ā€0.5138888888888888inā€}Takes a sprite as input. Like stamp except +that the costume is stamped onto the selected sprite instead of onto the +stage. (Does nothing if the current sprite doesnā€™t overlap the chosen +sprite.)

+ +

{width=ā€1.1916666666666667inā€ +height=ā€0.3388888888888889inā€}Takes a sprite as input. Erases from that +spriteā€™s costume the area that overlaps with the current spriteā€™s +costume. (Does not affect the costume in the chosen spriteā€™s wardrobe, +only the copy currently visible.)

+ +

{width=ā€0.5298611111111111inā€ +height=ā€0.5inā€}{width=ā€0.9895833333333334inā€ +height=ā€0.25972222222222224inā€}Icon Description automatically
+generated{width=ā€1.3298611111111112inā€ +height=ā€0.42986111111111114inā€} See page 6. See page 17.

+ +

{width=ā€1.71inā€ +height=ā€0.23inā€}Reporter version of the if/else primitive command block. +Only one of the two branches is evaluated, depending on the value of the +first input.

+ +

{width=ā€1.83inā€ +height=ā€0.61inā€}Looping block like repeat but with an index variable.

+ +

{width=ā€1.3798611111111112inā€ +height=ā€0.28958333333333336inā€}Declare local variables in a script.

+ +

{width=ā€0.86inā€ +height=ā€0.19inā€}{width=ā€0.72inā€ +height=ā€0.2inā€}{width=ā€1.17inā€ +height=ā€0.18inā€} See page 91.

+ +

{width=ā€2.738611111111111inā€ +height=ā€0.2116819772528434inā€}Constant true or false value. See page 12.

+ +

{width=ā€2.13inā€ height=ā€0.18inā€} +Create a primitive using JavaScript. (This block is disabled by default; +the user must check ā€œJavascript extensionsā€ in the setting menu each +time a project is loaded.)

+ +

{width=ā€1.6305555555555555inā€ +height=ā€1.5756944444444445inā€}The at block lets you examine the screen +pixel directly behind the rotation center of a sprite, the mouse, or an +arbitrary (x,y) coordinate pair dropped onto the second menu slot. The +first five items of the left menu let you examine the color visible at +the position. (The ā€œRGBAā€ option reports a list.) The ā€œspritesā€ option +reports a list of all sprites, including this one, any point of which +overlaps this spriteā€™s rotation center (behind or in front). This is a +hyperblock with respect to its second input.

+ +

{width=ā€1.6862992125984253inā€ +height=ā€1.852853237095363inā€}{width=ā€2.4458333333333333inā€ +height=ā€1.3263888888888888inā€}{width=ā€2.3555555555555556inā€ +height=ā€0.3888888888888889inā€} Checks the data type of a value.

+ +

{width=ā€3.398297244094488inā€ +height=ā€1.065152012248469inā€}

+ +

{width=ā€2.504166666666667inā€ +height=ā€2.23125inā€}Turn the text into a list, using the second input as +the delimiter between items. The default delimiter, indicated by the +brown dot in the input slot, is a single space character. ā€œLetterā€ puts +each character of the text in its own list item. ā€œWordā€ puts each word +in an item. (Words are separated by any number of consecutive space, +tab, carriage return, or newline characters.) ā€œLineā€ is a newline +character (0xa); ā€œtabā€ is a tab character (0x9); ā€œcrā€ is a carriage +return (0xd). ā€œCsvā€ and ā€œjsonā€ split formatted text into lists of lists; +see page 54. ā€œBlocksā€ takes a script as the first input, reporting a +list structure representing the structure of the script. See Chapter XI.

+ +

{width=ā€1.479861111111111inā€ +height=ā€0.18958333333333333inā€}For lists, reports true only if its two +input values are the very same list, so changing an item in one of them +is visible in the other. (For =, lists that look the same are the same.) +For text strings, uses case-sensitive comparison, unlike =, which is +case-independent.

+ +

{width=ā€2.867929790026247inā€ +height=ā€0.18958333333333333inā€}These hidden blocks can be found with +the relabel option of any dyadic arithmetic block. Theyā€™re hidden partly +because writing them in Snap! is a good, pretty easy programming +exercise. Note: the two inputs to atan2 are Ī”x and Ī”y in that order, +because we measure angles clockwise from north. Max and min are +variadic; by clicking the arrowhead, you can provide additional +inputs.

+ +

Logo Description automatically generated with medium
+confidence{width=ā€0.63inā€ +height=ā€0.19inā€} A picture containing text, monitor, screenshot
+Description automatically
+generated{width=ā€0.63inā€ +height=ā€0.19inā€} Logo Description automatically
+generated{width=ā€0.63inā€ +height=ā€0.19inā€} Similarly, these hidden predicates can be found by +relabeling the relational predicates.

+ +

{width=ā€5.449558180227472inā€ +height=ā€0.6166666666666667inā€}Metaprogramming (see Chapter XI. , +page 101)

+ +

These blocks support metaprogramming, which means manipulating blocks +and scripts as data. This is not the same as manipulating procedures +(see Chapter VI. ), which are what the blocks mean; in metaprogramming +the actual blocks, what you see on the screen, are the data. This +capability is new in version 8.0.

+ +

First class list blocks (see Chapter IV, page 46):

+ +

{width=ā€7.616666666666666inā€ +height=ā€2.183333333333333inā€}

+ +


+**{width=ā€0.83inā€ +height=ā€0.21inā€} {width=ā€1.43inā€ +height=ā€0.21inā€} **report the sprite or mouse position as a two-item +vector (x,y).

+ +

{width=ā€5.9944444444444445inā€ +height=ā€0.325inā€}First class procedure blocks (see Chapter VI, page +65):

+ +

{width=ā€5.330555555555556inā€ +height=ā€0.3451388888888889inā€}{width=ā€4.361111111111111inā€ +height=ā€0.325inā€}First class continuation blocks (see Chapter X, +page 93):

+ +

First class sprite, costume, and sound blocks (see Chapter VII, page +73):

+ +

{width=ā€5.88125inā€ +height=ā€2.1479166666666667inā€}

+ +

Scenes:

+ +

{width=ā€2.38inā€ +height=ā€1.32inā€}The major new feature of version 7.0 is scenes: A +project can include within it sub-projects, called scenes, each with its +own stage, sprites, scripts, and so on. This block makes another scene +active, replacing the current one.

+ +

Nothing is automatically shared between scenes: no sprites, no blocks, +no variables. But the old scene can send a message to the new one, to +start it running, with optional payload as in broadcast (page 23).

+ +

{width=ā€2.54inā€ +height=ā€0.31inā€}{width=ā€3.129861111111111inā€ +height=ā€0.5236111111111111inā€}In particular, you can say

+ +
+

if the new scene expects to be started with a green flag signal.

+
+ +


+These arenā€™t new blocks but they have a new feature:

+ +

These accept two-item (x,y) lists as input, and have extended menus +(also including other sprites):

+ +

{width=ā€7.483252405949257inā€ +height=ā€1.1298611111111112inā€}ā€Centerā€ means the center of the stage, +the point at (0,0). ā€œDirectionā€ is in the point in direction sense, the +direction that would leave this sprite pointing toward another sprite, +the mouse, or the center. ā€œRay lengthā€ is the distance from the center +of this sprite to the nearest point on the other sprite, in the current +direction.

+ +

{width=ā€2.571527777777778inā€ +height=ā€1.41875inā€}The stop block has two extra menu choices. Stop this +block is used inside the definition of a custom block to stop just this +invocation of this custom block and continue the script that called it. +Stop all but this script is good at the end of a game to stop all the +game pieces from moving around, but keep running this script to provide +the userā€™s final score. The last two menu choices add a tab at the +bottom of the block because the current script can continue after it.

+ +

{width=ā€2.4125inā€ +height=ā€1.0659722222222223inā€}The new ā€œpen trailsā€ option is true if the +sprite is touching any drawn or stamped ink on the stage. Also, touching +will not detect hidden sprites, but a hidden sprite can use it to detect +visible sprites.

+ +

{width=ā€1.0597222222222222inā€ +height=ā€0.2798611111111111inā€}{width=ā€2.433333333333333inā€ +height=ā€0.3inā€}The video block has a snap option that takes a snapshot +and reports it as a costume. It is hyperized with +{width=ā€1.0520833333333333inā€ +height=ā€0.28125inā€}respect to its second input.

+ +

{width=ā€1.4166666666666667inā€ +height=ā€3.3319444444444444inā€}The ā€œnegā€ option is a monadic negation +operator, equivalent to . ā€œlgā€ is log~2~. ā€œidā€ is the identity function, +which reports its input. ā€œsignā€ reports 1 for positive input, 0 for zero +input, or -1 for negative input.

+ +

{width=ā€3.286111111111111inā€ +height=ā€0.5513888888888889inā€}

+ +

{width=ā€3.7604166666666665inā€ +height=ā€1.214646762904637inā€}

+ +

{width=ā€2.213888888888889inā€ +height=ā€1.6604166666666667inā€}Extended mouse interaction events, sensing +clicking, dragging, hovering, etc. The ā€œstoppedā€ option triggers when +all scripts are stopped, as with the stop button; it is useful for +robots whose hardware interface must be told to turn off motors. A when +I am stopped script can run only for a limited time.

+ +

{width=ā€2.879861111111111inā€ +height=ā€1.717186132983377inā€}

+ +

Extended broadcast: Click the right arrowhead to direct the message to a +single sprite or the stage. Click again to add any value as a payload to +the message.

+ +

{width=ā€3.7784722222222222inā€ +height=ā€1.8090277777777777inā€}{width=ā€1.8194444444444444inā€ +height=ā€0.9597222222222223inā€}Extended when I receive: Click the right +arrowhead to expose a script variable (click on it to change its name, +like any script variable) that will be set to the data of a matching +broadcast. If the first input is set to ā€œany message,ā€ then the data +variable will be set to the message, if no payload is included with the +broadcast, or to a two-item list containing the message and the payload.

+ +

A picture containing text, clipart Description automatically
+generated{width=ā€1.68inā€ +height=ā€0.38inā€} If the input is set to ā€œany key,ā€ then a right +arrowhead appears:

+ +
+

{width=ā€2.25inā€ +height=ā€0.41944444444444445inā€}{width=ā€1.8194444444444444inā€ +height=ā€0.3798611111111111inā€}and if you click it, a script variable +key is created whose value is the key that was pressed. (If the key is +one thatā€™ represented in the input menu by a word or phrase, e.g., +ā€œenterā€ or ā€œup arrow,ā€ then the value of key will be that word or +phrase, except for the space character, which is represented as +itself in key.)
+{width=ā€3.0924245406824147inā€ +height=ā€0.6895833333333333inā€}

+
+ +

{width=ā€5.95inā€ +height=ā€0.8798611111111111inā€}{width=ā€5.569444444444445inā€ +height=ā€1.1inā€}{width=ā€6.3694444444444445inā€ +height=ā€2.9086690726159232inā€}

+ +

{width=ā€1.455618985126859inā€ +height=ā€2.327904636920385inā€}{width=ā€5.874242125984252inā€ +height=ā€1.0097222222222222inā€}These ask features and more in the Menus +library.

+ +

The of block has an extended menu of attributes of a sprite. Position +reports an (x,y) vector. Size reports the percentage of normal size, as +controlled by the set size block in the Looks category. Left, right, +etc. report the stage coordinates of the corresponding edge of the +spriteā€™s bounding box. Variables reports a list of the names of all +variables in scope (global, sprite-local, and script variables if the +right input is a script.

+ +

Libraries

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}{width=ā€7.401388888888889inā€ +height=ā€3.238888888888889inā€}There are several collections of useful +procedures that arenā€™t Snap! primitives, but are provided as +libraries. To include a library in your project, choose the Librariesā€¦ +option in the file ( ) menu.

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs.

+ +

The libraries and their contents may change, but as of this writing the +list library has these blocks:

+ +

{width=ā€1.8486111111111112inā€ +height=ā€2.4923611111111112inā€} (The lightning bolt before the name in +several of these blocks means that they use compiled HOFs or JavaScript +primitives to achieve optimal speed. They are officially considered +experimental.) Remove duplicates from reports a list in which no two +items are equal. The sort block takes a list and a two-input comparison +predicate, such as <, and reports a list with the items sorted +according to that comparison. The assoc block is for looking up a key in +an association list: a list of two-item lists. In each two-item list, +the first is a key and the second is a value. The inputs are a key +and an association list; the block reports the first key-value pair +whose key is equal to the input key.

+ +

For each item is a variant of the primitive version that provides a # +variable containing the position in the input list of the currently +considered item. Multimap is a version of map that allows multiple list +inputs, in which case the mapping function must take as many inputs as +there are lists; it will be called with all the first items, all the +second items, and so on. Zip takes any number of lists as inputs; it +reports a list of lists: all the first items, all the second items, and +so on. The no-name identity function reports its input.

+ +

Sentence and sentenceāž”list are borrowed from the word and sentence +library (page 27) to serve as a variant of append that accepts non-lists +as inputs. Printable takes a list structure of any depth as input and +reports a compact representation of the list as a text string.

+ +

The iteration, composition library has these blocks:

+ +

{width=ā€1.6888888888888889inā€ +height=ā€4.75inā€}Catch and throw provide a nonlocal exit facility. You +can drag the tag from a catch block to a throw inside its C-slot, and +the throw will then jump directly out to the matching catch without +doing anything in between.

+ +

If do and pause all is for setting a breakpoint while debugging code. +The idea is to put show variable blocks for local variables in the +C-slot; the watchers will be deleted when the user continues from the +pause.

+ +

Ignore is used when you need to call a reporter but you donā€™t care about +the value it reports. (For example, you are writing a script to time how +long the reporter takes.)

+ +

The cascade blocks take an initial value and call a function repeatedly +on that value, f(f(f(fā€¦(x)))).

+ +

The compose block takes two functions and reports the function +f(g(x)).

+ +

{width=ā€1.0444444444444445inā€ +height=ā€0.16111111111111112inā€}{width=ā€3.1527777777777777inā€ +height=ā€0.2986111111111111inā€}The first three repeat blocks are variants +of the primitive repeat until block, giving all four combinations of +whether the first test happens before or after the first repetition, and +whether the condition must be true or false to continue repeating. The +last repeat block is like the repeat primitive, but makes the number of +repetitions so far available to the repeated script. The next two blocks +are variations on for: the first allows an explicit step instead of +using Ā±1, and the second allows any values, not just numbers; inside the +script you say

+ +

{width=ā€3.4409722222222223inā€ +height=ā€1.3611111111111112inā€}{width=ā€3.709722222222222inā€ +height=ā€1.1715277777777777inā€}replacing the grey block in the picture +with an expression to give the next desired value for the loop index. +Pipe allows reordering a nested composition with a left-to-right one:

+ +

The stream library has these blocks:

+ +

{width=ā€3.161111111111111inā€ +height=ā€2.1534722222222222inā€}Streams are a special kind of list whose +items are not computed until they are needed. This makes certain +computations more efficient, and also allows the creation of lists with +infinitely many items, such as a list of all the positive integers. The +first five blocks are stream versions of the list blocks in front of, +item 1 of, all but first of, map, and keep. Show stream takes a stream +and a number as inputs, and reports an ordinary list of the first n +items of the stream. Stream is like the primitive list; it makes a +finite stream from explicit items. Sieve is an example block that takes +as input the stream of integers starting with 2 and reports the stream +of all the prime numbers. Stream with numbers from is like the numbers +from block for lists, except that there is no endpoint; it reports an +infinite stream of numbers.

+ +

The word and sentence library has these blocks:

+ +

{width=ā€1.679861111111111inā€ +height=ā€3.6430555555555557inā€}This library has the goal of recreating +the Logo approach to handling text: A text isnā€™t best viewed as a string +of characters, but rather as a sentence, made of words, each of +which is a string of letters. With a few specialized exceptions, this +is why people put text into computers: The text is sentences of natural +(i.e., human) language, and the emphasis is on words as constitutive of +sentences. You barely notice the letters of the words, and you donā€™t +notice the spaces between them at all, unless youā€™re proof-reading. +(Even then: Proofreading is diffciult, because you see what you expect +to see, what will make the snetence make sense, rather than the +misspelling in front of of your eyes.) Internally, Logo stores a +sentence as a list of words, and a word as a string of letters.

+ +

Inexplicably, the designers of Scratch chose to abandon that tradition, +and to focus on the representation of text as a string of characters. +The one vestige of the Logo tradition from which Scratch developed is +the block named letter (1) of (world), rather than character (1) of +(world). Snap! inherits its text handling from Scratch.

+ +

In Logo, the visual representation of a sentence (a list of words) looks +like a natural language sentence: a string of words with spaces between +them. In Snap!, the visual representation of a list looks nothing at +all like natural language. On the other hand, representing a sentence as +a string means that the program must continually re-parse the text on +every operation, looking for spaces, treating multiple consecutive +spaces as one, and so on. Also, itā€™s more convenient to treat a sentence +as a list of words rather than a string of words because in the former +case you can use the higher order functions map, keep, and combine on +them. This library attempts to be agnostic as to the internal +representation of sentences. The sentence selectors accept any +combination of lists and strings; there are two sentence constructors, +one to make a string (join words) and one to make a list (sentence).

+ +

The selector names come from Logo, and should be self-explanatory. +However, because in a block language you donā€™t have to type the block +name, instead of the terse butfirst or the cryptic bf we spell out ā€œall +but first ofā€ and include ā€œwordā€ or ā€œsentenceā€ to indicate the intended +domain. Thereā€™s no first letter of block because letter 1 of serves that +need. Join words (the sentence-as-string constructor) is like the +primitive join except that it puts a space in the reported value between +each of the inputs. Sentence (the List-colored sentence-as-list +constructor) accepts any number of inputs, which can be words, +sentences-as-lists, or sentences-as-strings. (If inputs are lists of +lists, only one level of flattening is done.) Sentence reports a list of +words; there will be no empty words or words containing spaces. The four +blocks with right-arrows in their names convert back and forth between +text strings (words or sentences) and lists. (Splitting a word into a +list of letters is unusual unless youā€™re a linguist investigating +orthography.) Printable takes a list (including a deep list) of words as +input and reports a text string in which parentheses are used to show +the structure, as in Lisp/Scheme.

+ +

The pixels library has one block:

+ +

{width=ā€0.7791666666666667inā€ +height=ā€0.6298611111111111inā€}Costumes are first class data in Snap!. +Most of the processing of costume data is done by primitive blocks in +the Looks category. (See page 79.) This library provides snap, which +takes a picture using your computerā€™s camera and reports it as a +costume.

+ +

The bar charts library has these blocks:

+ +

{width=ā€3.4305555555555554inā€ +height=ā€1.9166666666666667inā€}Bar chart takes a table (typically from a +CSV data set) as input and reports a summary of the table grouped by the +field in the specified column number. The remaining three inputs are +used only if the field values are numbers, in which case they can be +grouped into buckets (e.g., decades, centuries, etc.). Those inputs +specify the smallest and largest values of interest and, most +importantly, the width of a bucket (10 for decades, 100 for centuries). +If the field isn't numeric, leave these three inputs empty or set them +to zero. Each string value of the field is its own bucket, and they +appear sorted alphabetically.

+ +

Bar chart reports a new table with three columns. The first column +contains the bucket name or smallest number. The second column contains +a nonnegative integer that says how many records in the input table fall +into this bucket. The third column is a subtable containing the actual +records from the original table that fall into the bucket. Plot bar +chart takes the table reported by bar chart and graphs it on the stage, +with axes labelled appropriately. The remaining blocks are helpers for +those.

+ +

If your buckets aren't of constant width, or you want to group by some +function of more than one field, load the "Frequency Distribution +Analysis" library instead.

+ +

The multi-branched conditional library has these blocks:

+ +

{width=ā€1.85inā€ +height=ā€2.479861111111111inā€}The catch and throw blocks duplicate ones +in the iteration library, and are included because they are used to +implement the others. The cases block sets up a multi-branch +conditional, similar to cond in Lisp or switch in C-family languages. +The first branch is built into the cases block; it consists of a Boolean +test in the first hexagonal slot and an action script, in the C-slot, to +be run if the test reports true. The remaining branches go in the +variadic hexagonal input at the end; each branch consists of an else if +block, which includes the Boolean test and the corresponding action +script, except possibly for the last branch, which can use the +unconditional else block. As in other languages, once a branch succeeds, +no other branches are tested.

+ +

###

+ +

The variadic library has these blocks:

+ +

{width=ā€1.1965277777777779inā€ +height=ā€0.4166666666666667inā€}These are versions of the associative +operators and, and or that take any number of inputs instead of exactly +two inputs. As with any variadic input, you can also drop a list of +values onto the arrowheads instead of providing the inputs one at a time +As of version 8.0, the arithmetic operators sum, product, minimum, and +maximum are no longer included, because the primitive operators +. Ɨ, +min, and max are themselves variadic.

+ +

{width=ā€7.277083333333334inā€ +height=ā€1.1027777777777779inā€}The colors and crayons library has these +blocks:

+ +

It is intended as a more powerful replacement for the primitive set pen +block, including first class color support; HSL color specification as +a better alternative to the HSV that Snap! inherits from JavaScript; a +ā€œfair hueā€ scale that compensates for the eyeā€™s grouping a wide range of +light frequencies as green while labelling mere slivers as orange or +yellow; the X11/W3C standard color names; RGB in hexadecimal; a linear +color scale (as in the old days, but better) based on fair hues and +including shades (darker colors) and grayscale. Another linear scale is +a curated set of 100 ā€œcrayons,ā€ explained further on the next page.

+ +

{width=ā€3.0590277777777777inā€ +height=ā€2.283333333333333inā€}{width=ā€1.1333333333333333inā€ +height=ā€0.23333333333333334inā€}{width=ā€0.95inā€ +height=ā€0.225inā€}Colors are created by the block (for direct user +selection), the color from block to specify a color numerically, or by , +which reports the color currently in use by the pen. The from color +block reports names or numbers associated with a color:

+ +

{width=ā€4.833333333333333inā€ +height=ā€0.4305555555555556inā€}Colors can be created from other colors:

+ +

The three blocks with pen in their names are improved versions of +primitive Pen blocks. In principle set pen, for example, could be +implemented using a (hypothetical) set pen to color composed with the +color from block, but in fact set pen benefits from knowing how the pen +color was set in its previous invocation, so itā€™s implemented separately +from color from. Details in Appendix A.

+ +

{width=ā€7.5inā€ +height=ā€0.25inā€}The recommended way to choose a color is from one of two +linear scales: the continuous color numbers and the discrete +crayons:

+ +

{width=ā€7.5inā€ height=ā€0.25inā€}

+ +

{width=ā€4.0inā€ +height=ā€0.20833333333333334inā€}Color numbers are based on fair hues, a +modification of the spectrum (rainbow) hue scale that devotes less space +to green and more to orange and yellow, as well as promoting brown to a +real color. Here is the normal hue scale, for reference:

+ +

{width=ā€4.0inā€ +height=ā€0.20833333333333334inā€}Here is the fair hue scale:

+ +

{width=ā€5.0inā€ +height=ā€0.20833333333333334inā€}Here is the color number scale:

+ +

(The picture is wider so that pure spectral colors line up with the fair +hue scale.)

+ +

{width=ā€5.0inā€ +height=ā€0.20833333333333334inā€}And here are the 100 crayons:

+ +

The color from block, for example, provides different pulldown menus +depending on which scale you choose:

+ +

{width=ā€2.4166666666666665inā€ +height=ā€0.34444444444444444inā€}{width=ā€7.070138888888889inā€ +height=ā€2.8673611111111112inā€}You can also type the crayon name: There +are many scales:

+ +

{width=ā€4.291666666666667inā€ +height=ā€1.9097222222222223inā€}

+ +

{width=ā€6.1506944444444445inā€ +height=ā€0.5347222222222222inā€} The white slot at the end of some of the +blocks has two purposes. It can be used to add a transparency to a color +(0=opaque, 100=transparent):

+ +

{width=ā€7.029861111111111inā€ +height=ā€0.4305555555555556inā€}or it can be expanded to enter three or +four numbers for a vector directly into the block, so these are +equivalent:

+ +

{width=ā€7.493055555555555inā€ +height=ā€0.4305555555555556inā€}But note that a transparency number in a +four-number RGBA vector is on the scale 255=opaque, 0=transparent, so +the following are not equivalent:

+ +

Set pen crayon to provides the equivalent of a box of 100 crayons. They +are divided into color groups, so the menu in the set pen crayon to +input slot has submenus. The colors are chosen so that starting +{width=ā€4.365277777777778inā€ +height=ā€0.5152777777777777inā€}from crayon 0, change pen crayon by 10 +rotates through an interesting, basic set of ten colors:

+ +

{width=ā€4.355555555555555inā€ +height=ā€0.28194444444444444inā€}Using change pen crayon by 5 instead +gives ten more colors, for a total of 20:

+ +

(Why didnā€™t we use the colors of the 100-crayon Crayolaā„¢ box? A few +reasons, one of which is that some Crayola colors arenā€™t representable +on RGB screens. Some year when you have nothing else to do, look up +ā€œcolor spaceā€ on Wikipedia. Also ā€œcrayon.ā€ Oh, itā€™s deliberate that +change pen crayon by 5 doesnā€™t include white, since thatā€™s the usual +stage background color. White is crayon 14.) Note that crayon 43 is +ā€œVariablesā€; all the standard block colors are included.

+ +

See Appendix A (page 139) for more information.

+ +

{width=ā€1.51inā€ +height=ā€0.9inā€}The crayon library has only the crayon features, +without the rest of the colors package.

+ +

The catch errors library has these blocks:

+ +

{width=ā€0.4305555555555556inā€ +height=ā€0.1527777777777778inā€}{width=ā€3.0416666666666665inā€ +height=ā€1.3958333333333333inā€}The safely try block allows you to handle +errors that happen when your program is run within the program, instead +of stopping the script with a red halo and an obscure error message. The +block runs the script in its first C-slot. If it finishes without an +error, nothing else happens. But if an error happens, the code in the +second C-slot is run. While that second script is running, the variable +contains the text of the error message that would have been displayed if +you werenā€™t catching the error. The error block is sort of the opposite: +it lets your program generate an error message, which will be +displayed with a red halo unless it is caught by safely try. Safely try +reporting is the reporter version of safely try.

+ +

The text costumes library has only two blocks:

+ +

{width=ā€0.5347222222222222inā€ +height=ā€0.20833333333333334inā€}{width=ā€1.92inā€ +height=ā€0.4507830271216098inā€}Costume from text reports a costume that +can be used with the switch to +{width=ā€3.2597222222222224inā€ +height=ā€0.18958333333333333inā€}costume block to make a button:

+ +

Costume with background reports a costume made from another costume by +coloring its background, taking a color input like the set pen color to +RGB(A) block and a number of turtle steps of padding around the original +costume. These two blocks work together to make even better buttons:

+ +

{width=ā€5.51inā€ height=ā€0.68inā€}

+ +

The text to speech library has these blocks:

+ +

{width=ā€2.275inā€ +height=ā€0.8inā€}This library interfaces with a capability in up-to-date +browsers, so it might not work for you. It works best if the accent +matches the text!

+ +

The parallelization library contains these blocks:

+ +

{width=ā€1.179861111111111inā€ +height=ā€1.2597222222222222inā€}The two do in parallel blocks take any +number of scripts as inputs. Those scripts will be run in parallel, like +ordinary independent scripts in the scripting area. The and wait version +waits until all of those scripts have finished before continuing the +script below the block.

+ +

{width=ā€1.3777777777777778inā€ +height=ā€1.4833333333333334inā€}The create variables library has these +blocks:

+ +

These blocks allow a program to perform the same operation as the

+ +

button, making global, sprite local, or script variables, but allowing +the program to compute the variable name(s). It can also set and find +the values of these variables, show and hide their stage watchers, +delete them, and find out if they already exist.

+ +

The getters and setters library has these blocks:

+ +

{width=ā€1.875inā€ +height=ā€1.05inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The purpose of this library is to allow +program access to the settings controlled by user interface elements, +such as the settings menu. The setting block reports a setting; the set +flag block sets yes-or-no options that have checkboxes in the user +interface, while the set value block controls settings with numeric or +text values, such as project name.

+ +

Certain settings are ordinarily remembered on a per-user basis, such as +the ā€œzoom blocksā€ value. But when these settings are changed by this +library, the change is in effect only while the project using the +library is loaded. No permanent changes are made. Note: this library has +not been converted for version 7.0, so youā€™ll have to enable Javascript +extensions to use it.

+ +

The bignums, rationals, complex #s library has these blocks:

+ +

{width=ā€1.875inā€ +height=ā€1.55inā€}The USE BIGNUMS block takes a Boolean input, to turn the +infinite precision feature on or off. When on, all of the arithmetic +operators are redefined to accept and report integers of any number of +digits (limited only by the memory of your computer) and, in fact, the +entire Scheme numeric tower, with exact rationals and with complex +numbers. The Scheme number block has a list of functions applicable to +Scheme numbers, including subtype predicates such as rational? and +infinite?, and selectors such as numerator and real-part.

+ +

{width=ā€4.836805555555555inā€ +height=ā€0.4166666666666667inā€}The ! block computes the factorial +function, useful to test whether bignums are turned on. Without bignums:

+ +

With bignums:

+ +

{width=ā€7.527083333333334inā€ +height=ā€0.36041666666666666inā€}The 375-digit value of 200! isnā€™t +readable on this page, but if you right-click on the block and choose +ā€œresult pic,ā€ you can open the resulting picture in a browser window and +scroll through it. (These values end with a bunch of zero digits. Thatā€™s +not roundoff error; the prime factors of 100! and 200! include many +copies of 2 and 5.) The block with no name is a way to enter things like +3/4 and 4+7i into numeric input slots by converting the slot to Any +type.

+ +

The strings, multi-line input library provides these blocks:

+ +

{width=ā€3.9375inā€ +height=ā€2.0416666666666665inā€}All of these could be written in Snap! +itself, but these are implemented using the corresponding JavaScript +library functions directly, so they run fast. They can be used, for +example, in scraping data from a web site. The command use +case-independent comparisons applies only to this library. The multiline +block accepts and reports a text input that can include newline +characters.

+ +

The animation library has these blocks:

+ +

{width=ā€4.0125inā€ +height=ā€2.33125inā€}Despite the name, this isnā€™t only about graphics; you +can animate the values of a variable, or anything else thatā€™s expressed +numerically.

+ +

{width=ā€0.9652777777777778inā€ +height=ā€0.19444444444444445inā€}The central idea of this library is an +easing function, a reporter whose domain and range are real numbers +between 0 and 1 inclusive. The function represents what fraction of the +ā€œdistanceā€ (in quotes because it might be any numeric value, such as +temperature in a simulation of weather) from here to there should be +covered in what fraction of the time. A linear easing function means +steady progression. A quadratic easing function means starting slowly +and accelerating. (Note that, since itā€™s a requirement that f(0)=0 and +f(1)=1, there is only one linear easing function, f(x)=x, and +similarly for other categories.) The block reports some of the common +easing functions.

+ +

{width=ā€4.631944444444445inā€ +height=ā€0.6319444444444444inā€}The two Motion blocks in this library +animate a sprite. Glide always animates the spriteā€™s motion. Animateā€™s +first pulldown menu input allows you to animate horizontal or vertical +motion, but will also animate the spriteā€™s direction or size. The +animate block in Control lets you animate any numeric quantity with any +easing function. The getter and setter inputs are best explained by +example:

+ +

{width=ā€3.4097222222222223inā€ +height=ā€0.2569444444444444inā€}is equivalent to

+ +

The other blocks in the library are helpers for these four.

+ +

The serial ports library contains these blocks:

+ +

{width=ā€1.7326388888888888inā€ +height=ā€1.0347222222222223inā€}It is used to allow hardware developers to +control devices such as robots that are

+ +

connected to your computer via a serial port.

+ +

The frequency distribution analysis library has these blocks:

+ +

{width=ā€4.027083333333334inā€ +height=ā€2.3958333333333335inā€}

+ +

This is a collection of tools for analyzing large data sets and plotting +histograms of how often some value is found in some column of the table +holding the data.

+ +

For more information go here:

+ +

http://tinyurl.com/jens-data

+ +

The audio comp library includes these blocks:

+ +

{width=ā€3.5416666666666665inā€ +height=ā€2.98125inā€}This library takes a sound, one that you record or +one from our collection of sounds, and manipulates it by systematically +changing the intensity of the samples in the sound and by changing the +sampling rate at which the sound is reproduced. Many of the blocks are +helpers for the plot sound block, used to plot the waveform of a sound. +The play sound (primitive) block plays a sound. __ Hz for reports a +sine wave as a list of samples.

+ +

The web services library has these blocks:

+ +

{width=ā€3.4097222222222223inā€ +height=ā€1.1041666666666667inā€}The first block is a generalization of the +primitive url block, allowing more control over the various options in +web requests: GET, POST, PUT, and DELETE, and fine control over the +content of the message sent to the server. Current location reports your +latitude and longitude. Listify takes some text in JSON format (see page +54) and converts it to a structured list. Value at key looks up a +key-value pair in a (listified) JSON dictionary. The key:value: block is +just a constructor for an abstract data type used with the other blocks

+ +

The database library contains these blocks:

+ +

{width=ā€2.263888888888889inā€ +height=ā€1.2222222222222223inā€}It is used to keep data that persist from +one Snap! session to the next, if you use the same browser and the +same login.

+ +

The world map library has these blocks:

+ +

{width=ā€2.442361111111111inā€ +height=ā€3.4027777777777777inā€}Using any of the command blocks puts a map +on the screen, in a layer in front of the stageā€™s background but behind +the pen trails layer (which is in turn behind all the sprites). The +first block asks your browser for your current physical location, for +which you may be asked to give permission. The next two blocks get and +set the mapā€™s zoom amount; the default zoom of 10 ļ¬ts from San Francisco +not quite down to Palo Alto on the screen. A zoom of 1 ļ¬ts almost the +entire world. A zoom of 3 fits the United States; a zoom of 5 ļ¬ts +Germany. The zoom can be changed in half steps, i.e., 5.5 is different +from 5, but 5.25 isnā€™t.

+ +

The next five blocks convert between stage coordinates (pixels) and +Earth coordinates (latitude and longitude). The change by x: y: block +shifts the map relative to the stage. The distance to block measures the +map distance (in meters) between two sprites. The three reporters with +current in their names find your actual location, again supposing that +geolocation is enabled on your device. Update redraws the map; as +costume reports the visible section of the map as a costume. Set style +allows things like satellite pictures.

+ +

The APL primitives library contains these blocks:

+ +

{width=ā€5.733333333333333inā€ +height=ā€1.1133333333333333inā€}

+ +

{width=ā€6.453333333333333inā€ +height=ā€2.04inā€}

+ +

For more information about APL, see Appendix B (page 148).

+ +

The {width=ā€1.2inā€ +height=ā€0.4895833333333333inā€}list comprehension library has one +block, zip. Its first input is a function of two inputs. The two +Any-type inputs are deep lists (lists of lists ofā€¦) interpreted as +trees, and the function is called with every possible combination of a +leaf node of the first tree and a leaf node of the second tree. But +instead of taking atoms (non-lists) as the leaves, zip allows the leaves +of each tree to be vectors (one-dimensional lists), matrices +(two-dimensional lists), etc. The Number-type inputs specify the leaf +dimension for each tree, so the function input might be called with a +vector from the first tree and an atom from the second tree.

+ +

{width=ā€0.89inā€ +height=ā€1.51inā€}The bitwise library provides bitwise logic +functions; each bit of the reported value is the result of applying the +corresponding Boolean function to the corresponding bits of the +input(s). The Boolean functions are not for Ā¬, and for āˆ§, or for āˆØ, and +xor (exclusive or) for āŠ». The remaining functions shift their first +input left or right by the number of bits given by the second input. +<< is left shift, >> is arithmetic right shift (shifting in one bits +from the left), and >>> is logical right shift (shifting in zero bits +from the left). If you donā€™t already know what these mean, find a +tutorial online.

+ +

{width=ā€6.528977471566054inā€ +height=ā€1.6097222222222223inā€}

+ +

The MQTT library supports the Message Queuing Telemetry Transport +protocol, for connecting with IOT devices. See https://mqtt.org/ for +more information.

+ +

{width=ā€4.986805555555556inā€ +height=ā€2.8895833333333334inā€}The Signada library allows you to +control a microBit or similar device that works with the Signada +MicroBlocks project.

+ +

{width=ā€3.39inā€ height=ā€1.9inā€}

+ +

The menus library provides the ability to display hierarchical menus +on the stage, using the ask blockā€™s ability to take lists as inputs. See +page 24.

+ +

The SciSnap! library and the TuneScope library are too big to +discuss here and are documented separately at +http://emu-online.de/ProgrammingWithSciSnap.pdf and +https://maketolearn.org/creating-art-animations-and-music/ +respectively.

+ +

Saving and Loading Projects and Media

+ +

After youā€™ve created a project, youā€™ll want to save it, so that you can +have access to it the next time you use Snap!. There are two ways to +do that. You can save a project on your own computer, or you can save it +at the Snap! web site. The advantage of saving on the net is that you +have access to your project even if you are using a different computer, +or a mobile device such as a tablet or smartphone. The advantage of +saving on your computer is that you have access to the saved project +while on an airplane or otherwise not on the net. Also, cloud projects +are limited in size, but you can have all the costumes and sounds you +like if you save locally. This is why we have multiple ways to save.

+ +

{width=ā€3.548611111111111inā€ +height=ā€2.576388888888889inā€}In either case, if you choose ā€œSave asā€¦ā€ +from the File menu. Youā€™ll see something like this:

+ +

(If you are not logged in to your Snap! cloud account, Computer will +be the only usable option.) The text box at the bottom right of the Save +dialog allows you to enter project notes that are saved with the +project.

+ +

Local Storage

+ +

Click on Computer and Snap!ā€™s Save Project dialog window will be +replaced by your operating systemā€™s standard save window. If your +project has a name, that name will be the default filename if you donā€™t +give a different name. Another, equivalent way to save to disk is to +choose ā€œExport projectā€ from the File menu.

+ +

{width=ā€1.2340277777777777inā€ height=ā€2.329861111111111inā€}Creating a Cloud Account

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The other possibility is to save your +project ā€œin the cloud,ā€ at the Snap! web site. In order to do this, +you need an account with us. Click on the Cloud button ( ) in the Tool +Bar. Choose the ā€œSignupā€¦ā€ option. This will show you a window that +looks like the picture at the right.

+ +

You must choose a user name that will identify you on the web site, such +as Jens or bh. If youā€™re a Scratch user, you can use your Scratch name +for Snap! too. If youā€™re a kid, donā€™t pick a user name that includes +your family name, but first names or initials are okay. Donā€™t pick +something youā€™d be embarrassed to have other users (or your parents) +see! If the name you want is already taken, youā€™ll have to choose +another one. You must also supply a password.

+ +

We ask for your month and year of birth; we use this information only to +decide whether to ask for your own email address or your parentā€™s email +address. (If youā€™re a kid, you shouldnā€™t sign up for anything on the +net, not even Snap!, without your parentā€™s knowledge.) We do not store +your birthdate information on our server; it is used on your own +computer only during this initial signup. We do not ask for your exact +birthdate, even for this one-time purpose, because thatā€™s an important +piece of personally identifiable information.

+ +

When you click OK, an email will be sent to the email address you gave, +asking you to verify (by clicking a link) that itā€™s really your email +address. We keep your email address on file so that, if you forget your +password, we can send you a password-reset link. We will also email you +if your account is suspended for violation of the Terms of Service. We +do not use your address for any other purpose. You will never receive +marketing emails of any kind through this site, neither from us nor from +third parties. If, nevertheless, you are worried about providing this +information, do a web search for ā€œtemporary email.ā€

+ +

Finally, you must read and agree to the Terms of Service. A quick +summary: Donā€™t interfere with anyone elseā€™s use of the web site, and +donā€™t put copyrighted media or personally identifiable information in +projects that you share with other users. And weā€™re not responsible if +something goes wrong. (Not that we expect anything to go wrong; since +Snap! runs in JavaScript in your browser, it is strongly isolated from +the rest of your computer. But the lawyers make us say this.)

+ +

Saving to the Cloud

+ +

Once youā€™ve created your account, you can log into it using the +ā€œLoginā€¦ā€ option from the Cloud menu:

+ +

{width=ā€1.6875inā€ +height=ā€2.0277777777777777inā€}Use the user name and password that you +set up earlier. If you check the ā€œStay signed inā€ box, then you will be +logged in automatically the next time you run Snap! from the same +browser on the same computer. Check the box if youā€™re using your own +computer and you donā€™t share it with siblings. Donā€™t check the box if +youā€™re using a public computer at the library, at school, etc.

+ +

Once logged in, you can choose the ā€œCloudā€ option in the ā€œSave Projectā€ +dialog shown on page 37. You enter a project name, and optionally +project notes; your project will be saved online and can be loaded from +anywhere with net access. The project notes will be visible to other +users if you publish your project.

+ +

Loading Saved Projects

+ +

Once youā€™ve saved a project, you want to be able to load it back into +Snap!. There are two ways to do this:

+ +

1. If you saved the project in your online Snap! account, choose the +ā€œOpenā€¦ā€ option from the File menu. Choose the ā€œCloudā€ button, then +select your project from the list in the big text box and click OK, or +choose the ā€œComputerā€ button to open an operating system open dialog. (A +third button, ā€œExamples,ā€ lets you choose from example projects that we +provide. You can see what each of these projects is about by clicking on +it and reading its project notes.)

+ +

2. If you saved the project as an XML file on your computer, choose +ā€œImportā€¦ā€ from the File menu. This will give you an ordinary browser +file-open window, in which you can navigate to the file as you would in +other software. Alternatively, find the XML file on your desktop, and +just drag it onto the Snap! window.

+ +

The second technique above also allows you to import media (costumes and +sounds) into a project. Just choose ā€œImportā€¦ā€ and then select a +picture or sound file instead of an XML file.

+ +

Snap! can also import projects created in BYOB 3.0 or 3.1, or (with +some effort; see our web site) in Scratch 1.4, 2.0 or 3.0. Almost all +such projects work correctly in Snap!, apart from a small number of +incompatible blocks.

+ +

If you saved projects in an earlier version of Snap! using the +ā€œBrowserā€ option, then a Browser button will be shown in the Open dialog +to allow you to retrieve those projects. But you can save them only with +the Computer and Cloud options.

+ +

If you lose your project, do this first!

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}If you are still in Snap! and +realize that youā€™ve loaded another project without saving the one you +were working on: Donā€™t edit the new project. From the File menu +choose the Restore unsaved project option.

+ +

Restore unsaved project will also work if you log out of Snap! and +later log back in, as long as you donā€™t edit another project meanwhile. +Snap! remembers only the most recent project that youā€™ve edited (not +just opened, but actually changed in the project editor).

+ +

If your project on the cloud is missing, empty, or otherwise broken and +isnā€™t the one you edited most recently, or if Restore unsaved project +fails: Donā€™t edit the broken project. In the Openā€¦ box, enter +your project name, then push the Recover button. Do this right away, +because we save only the version before the most recent, and the latest +before today. So donā€™t keep saving bad versions; Recover right away. The +Recover feature works only on a project version that you actually saved, +so Restore unsaved project is your first choice if you switch away from +a project without saving it.

+ +

To help you remember to save your projects, when youā€™ve edited the +project and havenā€™t yet saved it, Snap! displays a pencil icon to the +left of the project name on the toolbar at the top of the window:

+ +

{width=ā€6.29671697287839inā€ +height=ā€0.5138888888888888inā€}

+ +

Private and Public Projects

+ +

By default, a project you save in the cloud is private; only you can see +it. There are two ways to make a project available to others. If you +share a project, you can give your friends a project URL (in your +browserā€™s URL bar after you open the project) they can use to read it. +If you publish a project, it will appear on the Snap! web site, and +the whole world can see it. In any case, nobody other than you can ever +overwrite your project; if others ask to save it, they get their own +copy in their own account.

+ +

Building a Block

+ +

The first version of Snap! was called BYOB, for ā€œBuild Your Own +Blocks.ā€ This was the first and is still the most important capability +we added to Scratch. (The name was changed because a few teachers have +no sense of humor. ā˜¹ You pick your battles.) Scratch 2.0 and later also +has a partial custom block capability.

+ +

Simple Blocks

+ +

{width=ā€7.5inā€ +height=ā€2.7152777777777777inā€}In every palette, at or near the bottom, +is a button labeled ā€œMake a block.ā€ Also, floating near the top of the +palette is a plus sign. Also, the menu you get by right-clicking on the +background of the scripting area has a ā€œmake a blockā€ option.

+ +

{width=ā€2.2708333333333335inā€ +height=ā€2.3472222222222223inā€}Clicking any of these will display a +dialog window in which you choose the blockā€™s name, shape, and +palette/color. You also decide whether the block will be available to +all sprites, or only to the current sprite and its children.

+ +

In this dialog box, you can choose the block's palette, shape, and +name. With one exception, there is one color per palette, e.g., all +Motion blocks are blue. But the Variables palette includes the orange +variable-related blocks and the red list-related blocks. Both colors are +available, along with an ā€œOtherā€ option that makes grey blocks in the +Variables palette for blocks that donā€™t fit any category.

+ +

There are three block shapes, following a convention that should be +familiar to Scratch users: The jigsaw-puzzle-piece shaped blocks are +Commands, and donā€™t report a value. The oval blocks are Reporters, and +the hexagonal blocks are Predicates, which is the technical term for +reporters that report Boolean (true or false) values.

+ +

Suppose you want to make a block named ā€œsquareā€ that draws a square. You +would choose Motion, Command, and type ā€œsquareā€ into the name field. +When you click OK, you enter the Block Editor. This works just like +making a script in the spriteā€™s scripting area, except that the ā€œhatā€ +block at the top, instead of saying something like ā€œwhen I am clicked,ā€ +has a picture of the block youā€™re building. This hat block is called the +prototype of your custom block.3 You drag blocks under the hat to +program your custom block, then click OK:

+ +

{width=ā€4.210937226596675inā€ +height=ā€1.3364041994750657inā€}

+ +

{width=ā€4.615555555555556inā€ +height=ā€3.647777777777778inā€}

+ +

Your block appears at the bottom of the Motion palette. Hereā€™s the block +and the result of using it:

+ +

{width=ā€4.242361111111111inā€ +height=ā€1.4166666666666667inā€}

+ +

Custom Blocks with Inputs

+ +

But suppose you want to be able to draw squares of different sizes. +Control-click or right-click on the block, choose ā€œedit,ā€ and the Block +Editor will open. Notice the plus signs before and after the word square +in the prototype block. If you hover the mouse over one, it lights up:

+ +

{width=ā€3.4444444444444446inā€ +height=ā€2.7222222222222223inā€}

+ +

{width=ā€2.5833333333333335inā€ +height=ā€1.6041666666666667inā€}Click on the plus on the right. You will +then see the ā€œinput nameā€ dialog:

+ +

Type in the name ā€œsizeā€ and click OK. There are other options in this +dialog; you can choose ā€œtitle textā€ if you want to add words to the +block name, so it can have text after an input slot, like the ā€œmove ( ) +stepsā€ block. Or you can select a more extensive dialog with a lot of +options about your input name. But weā€™ll leave that for later. When you +click OK, the new input appears in the block prototype:

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.4895833333333333inā€}You can now drag the orange variable down +into the script, then click okay:

+ +

{width=ā€1.474724409448819inā€ +height=ā€1.495495406824147inā€}

+ +

{width=ā€0.6979166666666666inā€ +height=ā€0.25inā€}Your block now appears in the Motion palette with an +input box: You can draw any size square by entering the length of its +side in the box and running the block as usual, by clicking it or by +putting it in a script.

+ +

Editing Block Properties

+ +

{width=ā€0.9993055555555556inā€ +height=ā€0.7604166666666666inā€}What if you change your mind about a +blockā€™s color (palette) or shape (command, reporter, predicate)? If you +click in the hat block at the top that holds the prototype, but not in +the prototype itself, youā€™ll see a window in which you can change the +color, and sometimes the shape, namely, if the block is not used in +any script, whether in a scripting area or in another custom block. +(This includes a one-block script consisting of a copy of the new block +pulled out of the palette into the scripting area, seeing which made you +realize itā€™s the wrong category. Just delete that copy (drag it back to +the palette) and then change the category.)

+ +

If you right-click/control-click the hat block, you get this menu:

+ +

Script pic exports a picture of the script. (Many of the illustrations +in this manual were made that way.) Translations opens a window in which +you can specify how your block should be translated if the user chooses +a language other than the one in which you are programming. Block +variables lets you create a variant of script variables for this block: +A script variable is created when a block is called, and it disappears +when that call finishes. What if you want a variable thatā€™s local to +this block, as a script variable is, but doesnā€™t disappear between +invocations? Thatā€™s a block variable. If the definition of a block +includes a block variable, then every time that (custom) block is +dragged from the palette into a script, the block variable is created. +Every time that copy of the block is called, it uses the same block +variable, which preserves its value between calls. Other copies of the +block have their own block variables. The in palette checkbox determines +whether or not this block will be visible in the palette. Itā€™s normally +checked, but you may want to hide custom blocks if youā€™re a curriculum +writer creating a Parsons problem. To unhide blocks, choose ā€œHide +blocksā€ from the File menu and uncheck the checkboxes. Edit does the +same thing as regular clicking, as described earlier.

+ +

Recursion

+ +

{width=ā€2.9652777777777777inā€ +height=ā€2.3631944444444444inā€}{width=ā€1.9583333333333333inā€ +height=ā€2.3541666666666665inā€}{width=ā€1.4236111111111112inā€ +height=ā€0.9118055555555555inā€}Since the new custom block appears in its +palette as soon as you start editing it, you can write recursive +blocks (blocks that call themselves) by dragging the block into its own +definition:

+ +

(If you added inputs to the block since opening the editor, click Apply +before finding the block in the palette, or drag the block from the top +of the block editor rather than from the palette.)

+ +

If recursion is new to you, here are a few brief hints: Itā€™s crucial +that the recursion have a base case, that is, some small(est) case +that the block can handle without using recursion. In this example, itā€™s +the case depth=0, for which the block does nothing at all, because of +the enclosing if. Without a base case, the recursion would run forever, +calling itself over and over.

+ +

Donā€™t try to trace the exact sequence of steps that the computer follows +in a recursive program. Instead, imagine that inside the computer there +are many small people, and if Theresa is drawing a tree of size 100, +depth 6, she hires Tom to make a tree of size 70, depth 5, and later +hires Theo to make another tree of size 70, depthĀ 5. Tom in turn hires +Tammy and Tallulah, and so on. Each little person has his or her own +local variables size and depth, each with different values.

+ +

{width=ā€4.8380686789151355inā€ +height=ā€1.5833333333333333inā€}You can also write recursive reporters, +like this block to compute the factorial function:

+ +

Note the use of the report block. When a reporter block uses this block, +the reporter finishes its work and reports the value given; any further +blocks in the script are not evaluated. Thus, the if else block in the +script above could have been just an if, with the second report block +below it instead of inside it, and the result would be the same, because +when the ļ¬rst report is seen in the base case, that finishes the block +invocation, and the second report is ignored. There is also a stop this +block block that has a similar purpose, ending the block invocation +early, for command blocks. (By contrast, the stop this script block +stops not only the current block invocation, but also the entire +toplevel script that called it.)

+ +

{width=ā€4.291666666666667inā€ +height=ā€0.8645833333333334inā€}Hereā€™s a slightly more compact way to +write the factorial function:

+ +

For more on recursion, see Thinking Recursively by Eric Roberts. (The +original edition is ISBN 978ā€‘0471816522; a more recent Thinking +Recursively in Java is ISBN 978-0471701460.)

+ +

Block Libraries

+ +

When you save a project (see Chapter II above), any custom blocks youā€™ve +made are saved with it. But sometimes youā€™d like to save a collection of +blocks that you expect to be useful in more than one project. Perhaps +your blocks implement a particular data structure (a stack, or a +dictionary, etc.), or theyā€™re the framework for building a multilevel +game. Such a collection of blocks is called a block library.

+ +

*
+*To create a block library, choose ā€œExport blocksā€¦ā€ from the File +menu. You then see a window like this:

+ +

{width=ā€2.0215277777777776inā€ +height=ā€2.7222222222222223inā€}The window shows all of your global custom +blocks. You can uncheck some of the checkboxes to select exactly which +blocks you want to include in your library. (You can right-click or +control-click on the export window for a menu that lets you check or +uncheck all the boxes at once.) Then press OK. An XML file containing +the blocks will appear in your Downloads location.

+ +

To import a block library, use the ā€œImportā€¦ā€ command in the File menu, +or just drag the XML file into the Snap! window.

+ +

Several block libraries are included with Snap!; for details about +them, see page 25.

+ +

Custom blocks and Visible Stepping

+ +

Visible stepping normally treats a call to a custom block as a single +step. If you want to see stepping inside a custom block you must take +these steps in order:

+ +
    +
  1. +

    {width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Turn on Visible Stepping.

    +
  2. +
  3. +

    Select ā€œEditā€ in the context menu(s) of the block(s) you want to +examine.

    +
  4. +
  5. +

    Then start the program.

    +
  6. +
+ +

The Block Editor windows you open in step 2 do not have full editing +capability. You can tell because there is only one ā€œOKā€ button at the +bottom, not the usual three buttons. Use the button to close these +windows when done stepping.

+ +

First class lists

+ +

A data type is ļ¬rst class in a programming language if data of that +type can be

+ + + +

In Scratch, numbers and text strings are ļ¬rst class. You can put a +number in a variable, use one as the input to a block, call a reporter +that reports a number, or put a number into a list.

+ +

But Scratchā€™s lists are not ļ¬rst class. You create one using the ā€œMake a +listā€ button, which requires that you give the list a name. You canā€™t +put the list into a variable, into an input slot of a block, or into a +list itemā€”you canā€™t have lists of lists. None of the Scratch reporters +reports a list value. (You can use a reduction of the list into a text +string as input to other blocks, but this loses the list structure; the +input is just a text string, not a data aggregate.)

+ +

A fundamental design principle in Snap! is that [all data should be +ļ¬rst class]{.underline}. If itā€™s in the language, then we should be +able to use it fully and freely. We believe that this principle avoids +the need for many special-case tools, which can instead be written by +Snap! users themselves.

+ +

{width=ā€2.839583333333333inā€ +height=ā€0.41597222222222224inā€}Note that itā€™s a data type thatā€™s ļ¬rst +class, not an individual value. Donā€™t think, for example, that some +lists are ļ¬rst class, while others arenā€™t. In Snap!, lists are ļ¬rst +class, period.

+ +

The list Block

+ +

At the heart of providing first class lists is the ability to make an +ā€œanonymousā€ listā€”to make a list without simultaneously giving it a +name. The list reporter block does that.

+ +

{width=ā€4.2inā€ +height=ā€1.5694444444444444inā€}At the right end of the block are two +left-and-right arrowheads. Clicking on these changes the number of +inputs to list, i.e., the number of elements in the list you are +building. Shift-clicking changes by three at a time.

+ +

{width=ā€1.5034722222222223inā€ +height=ā€1.8125inā€}{width=ā€2.24375inā€ +height=ā€0.3215277777777778inā€}You can use this block as input to many +other blocks:

+ +

{width=ā€3.09375inā€ +height=ā€0.7708333333333334inā€}{width=ā€1.8229166666666667inā€ +height=ā€0.2916666666666667inā€}Snap! does not have a ā€œMake a listā€ +button like the one in Scratch. If you want a global ā€œnamed list,ā€ make +a global variable and use the set block to put a list into the variable.

+ +

Lists of Lists

+ +

{width=ā€5.888888888888889inā€ +height=ā€1.0486111111111112inā€}Lists can be inserted as elements in +larger lists. We can easily create ad hoc structures as needed:

+ +

Notice that this list is presented in a different format from the ā€œShe +Loves Youā€ list above. A two-dimensional list is called a table and is +by default shown in table view. Weā€™ll have more to say about this +later.

+ +

{width=ā€7.343055555555556inā€ +height=ā€2.78125inā€}We can also build any classic computer science data +structure out of lists of lists, by defining constructors (blocks to +make an instance of the structure), selectors (blocks to pull out a +piece of the structure), and mutators (blocks to change the contents +of the structure) as needed. Here we create binary trees with selectors +that check for input of the correct data type; only one selector is +shown but the ones for left and right children are analogous.

+ +

Functional and Imperative List Programming

+ +

{width=ā€2.1041666666666665inā€ +height=ā€1.09375inā€} There are two ways to create a list inside a +program. Scratch users will be familiar with the imperative +programming style, which is based on a set of command blocks that modify +a list:

+ +

As an example, here are two blocks that take a list of numbers as input, +and report a new list containing only the even numbers from the original +list:4

+ +

{width=ā€5.892361111111111inā€ +height=ā€2.28125inā€}

+ +

or

+ +

In this script, we first create a temporary variable, then put an empty +list in it, then go through the items of the input list using the add +ā€¦ to (result) block to modify the result list, adding one item at +a time, and finally report the result.

+ +

{width=ā€1.5625inā€ +height=ā€0.8104166666666667inā€}Functional programming is a different +approach that is becoming important in ā€œreal worldā€ programming because +of parallelism, i.e., the fact that different processors can be +manipulating the same data at the same time. This makes the use of +mutation (changing the value associated with a variable, or the items of +a list) problematic because with parallelism itā€™s impossible to know the +exact sequence of events, so the result of mutation may not be what the +programmer expected. Even without parallelism, though, functional +programming is sometimes a simpler and more effective technique, +especially when dealing with recursively defined data structures. It +uses reporter blocks, not command blocks, to build up a list value:

+ +

In a functional program, we often use recursion to construct a list, one +item at a time. The in front of block makes a list that has one item +added to the front of an existing list, without changing the value of +the original list. A nonempty list is processed by dividing it into its +first item (item 1 of) and all the rest of the items (all but first of), +which are handled through a recursive call:

+ +

{width=ā€4.75inā€ +height=ā€2.240972222222222inā€}Snap! uses two different internal +representations of lists, one (dynamic array) for imperative programming +and the other (linked list) for functional programming. Each +representation makes the corresponding built-in list blocks (commands or +reporters, respectively) most efficient. Itā€™s possible to mix styles in +the same program, but if the same list is used both ways, the program +will run more slowly because it converts from one representation to the +other repeatedly. (The item ( ) of [ ] block doesnā€™t change the +representation.) You donā€™t have to know the details of the internal +representations, but itā€™s worthwhile to use each list in a consistent +way.

+ +

{width=ā€5.864583333333333inā€ height=ā€1.0715277777777779inā€}Higher Order List Operations and Rings

+ +

Thereā€™s an even easier way to select the even numbers from a list:

+ +

{width=ā€2.375inā€ +height=ā€0.2777777777777778inā€}The keep block takes a Predicate +expression as its first input, and a list as its second input. It +reports a list containing those elements of the input list for which the +predicate returns true. Notice two things about the predicate input: +First, it has a grey ring around it. Second, the mod block has an empty +input. Keep puts each item of its input list, one at a time, into that +empty input before evaluating the predicate. (The empty input is +supposed to remind you of the ā€œboxā€ notation for variables in elementary +school: ā˜+3=7.) The grey ring is part of the keep block as it appears in +the palette:

+ +

{width=ā€4.1402777777777775inā€ +height=ā€0.6354166666666666inā€}What the ring means is that this input is +a block (a predicate block, in this case, because the interior of the +ring is a hexagon), rather than the value reported by that block. Hereā€™s +the difference:

+ +

Evaluating the = block without a ring reports true or false; evaluating +the block with a ring reports the block itself. This allows keep to +evaluate the = predicate repeatedly, once for each list item. A block +that takes another block as input is called a higher order block (or +higher order procedure, or higher order function).

+ +

{width=ā€2.39inā€ +height=ā€0.22inā€}{width=ā€1.6944444444444444inā€ +height=ā€0.9930555555555556inā€} Snap! provides four higher order +function blocks for operating on lists:

+ +

{width=ā€7.5inā€ +height=ā€1.7138888888888888inā€}Youā€™ve already seen keep. Find first is +similar, but it reports just the first item that satisfies the +predicate, not a list of all the matching items. Itā€™s equivalent to but +faster because it

+ +

stops looking as soon as it finds a match. If there are no matching +items, it returns an empty string.

+ +

{width=ā€7.589583333333334inā€ +height=ā€1.0791666666666666inā€}

+ +

{width=ā€7.486111111111111inā€ +height=ā€1.0020833333333334inā€}These examples use small lists, to fit the +page, but the higher order blocks work for any size list.

+ +

An empty gray ring represents the identity function, which just +reports its input. Leaving the ring in map empty is the most concise way +to make a shallow copy of a list (that is, in the case of a list of +lists, the result is a new toplevel list whose items are the same +(uncopied) lists that are items of the toplevel input list). To make a +deep copy of a list (that is, one in which all the sublists, sublists of +sublists, etc. are copied), use the list as input to the Macintosh
+HD:Users:bh:Desktop:id.png{width=ā€0.7430555555555556inā€ +height=ā€0.19444444444444445inā€} block (one of the variants of the sqrt +of block). This works because id of is a hyperblock (page 55).

+ +

{width=ā€5.5800503062117235inā€ +height=ā€0.4623108048993876inā€}The third higher order block, combine, +computes a single result from all the items of a list, using a +two-input reporter as its second input. In practice, there are only a +few blocks youā€™ll ever use with combine:

+ +

These blocks take the sum of the list items, take their product, string +them into one word, combine them into a sentence (with spaces between +items), see if all items of a list of Booleans are true, see if any of +the items is true, find the smallest, or find the largest.

+ +

{width=ā€6.279166666666667inā€ +height=ā€0.37569444444444444inā€}{width=ā€3.8680555555555554inā€ +height=ā€0.3451388888888889inā€}Why + but not āˆ’? It only makes sense to +combine list items using an associative function: one that doesnā€™t +care in what order the items are combined (left to right or right to +left). (2+3)+4 = 2+(3+4), but (2āˆ’3)āˆ’4 ā‰  2āˆ’(3āˆ’4).

+ +

{width=ā€5.808333333333334inā€ +height=ā€1.1909722222222223inā€}The functions map, keep, and find first +have an advanced mode with rarely-used features: If their function input +is given explicit input names (by clicking the arrowhead at the right +end of the gray ring; see page 69), then it will be called for each list +item with three inputs: the itemā€™s value (as usual), the itemā€™s +position in the input list (its index), and the entire input list. No +more than three input names can be used in this contex

+ +

{#section-2 .ListParagraph}

+ +

Table View vs. List View

+ +

{width=ā€3.0993055555555555inā€ +height=ā€2.513888888888889inā€}We mentioned earlier that there are two +ways of representing lists visually. For one-dimensional lists (lists +whose items are not themselves lists) the visual differences are small:

+ +

For one-dimensional lists, itā€™s not really the appearance thatā€™s +important. What matters is that the list view allows very versatile +direct manipulation of the list through the picture: you can edit the +individual items, you can delete items by clicking the tiny buttons next +to each item, and you can add new items at the end by clicking the tiny +plus sign in the lower left corner. (You can just barely see that the +item deletion buttons have minus signs in them.) Even if you have +several watchers for the same list, all of them will be updated when you +change anything. On the other hand, this versatility comes at an +efficiency cost; a list view watcher for a long list would be way too +slow. As a partial workaround, the list view can only contain 100 items +at a time; the downward-pointing arrowhead opens a menu in which you can +choose which 100 to display.

+ +

{width=ā€1.2555555555555555inā€ +height=ā€0.9125inā€}

+ +

By contrast, because it doesnā€™t allow direct editing, the table view +watcher can hold hundreds of thousands of items and still scroll through +them efficiently. The table view has flatter graphics for the items to +remind you that theyā€™re not clickable to edit the values.

+ +

Right-clicking on a list watcher (in either form) gives you the option +to switch to the other form. The right-click menu also offers an open in +dialogā€¦ option that opens an offstage table view watcher, because +the watchers can take up a lot of stage space that may make it hard to +see what your program is actually doing. Once the offstage dialog box is +open, you can close the stage watcher. Thereā€™s an OK button on the +offstage dialog to close it if you want. Or you can right-click it to +make another offstage watcher, which is useful if you want to watch +two parts of the list at once by having each watcher scrolled to a +different place.

+ +

{width=ā€5.888888888888889inā€ +height=ā€1.0486111111111112inā€}Table view is the default if the list has +more than 100 items, or if any of the first ten items of the list are +lists, in which case it makes a very different-looking two-dimensional +picture:

+ +

In this format, the column of red items has been replaced by a +spreadsheet-looking display. For short, wide lists, this display makes +the content of the list very clear. A vertical display, with much of the +space taken up by the ā€œmachineryā€ at the bottom of each sublist, would +make it hard to show all the text at once. (The pedagogic cost is that +the structure is no longer explicit; we canā€™t tell just by looking that +this is a list of row-lists, rather than a list of column-lists or a +primitive two-dimensional array type. But you can choose list view to +see the structure.)

+ +

Beyond such simple cases, in which every item of the main list is a list +of the same length, itā€™s important to keep in mind that the design of +table view has to satisfy two goals, not always in agreement: (1) a +visually compelling display of two-dimensional arrays, and (2) highly +efficient display generation, so that Snap! can handle very large +lists, since ā€œbig dataā€ is an important topic of study. To meet the +first goal perfectly in the case of ā€œragged rightā€ arrays in which +sublists can have different lengths, Snap! would scan the entire list +to find the maximum width before displaying anything, but that would +violate the second goal.

+ +

Snap! uses the simplest possible compromise between the two goals: It +examines only the first ten items of the list to decide on the format. +If none of those are lists, or theyā€™re all lists of one item, and the +overall length is no more than 100, list view is used. If the any of +first ten items is a list, then table view is used, and the number of +columns in the table is equal to the largest number of items among the +first ten items (sublists) of the main list.

+ +

Table views open with standard values for the width and height of a +cell, regardless of the actual data. You can change these values by +dragging the column letters or row numbers. Each column has its own +width, but changing the height of a row changes the height for all rows. +(This distinction is based not on the semantics of rows vs. columns, but +on the fact that a constant row height makes scrolling through a large +list more efficient.) Shift-dragging a column label will change the +width of that column.

+ +

If you tried out the adjustments in the previous paragraph, you may have +noticed that a column letter turns into a number when you hover over it. +Labeling rows and columns differently makes cell references such as +ā€œcell 4Bā€ unambiguous; you donā€™t have to have a convention about whether +to say the row first or the column first. (ā€œCell B4ā€ is the same as +ā€œcell 4B.ā€) On the other hand, to extract a value from column B in your +program, you have to say item 2 of, not item B of. So itā€™s useful to be +able to find out a column number by hovering over its letter.

+ +

{width=ā€3.817361111111111inā€ +height=ā€0.8111111111111111inā€}Any value that can appear in a program can +be displayed in a table cell:

+ +

{width=ā€4.336805555555555inā€ +height=ā€2.104861111111111inā€}This display shows that the standard cell +dimensions may not be enough for large value images. By expanding the +entire speech balloon and then the second column and all the rows, we +can make the result fit:

+ +

{width=ā€3.3409722222222222inā€ +height=ā€0.5770833333333333inā€}But we make an exception for cases in +which the value in a cell is a list (so that the entire table is +three-dimensional). Because lists are visually very big, we donā€™t try to +fit the entire value in a cell:

+ +

Even if you expand the size of the cells, Snap! will not display +sublists of sublists in table view. There are two ways to see these +inner sublists: You can switch to list view, or you can double-click on +a list icon in the table to open a dialog box showing just that +sub-sub-list in table view.

+ +

{width=ā€3.3541666666666665inā€ +height=ā€0.6944444444444444inā€}One last detail: If the first item of a +list is a list (so table view is used), but a later item isnā€™t a list, +that later item will be displayed on a red background, like an item of a +single-column list:

+ +

So, in particular, if only the first item is a list, the display will +look almost like a one-column display.

+ +

Comma-Separated Values

+ +

Spreadsheet and database programs generally offer the option to export +their data as CSV (comma-separated values lists. You can import these +files into Snap! and turn them into tables (lists of lists), and you +can export tables in CSV format. Snap! recognizes a CSV file by the +extension .csv in its filename.

+ +

A CSV file has one line per table row, with the fields separated by +commas within a row:

+ +

{width=ā€5.0inā€ +height=ā€2.6743055555555557inā€}John,Lennon,rhythm guitar

+ +

Paul,McCartney,bass guitar

+ +

George,Harrison,lead guitar

+ +

Ringo,Starr,drums

+ +

Hereā€™s what the corresponding table looks like:

+ +

Hereā€™s how to read a spreadsheet into Snap!:

+ +

{width=ā€1.2083333333333333inā€ +height=ā€0.2708333333333333inā€}1. Make a variable with a watcher on +stage:

+ +

2. Right-click on the watcher and choose the ā€œimportā€ option. (If the +variableā€™s value is already a list, be sure to click on the outside +border of the watcher; there is a different menu if you click on the +list itself.) Select the file with your csv data.

+ +

3. There is no 3; thatā€™s it! Snap! will notice that the name of the +file youā€™re importing is something.csv and will turn the text into a +list of lists automatically.

+ +

Or, even easier, just drag and drop the file from your desktop onto the +Snap! window, and Snap! will automatically create a variable named +after the file and import the data into it.

+ +

If you actually want to import the raw CSV data into a variable, either +change the file extension to .txt before loading it, or choose ā€œraw +dataā€ instead of ā€œimportā€ in the watcher menu.

+ +

If you want to export a list, put a variable watcher containing the list +on the stage, right-click its border, and choose ā€œExport.ā€ (Donā€™t +right-click an item instead of the border; that gives a different menu.)

+ +

Multi-dimensional lists and JSON

+ +

CSV format is easy to read, but works only for one- or two-dimensional +lists. If you have a list of lists of lists, Snap! will instead export +your list as a JSON (JavaScript Object Notation) file. I modified my +list:

+ +

{width=ā€6.333333333333333inā€ +height=ā€0.4479166666666667inā€}and then exported again, getting this +file:

+ +

[["John","Lennon","rhythm +guitar"],[["James","Paul"],"McCartney","bass +guitar"],["George","Harrison","lead +guitar"],["Ringo","Starr","drums"]]

+ +

You can also import lists, including tables, from a .json file. (And you +can import plain text from a .txt file.) Drag and drop works for these +formats also.

+ +

Hyperblocks

+ +

A scalar is anything other than a list. The name comes from +mathematics, where it means a magnitude without direction, as opposed to +a vector, which points toward somewhere. A scalar function is one whose +domain and range are scalars, so all the arithmetic operations are +scalar functions, but so are the text ones such as letter and the +Boolean ones such as not.

+ +

The major new feature in Snap! 6.0 is that the domain and range of +most scalar function blocks is extended to multi-dimensional lists, with +the underlying scalar function applied termwise:

+ +

{width=ā€2.5625inā€ +height=ā€0.9166666666666666inā€}Macintosh
+HD:Users:bh:Desktop:vector-vector.png{width=ā€3.3402777777777777inā€ +height=ā€0.9166666666666666inā€}

+ +

Macintosh
+HD:Users:bh:Desktop:matrix-matrix.png{width=ā€4.944444444444445inā€ +height=ā€0.6944444444444444inā€}

+ +

{width=ā€5.743055555555555inā€ +height=ā€0.6944444444444444inā€}Mathematicians, note in the last example +above that the result is just a termwise application of the underlying +function (7Ɨ3, 8Ɨ5, etc.), not matrix multiplication. See Appendix B +for that. For a dyadic (two-input) function, if the lengths donā€™t agree, +the length of the result (in each dimension) is the length of the +shorter input:

+ +

{width=ā€6.791666666666667inā€ +height=ā€0.8680555555555556inā€}However, if the number of dimensions +differs in the two inputs, then the number of dimensions in the result +agrees with the higher-dimensional input; the lower-dimensional one is +used repeatedly in the missing dimension(s):

+ +

(7Ɨ6. 8Ɨ10, 1Ɨ20, 40Ɨ6, 20Ɨ10, etc.). In particular, a scalar +input is paired with every scalar in the other input:

+ +

{width=ā€7.483333333333333inā€ +height=ā€0.63125inā€}{width=ā€5.506944444444445inā€ +height=ā€1.5180555555555555inā€}One important motivation for this feature +is how it simplifies and speeds up media computation, as in this +shifting of the Alonzo costume to be bluer:

+ +

{width=ā€1.6875inā€ +height=ā€1.0486111111111112inā€}{width=ā€5.194444444444445inā€ +height=ā€1.0486111111111112inā€}Each pixel of the result has Ā¾ of its +original red and green, and three times its original blue (with its +transparency unchanged). By putting some sliders on the stage, you can +play with colors dynamically:

+ +

{width=ā€1.0298611111111111inā€ +height=ā€0.18958333333333333inā€}{width=ā€0.8895833333333333inā€ +height=ā€0.2inā€}There are a few naturally scalar functions that have +already had specific meanings when applied to lists and therefore are +not hyperblocks: = and identical to (because they compare entire +structures, not just scalars, always reporting a single Boolean result), +and and or (because they donā€™t evaluate their second input at all if the +first input determines the result), join (because it converts non-scalar +(and other non-text) inputs to text string form), and is a (type) +(because it applies to its input as a whole). Blocks whose inputs are +ā€œnativelyā€ lists, such as and , are never hyperblocks.

+ +

{width=ā€5.239583333333333inā€ +height=ā€1.679861111111111inā€}{width=ā€5.401514654418198inā€ +height=ā€1.227273622047244inā€}{width=ā€2.0991666666666666inā€ +height=ā€0.2475inā€}The reshape block takes a list (of any depth) as its +first input, and then takes zero or more sizes along the dimensions of +an array. In the example it will report a table (a matrix) of four rows +and three columns. If no sizes are given, the result is an empty list. +Otherwise, the cells of the specified shape are filled with the atomic +values from the input list. If more values are needed than provided, the +block starts again at the head of the list, using values more than once. +If more values are provided than needed, the extras are ignored; this +isnā€™t an error.

+ +

Icon Description automatically
+generated{width=ā€1.34inā€ +height=ā€0.25inā€} The item of block has a special set of rules, designed +to preserve its pre-hyperblock meaning and also provide a useful +behavior when given a list as its first (index) input:

+ +
    +
  1. +

    If the index is a number, then item of reports the indicated +top-level item of the list input; that item may be a sublist, in +which case the entire sublist is reported (the original meaning of +item of):Macintosh
+HD:Users:bh:Desktop:item-scalar.png{width=ā€5.506944444444445inā€ +height=ā€0.9166666666666666inā€}

    +
  2. +
  3. +

    If the index is a list of numbers (no sublists), then item of +reports a list of the indicated top-level items (rows, in a matrix; +a straightforward hyperization): Macintosh
+HD:Users:bh:Desktop:item-vector.png{width=ā€6.006944444444445inā€ +height=ā€0.8680555555555556inā€}

    +
  4. +
  5. +

    If the index is a list of lists of numbers, then item of reports an +array of only those scalars whose position in the list input matches +the index input in all dimensions (changed in Snap! +6.6!):{width=ā€6.006944444444445inā€ +height=ā€0.6875inā€}

    +
  6. +
  7. +

    If a list of list of numbers includes an empty sublist, then all +items are chosen along that +dimension:{width=ā€6.006944444444445inā€ +height=ā€0.6875inā€}

    +
  8. +
+ +

{width=ā€6.604166666666667inā€ +height=ā€1.0486111111111112inā€}To get a column or columns of a +spreadsheet, use an empty list in the row selector (changed in Snap! +6.6!):

+ +

{width=ā€1.5263888888888888inā€ +height=ā€1.8583333333333334inā€}The length of block is extended to provide +various ways of looking at the shape and contents of a list. The options +other than length are mainly useful for lists of lists, to any depth. +These new options work well with hyperblocks and the APL library. +(Examples are on the next page.)

+ +

length: reports the number of (toplevel) items in the list, as always.

+ +

rank: reports the number of dimensions of the list, i.e., the maximum +depth of lists of lists of lists of lists. (That example would be rank +4.)

+ +

dimensions: reports a list of numbers, each of which is the maximum +length in one dimension, so a spreadsheet of 1000 records, each with 4 +fields, would report the list [1000 4].

+ +

flatten: reports a flat, one-dimensional list containing the atomic +(non-list) items anywhere in the input list.

+ +

columns: reports a list in which the rows and columns of the input list +are interchanged, so the shape of the transpose of a shape [1000 4] +list would be [4 1000]. This option works only for lists whose rank is +at most 2. The name reflects the fact that the toplevel items of the +reported table are the columns of the original table.

+ +

reverse: reports a list in which the (toplevel) items of the input list +are in reverse order.

+ +

The remaining three options report a (generally multi-line) text string. +The input list may not include any atomic (non-list) data other than +text or numbers. The lines option is intended for use with rank-one +lists of text strings; it reports a string in which each list item +becomes a line of text. You can think of it as the opposite of the split +by line block. The csv option (comma-separated values) is intended for +rank-two lists that represent a spreadsheet or other tabular data. Each +item of the input list should be a list of atoms; the block reports a +text string in which each item of the big list becomes a line of text in +which the items of that sublist are separated by commas. The json option +is for lists of any rank; it reports a text string in which the list +structure is explicitly represented using square brackets. These are the +opposites of split by csv and split by json.

+ +

{width=ā€6.3530304024496935inā€ +height=ā€6.733522528433946inā€}

+ +

The idea of extending the domain and range of scalar functions to +include arrays comes from the language APL. (All the great programming +languages are based on mathematical ideas. Our primary ancestors are +Smalltalk, based on models, and Lisp, based on lambda calculus. Prolog, +a great language not (so far) influencing Snap!, is based on logic. +And APL, now joining our family, is based on linear algebra, which +studies vectors and matrices. Those other programming languages are +based on the weaknesses of computer hardware.) Hyperblocks are not the +whole story about APL, which also has mixed-domain functions and higher +order functions. Some of whatā€™s missing is provided in the APL library. +(See Appendix B.)

+ +

Typed Inputs

+ +

Scratchā€™s Type Notation

+ +

{width=ā€1.375inā€ +height=ā€0.2125inā€}Prior to version 3, Scratch block inputs came in two +types: Text-or-number type and Number type. The former is indicated by a +rectangular box, the latter by a rounded box: . A third Scratch type, +Boolean (true/false), can be used in certain Control blocks with +hexagonal slots.

+ +

The Snap! types are an expanded collection including Procedure, List, +and Object types. Note that, with the exception of Procedure types, all +of the input type shapes are just reminders to the user of what the +block expects; they are not enforced by the language.

+ +

{width=ā€2.5833333333333335inā€ height=ā€1.6041666666666667inā€}The Snap! Input Type Dialog

+ +

In the Block Editor input name dialog, there is a right-facing arrowhead +after the ā€œInput nameā€ option:

+ +

Clicking that arrowhead opens the ā€œlongā€ input name dialog:

+ +

{width=ā€5.170833333333333inā€ +height=ā€4.135416666666667inā€}{width=ā€0.19791666666666666inā€ +height=ā€0.19791666666666666inā€}There are twelve input type shapes, plus +three mutually exclusive modifiers, listed in addition to the basic +choice between title text and an input name. The default type, the one +you get if you donā€™t choose anything else, is ā€œAny,ā€ meaning that this +input slot is meant to accept any value of any type. If the size input +in your block should be an oval-shaped numeric slot rather than a +generic rectangle, click ā€œNumber.ā€

+ +

{width=ā€6.822222222222222inā€ +height=ā€2.7569444444444446inā€}The arrangement of the input types is +systematic. As the pictures on this and the next page show, each row of +types is a category, and parts of each column form a category. +Understanding the arrangement will make it a little easier to find the +type you want.

+ +

{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}The second row of input types contains +the ones found in Scratch: Number, Any, and Boolean. (The reason these +are in the second row rather than the ļ¬rst will become clear when we +look at the column arrangement.) The ļ¬rst row contains the new Snap! +types other than procedures: Object, Text, and List. The last two rows +are the types related to procedures, discussed more fully below.

+ +

The List type is used for ļ¬rst class lists, discussed in Chapter IV +above. The red rectangles inside the input slot are meant to resemble +the appearance of lists as Snap! displays them on the stage: each +element in a red rectangle.

+ +

The Object type is for sprites, costumes, sounds, and similar data +types.

+ +

The Text type is really just a variant form of the Any type, using a +shape that suggests a text input.5

+ +

Procedure Types

+ +

Although the procedure types are discussed more fully later, they are +the key to understanding the column arrangement in the input types. Like +Scratch, Snap! has three block shapes: jigsaw-piece for command +blocks, oval for reporters, and hexagonal for predicates. (A predicate +is a reporter that always reports true or false.) In Snap! these +blocks are ļ¬rst class data; an input to a block can be of Command type, +Reporter type, or Predicate type. Each of these types is directly below +the type of value that that kind of block reports, except for Commands, +which donā€™t report a value at all. Thus, oval Reporters are related to +the Any type, while hexagonal Predicates are related to the Boolean +(true or false) type.

+ +

The unevaluated procedure types in the fourth row are explained in +Section VI.E below. In one handwavy sentence, they combine the meaning +of the procedure types with the appearance of the reported value types +two rows higher. (Of course, this isnā€™t quite right for the C-shaped +command input type, since commands donā€™t +{width=ā€3.6458333333333335inā€ +height=ā€3.113888888888889inā€}report values. But youā€™ll see later that +itā€™s true in spirit.)

+ +

{width=ā€0.13194444444444445inā€ height=ā€0.13194444444444445inā€}Pulldown inputs

+ +

{width=ā€1.6805555555555556inā€ +height=ā€0.9409722222222222inā€}Certain primitive blocks have pulldown +inputs, either read-only, like the input to the touching block:

+ +

{width=ā€1.9020833333333333inā€ +height=ā€1.3229166666666667inā€}(indicated by the input slot being the +same (cyan, in this case) color as the body of the block), or +writeable, like the input to the point in direction block:

+ +

(indicated by the white input slot), which means that the user can type +in an arbitrary input instead of using the pulldown menu.

+ +

{width=ā€0.8326388888888889inā€ +height=ā€0.6527777777777778inā€}{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}Custom blocks can also have such inputs. +To make a pulldown input, open the long form input dialog, choose a text +type (Any, Text, or Number) and click the icon in the bottom right +corner, or control/right-click in the dialog. You will see this menu:

+ +

{width=ā€3.076388888888889inā€ +height=ā€1.875inā€}Click the read-only checkbox if you want a read-only +pulldown input. Then from the same menu, choose optionsā€¦ to get this +dialog box:

+ +

Each line in the text box represents one menu item. If the line does not +contain any of the characters =~{} then the text is both whatā€™s shown +in the menu and the value of the input if that entry is chosen.

+ +

If the line contains an equal sign =, then the text to the left of the +equal sign is shown in the menu, and the text to the right is what +appears in the input slot if that entry is chosen, and is also the value +of the input as seen by the procedure.

+ +

If the line consists of a tilde ~, then it represents a separator (a +horizontal line) in the menu, used to divide long menus into visible +categories. There should be nothing else on the line. This separator is +not choosable, so there is no input value corresponding to it.

+ +

{width=ā€7.5inā€ +height=ā€3.2416666666666667inā€}If the line ends with the two characters +equal sign and open brace ={, then it represents a submenu. The text +before the equal sign is a name for the submenu, and will be displayed +in the menu with an arrowhead ā–ŗ at the end of the line. This line is not +clickable, but hovering the mouse over it displays the submenu next to +the original menu. A line containing a close brace } ends the submenu; +nothing else should be on that line. Submenus may be nested to arbitrary +depth.

+ +

###

+ +

Alternatively, instead of giving a menu listing as described above, you +can put a JavaScript function that returns the desired menu in the +textbox. This is an experimental feature and requires that JavaScript be +enabled in the Settings menu.
+It is also possible to get the special menus used in some primitive +blocks, by choosing from the menu submenu: broadcast messages, sprites +and stage, costumes, sounds, variables that can be set in this scope, +the play note piano keyboard, or the point in direction 360Ā° dial. +Finally, you can make the input box accept more than one line of text +(that is, text including a newline character) from the special submenu, +either ā€œmulti-lineā€ for regular +{width=ā€0.6041666666666666inā€ +height=ā€0.3194444444444444inā€}text or ā€œcodeā€ for monospace-font computer +code.

+ +

{width=ā€0.13055555555555556inā€ +height=ā€0.1375inā€}{width=ā€1.6805555555555556inā€ +height=ā€0.2569444444444444inā€}If the input type is something other than +text, then clicking the button will instead show this menu:

+ +

{width=ā€7.5inā€ +height=ā€2.6277777777777778inā€}As an example, we want to make this block: +The second input must be a read-only object menu:

+ +

{width=ā€1.6388888888888888inā€ +height=ā€0.5208333333333334inā€}

+ +

{width=ā€1.7638888888888888inā€ +height=ā€0.9305555555555556inā€}{width=ā€3.5694444444444446inā€ +height=ā€1.2944444444444445inā€}The ā€œMultiple inputsā€ option: The list +block introduced earlier accepts any number of inputs to specify the +items of the new list. To allow this, Snap! introduces the arrowhead +notation () that expands and contracts the block, adding and removing +input slots. (Shift-clicking on an arrowhead adds or removes three input +slots at once.) Custom blocks made by the Snap! user have that +capability, too. If you choose the ā€œMultiple inputsā€ button, then +arrowheads will appear after the input slot in the block. More or fewer +slots (as few as zero) may be used. When the block runs, all of the +values in all of the slots for this input name are collected into a +list, and the value of the input as seen inside the script is that list +of values:

+ +

The ellipsis (ā€¦) in the orange input slot name box in the prototype +indicates a multiple or variadic input.

+ +

The third category, ā€œUpvar - make internal variable visible to caller,ā€ +isnā€™t really an input at all, but rather a sort of output from the block +to its user. It appears as an orange variable oval in the block, rather +than as an input slot. Hereā€™s an example; the uparrow (ā†‘) in the +prototype indicates this kind of internal variable name:

+ +

{width=ā€5.901388888888889inā€ +height=ā€0.53125inā€}

+ +

The variable i (in the block on the right above) can be dragged from the +for block into the blocks used in its C-shaped command slot. Also, by +clicking on the orange i, the user can change the name of the variable +as seen in the calling script (although the name hasnā€™t changed inside +the blockā€™s definition). This kind of variable is called an upvar for +short, because it is passed upward from the custom block to the script +that uses it.

+ +

Note about the example: for is a primitive block, but it doesnā€™t need to +be. Youā€™re about to see (next chapter) how it can be written in Snap!. +Just give it a different name to avoid confusion, such as my for as +above.

+ +

Prototype Hints

+ +

We have mentioned three notations that can appear in an input slot in +the prototype to remind you of what kind of input this is. Here is the +complete list of such notations:

+ +

{width=ā€0.7347222222222223inā€ +height=ā€6.118055555555555inā€}= default value ā€¦ multiple input ā†‘ upvar +# number

+ +

{width=ā€0.16319444444444445inā€ +height=ā€0.13541666666666666inā€}Ī» procedure types ā«¶ list ? Boolean object +Ā¶ multi-line text

+ +

Title Text and Symbols

+ +

{width=ā€1.21875inā€ +height=ā€0.23472222222222222inā€}Some primitive blocks have symbols as +part of the block name: . Custom blocks can use symbols too. In the +Block Editor, click the plus sign in the prototype at the point where +you want to insert the symbol. Then click the title text picture below +the text box thatā€™s expecting an input slot name. The dialog will then +change to look like this:

+ +

{width=ā€1.2444444444444445inā€ +height=ā€0.26666666666666666inā€}{width=ā€2.0347222222222223inā€ +height=ā€1.2638888888888888inā€}The important part to notice is the +arrowhead that has appeared at the right end of the text box. Click it +to see the menu shown here at the left.

+ +

Choose one of the symbols. The result will have the symbol you want: The +available symbols are, pretty much, the ones that are used in Snap! +icons.

+ +

{width=ā€2.0347222222222223inā€ +height=ā€1.2638888888888888inā€}But Iā€™d like the arrow symbol bigger, and +yellow, so I edit its name:

+ +

{width=ā€1.1979166666666667inā€ +height=ā€0.2708333333333333inā€}This makes the symbol 1.5 times as big as +the letters in the block text, using a color with red-green-blue values +of 255-255-150 (each between 0 and 255). Hereā€™s the result:

+ +

The size and color controls can also be used with text: +$foo-8-255-120-0 will make a huge orange ā€œfoo.ā€

+ +

Note the last entry in the symbol menu: ā€œnew line.ā€ This can be used in +a block with many inputs to control where the text continues on another +line, instead of letting Snap! choose the line break itself.

+ +

Procedures as Data

+ +

Call and Run

+ +

{width=ā€3.6729166666666666inā€ +height=ā€1.5833333333333333inā€}In the for block example above, the input +named action has been declared as type ā€œCommand (C-shaped)ā€; thatā€™s why +the finished block is C-shaped. But how does the block actually tell +Snap! to carry out the commands inside the C-slot? Here is a simple +version of the block script:

+ +

This is simplified because it assumes, without checking, that the ending +value is greater than the starting value; if not, the block should +(depending on the designerā€™s purposes) either not run at all, or change +the variable by āˆ’1 for each repetition instead of by 1.

+ +

{width=ā€0.5inā€ +height=ā€0.15625inā€}The important part of this script is the run block +near the end. This is a Snap! built-in command block that takes a +Command-type value (a script) as its input, and carries out its +instructions. (In this example, the value of the input is the script +that the user puts in the C-slot of the my for block.) There is a +similar call reporter block for invoking a Reporter or Predicate block. +The call and run blocks are at the heart of Snap!ā€™s ļ¬rst class +procedure feature; they allow scripts and blocks to be used as dataā€”in +this example, as an input to a blockā€”and eventually carried out under +control of the userā€™s program.

+ +

{width=ā€7.065972222222222inā€ +height=ā€1.65625inā€}Hereā€™s another example, this time using a +Reporter-type input in a map block (see page 50):

+ +

Here we are calling the Reporter ā€œmultiply by 10ā€ three times, once with +each item of the given list as its input, and collecting the results as +a list. (The reported list will always be the same length as the input +list.) Note that the multiplication block has two inputs, but here we +have specified a particular value for one of them (10), so the call +block knows to use the input value given to it just to fill the other +(empty) input slot in the multiplication block. In the my map +definition, the input function is declared to be type Reporter, and data +is of type List.

+ +

Call/Run with inputs

+ +

{width=ā€1.8125inā€ +height=ā€0.20833333333333334inā€}The call block (like the run block) has a +right arrowhead at the end; clicking on it adds the phrase ā€œwith inputsā€ +and then a slot into which an input can be inserted:

+ +

If the left arrowhead is used to remove the last input slot, the ā€œwith +inputsā€ disappears also. The right arrowhead can be clicked as many +times as needed for the number of inputs required by the reporter block +being called.

+ +

{width=ā€2.7291666666666665inā€ +height=ā€0.31805555555555554inā€}If the number of inputs given to call +(not counting the Reporter-type input that comes first) is the same as +the number of empty input slots, then the empty slots are filled from +left to right with the given input values. If call is given exactly one +input, then every empty input slot of the called block is filled with +the same value:

+ +

If the number of inputs provided is neither one nor the number of empty +slots, then there is no automatic filling of empty slots. (Instead you +must use explicit parameters in the ring, as discussed in Section C +below.)

+ +

{width=ā€6.990277777777778inā€ +height=ā€0.6979166666666666inā€}An even more important thing to notice +about these examples is the ring around the Reporter-type input slots +in call and map above. This notation indicates that the block itself, +not the number or other value that the block would report when called, +is the input. If you want to use a block itself in a non-Reporter-type +(e.g., Any-type) input slot, you can enclose it explicitly in a ring, +found at the top of the Operators palette.

+ +

As a shortcut, if you right-click or control-click on a block (such as +the + block in this example), one of the choices in the menu that +appears is ā€œringifyā€ and/or ā€œunringify.ā€ The ring indicating a +Reporter-type or Predicate-type input slot is essentially the same idea +for reporters as the C-shaped input slot with which youā€™re already +familiar; with a C-shaped slot, itā€™s the script you put in the slot +that becomes the input to the C-shaped block.

+ +

There are three ring shapes. All are oval on the outside, indicating +that the ring reports a value, the block or script inside it, but the +inside shapes are command, reporter, or predicate, indicating what kind +of block or script is expected. Sometimes you want to put something more +complicated than a single reporter inside a reporter ring; if so, you +can use a script, but the script must report a value, as in a custom +reporter definition.

+ +

Variables in Ring Slots

+ +

Note that the run block in the definition of the my for block (page 65) +doesnā€™t have a ring around its input variable action. When you drag a +variable into a ringed input slot, you generally do want to use the +value of the variable, which will be the block or script youā€™re trying +to run or call, rather than the orange variable reporter itself. So +Snap! automatically removes the ring in this case. If you ever do want +to use the variable block itself, rather than the value of the +variable, as a Procedure-type input, you can drag the variable into the +input slot, then control-click or right-click it and choose ā€œringifyā€ +from the menu that appears. (Similarly, if you ever want to call a +function that will report a block to use as the input, such as item 1 of +applied to a list of blocks, you can choose ā€œunringifyā€ from the menu. +Almost all the time, though, Snap! does what you mean without help.)

+ +

Writing Higher Order Procedures

+ +

A higher order procedure is one that takes another procedure as an +input, or that reports a procedure. In this document, the word +ā€œprocedureā€ encompasses scripts, individual blocks, and nested +reporters. (Unless specified otherwise, ā€œreporterā€ includes predicates. +When the word is capitalized inside a sentence, it means specifically +oval-shaped blocks. So, ā€œnested reportersā€ includes predicates, but ā€œa +Reporter-type inputā€ doesnā€™t.)

+ +

Although an Any-type input slot (what you get if you use the small +input-name dialog box) will accept a procedure input, it doesnā€™t +automatically ring the input as described above. So the declaration of +Procedure-type inputs makes the use of your custom higher order block +much more convenient.

+ +

{width=ā€2.375inā€ +height=ā€1.3541666666666667inā€}Why would you want a block to take a +procedure as input? This is actually not an obscure thing to do; the +primitive conditional and looping blocks (the C-shaped ones in the +Control palette) take a script as input. Users just donā€™t usually think +about it in those terms! We could write the repeat block as a custom +block this way, if Snap! didnā€™t already have one:

+ +

The lambda (Ī») next to action in the prototype indicates that this is a +C-shaped block, and that the script enclosed by the C when the block is +used is the input named action in the body of the script. The only way +to make sense of the variable action is to understand that its value is +a script.

+ +

{width=ā€2.5833333333333335inā€ +height=ā€1.6041666666666667inā€}To declare an input to be Procedure-type, +open the input name dialog as usual, and click on the arrowhead:

+ +

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

+ +

{width=ā€0.19791666666666666inā€ +height=ā€0.19791666666666666inā€}{width=ā€3.6527777777777777inā€ +height=ā€2.75455271216098inā€}
+Why would you ever choose an inline Command slot rather than a C shape? +Other than the run block +{width=ā€2.1145833333333335inā€ +height=ā€0.46875inā€}discussed below, the only case I can think of is +something like the C/C++/Java for loop, which actually has three +command script inputs (and one predicate input), only one of which is +the ā€œfeaturedā€ loop body:

+ +

Okay, now that we have procedures as inputs to our blocks, how do we use +them? We use the blocks run (for commands) and call (for reporters). The +run blockā€™s script input is an inline ring, not C-shaped, because we +anticipate that it will be rare to use a specific, literal script as the +input. Instead, the input will generally be a variable whose value is +a script.

+ +

The run and call blocks have arrowheads at the end that can be used to +open slots for inputs to the called procedures. How does Snap! know +where to use those inputs? If the called procedure (block or script) has +empty input slots, Snap! ā€œdoes the right thing.ā€ This has several +possible meanings:

+ +

{width=ā€3.4479166666666665inā€ +height=ā€0.34405949256342955inā€}1. If the number of empty slots is +exactly equal to the number of inputs provided, then Snap! fills the +empty slots from left to right:

+ +

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

+ +

{width=ā€2.8020833333333335inā€ +height=ā€0.30694444444444446inā€}

+ +

3. Otherwise, Snap! wonā€™t fill any slots, because the userā€™s intention +is unclear.

+ +

If the user wants to override these rules, the solution is to use a ring +with explicit input names that can be put into the given block or script +to indicate how inputs are to be used. This will be discussed more fully +below.

+ +

Recursive Calls to Multiple-Input Blocks

+ +

A relatively rare situation not yet considered here is the case of a +recursive block that has a variable number of inputs. Letā€™s say the user +of your project calls your block with five inputs one time, and 87 +inputs another time. How do you write the recursive call to your block +when you donā€™t know how many inputs to give it? The answer is that you +collect the inputs in a list (recall that, when you declare an input +name to represent a variable number of inputs, your block sees those +inputs as a list of values in the first place), and then, in the +recursive call, you drop that input list onto the arrowheads that +indicate a variable-input slot, rather than onto the input slot:

+ +

{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}{width=ā€2.501388888888889inā€ +height=ā€1.9444444444444444inā€}{width=ā€2.225inā€ +height=ā€1.1708333333333334inā€}{width=ā€2.2756944444444445inā€ +height=ā€1.5972222222222223inā€}
+Note that the halo you see while dragging onto the arrowheads is red +instead of white, and covers the input slot as well as the arrowheads. +And when you drop the expression onto the arrowheads, the words ā€œinput +list:ā€ are added to the block text and the arrowheads disappear (in this +invocation only) to remind you that the list represents all of the +multiple inputs, not just a single input. The items in the list are +taken individually as inputs to the script. Since numbers is a list of +numbers, each individual item is a number, just what sizes wants. This +{width=ā€6.8125inā€ +height=ā€1.7104166666666667inā€}block will take any number of numbers as +inputs, and will make the sprite grow and shrink accordingly:

+ +

{width=ā€2.9583333333333335inā€ +height=ā€0.6875inā€}The user of this block calls it with any number of +individual numbers as inputs. But inside the definition of the block, +all of those numbers form a list that has a single input name, +numbers. This recursive definition ļ¬rst checks to make sure there are +any inputs at all. If so, it processes the ļ¬rst input (item 1 of the +list), then it wants to make a recursive call with all but the ļ¬rst +number. But sizes doesnā€™t take a list as input; it takes numbers as +inputs! So this would be wrong:

+ +

Formal Parameters

+ +

{width=ā€3.5208333333333335inā€ +height=ā€1.0395833333333333inā€}The rings around Procedure-type inputs +have an arrowhead at the right. Clicking the arrowhead allows you to +give the inputs to a block or script explicit names, instead of using +empty input slots as weā€™ve done until now.

+ +

The names #1, #2, etc. are provided by default, but you can change a +name by clicking on its orange oval in the input names list. Be careful +not to drag the oval when clicking; thatā€™s how you use the input +inside the ring. The names of the input variables are called the formal +parameters of the encapsulated procedure.

+ +

{width=ā€4.322916666666667inā€ +height=ā€0.45416666666666666inā€}Hereā€™s a simple but contrived example +using explicit names to control which input goes where inside the ring:

+ +

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

+ +

{width=ā€4.679861111111111inā€ +height=ā€3.0180555555555557inā€}Here is a more realistic, much more +advanced example:

+ +

{width=ā€4.347222222222222inā€ +height=ā€1.4027777777777777inā€}

+ +

This is the definition of a block that takes any number of lists, and +reports the list of all possible combinations of one item from each +list. The important part for this discussion is that near the bottom +there are two nested calls to map, the higher order function that +applies an input function to each item of an input list. In the inner +block, the function being mapped is in front of, and that block takes +two inputs. The second, the empty List-type slot, will get its value in +each call from an item of the inner mapā€™s list input. But there is no +way for the outer map to communicate values to empty slots of the in +front of block. We must give an explicit name, newitem, to the value +that the outer map is giving to the inner one, then drag that variable +into the in front of block.

+ +

By the way, once the called block provides names for its inputs, Snap! +will not automatically fill empty slots, on the theory that the user has +taken control. In fact, thatā€™s another reason you might want to name the +inputs explicitly: to stop Snap! from filling a slot that should +really remain empty.

+ +

Procedures as Data

+ +

{width=ā€5.1875inā€ +height=ā€1.65625inā€}Hereā€™s an example of a situation in which a procedure +must be explicitly marked as data by pulling a ring from the Operators +palette and putting the procedure (block or script) inside it:

+ +

Here, we are making a list of procedures. But the list block accepts +inputs of any type, so its input slots are not ringed. We must say +explicitly that we want the block itself as the input, rather than +whatever value would result from evaluating the block.

+ +

{width=ā€3.8333333333333335inā€ +height=ā€0.84375inā€}Besides the list block in the example above, other +blocks into which you may want to put procedures are set (to set the +value of a variable to a procedure), say and think (to display a +procedure to the user), and report (for a reporter that reports a +procedure):

+ +

Special Forms

+ +

{width=ā€2.4993055555555554inā€ +height=ā€0.27847222222222223inā€}{width=ā€2.402083333333333inā€ +height=ā€1.4270833333333333inā€}The primitive if else block has two +C-shaped command slots and chooses one or the other depending on a +Boolean test. Because Scratch doesnā€™t emphasize functional programming, +it lacks a corresponding reporter block to choose between two +expressions. Snap! has one, but we could write our own:

+ +

{width=ā€4.291666666666667inā€ +height=ā€0.8486111111111111inā€}{width=ā€3.818985126859143inā€ +height=ā€0.27433070866141734inā€}Our block works for these simple +examples, but if we try to use it in writing a recursive operator, itā€™ll +fail:

+ +

The problem is that when any block is called, all of its inputs are +computed (evaluated) before the block itself runs. The block itself +knows only the values of its inputs, not what expressions were used to +compute them. In particular, all of the inputs to our if then else block +are evaluated ļ¬rst thing. That means that even in the base case, +factorial will try to call itself recursively, causing an infinite loop. +We need our if then else block to be able to select only one of the two +alternatives to be evaluated.

+ +

We have a mechanism to allow that: declare the then and else inputs to +be of type Reporter rather than type Any. Then, when calling the block, +those inputs will be enclosed in a ring so that the expressions +themselves, rather than their values, become the inputs:

+ +

{width=ā€1.1145833333333333inā€ +height=ā€0.6979166666666666inā€}{width=ā€4.520833333333333inā€ +height=ā€1.0229166666666667inā€}{width=ā€2.6173611111111112inā€ +height=ā€1.5104166666666667inā€}

+ +

In this version, the program works, with no infinite loop. But weā€™ve +paid a heavy price: this reporter-if is no longer as intuitively obvious +as the Scratch command-if. You have to know about procedures as data, +about rings, and about a trick to get a constant value in a ringed slot. +(The id block implements the identity function, which reports its +input.6 We need it because rings take only reporters as input, not +numbers.) What weā€™d like is a reporter-if that behaves like this one, +delaying the evaluation of its inputs, but looks like our ļ¬rst +version, which was easy to use except that it didnā€™t work.

+ +

Such blocks are indeed possible. A block that seems to take a simple +expression as input, but delays the evaluation of that input by wrapping +an ā€œinvisible ringā€ around it (and, if necessary, an id-like +transformation of constant data into constant functions) is called a +special form. To turn our if block into a special form, we edit the +blockā€™s prototype, declaring the inputs yes and no to be of type ā€œAny +(unevaluated)ā€ instead of type Reporter. The script for the block is +still that of the second version, including the use of call to evaluate +either yes or no but not both. But the slots appear as white Any-type +rectangles, not Reporter-type rings, and the factorial block will look +like our ļ¬rst attempt.

+ +

In a special formā€™s prototype, the unevaluated input slot(s) are +indicated by a lambda (Ī») next to the input name, just as if they were +declared as Procedure type. They are Procedure type, really; theyā€™re +just disguised to the user of the block.

+ +

Special forms trade off implementor sophistication for user +sophistication. That is, you have to understand all about procedures as +data to make sense of the special form implementation of my if then +else. But any experienced Scratch programmer can use my if then else +without thinking at all about how it works internally.

+ +

Special Forms in Scratch

+ +

Special forms are actually not a new invention in Snap!. Many of +Scratchā€™s conditional and looping blocks are really special forms. The +hexagonal input slot in the if block is a straightforward Boolean value, +because the value can be computed once, before the if block makes its +decision about whether or not to run its action input. But the forever +if, repeat until, and wait until blocksā€™ inputs canā€™t be Booleans; they +have to be of type ā€œBoolean (unevaluated),ā€ so that Scratch can evaluate +them over and over again. Since Scratch doesnā€™t have custom Cā€‘shaped +blocks, it can afford to handwave away the distinction between evaluated +and unevaluated Booleans, but Snap! canā€™t. The pedagogic value of +special forms is proven by the fact that no Scratcher ever notices that +thereā€™s anything strange about the way in which the hexagonal inputs in +the Control blocks are evaluated.

+ +

Also, the C-shaped slot familiar to Scratch users is an unevaluated +procedure type; you donā€™t have to use a ring to keep the commands in the +C-slot from being run before the C-shaped block is run. Those commands +themselves, not the result of running them, are the input to the +C-shaped Control block. (This is taken for granted by Scratch users, +especially because Scratchers donā€™t think of the contents of a C-slot as +an input at all.) This is why it makes sense that ā€œCā€‘shapedā€ is on the +fourth row of types in the long form input dialog, with other +unevaluated types.

+ +

Object Oriented Programming with Sprites

+ +

Object oriented programming is a style based around the abstraction +object: a collection of data and methods (procedures, which from +our point of view are just more data) that you interact 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. Our approach +is therefore less restrictive than that of some other OOP languages; we +give objects easy access to each othersā€™ data and methods.

+ +

Technically, object oriented programming rests on three legs: (1) +Message passing: There is a notation by which any object can send a +message to another object. (2) Local state: Each object can remember +the important past history of the computation it has performed. +(ā€œImportantā€ means that it need not remember every message it has +handled, but only the lasting effects of those messages that will affect +later computation.) (3) Inheritance: It would be impractical if each +individual object had to contain methods, many of them identical to +those of other objects, for all of the messages it can accept. Instead, +we need a way to say that this new object is just like that old object +except for a few differences, so that only those differences need be +programmed explicitly.

+ +

First Class Sprites

+ +

Like Scratch, Snap! comes with things that are natural objects: its +sprites. Each sprite can own local variables; each sprite has its own +scripts (methods). A Scratch animation is plainly a simulation of the +interaction of characters in a play. There are two ways in which Scratch +sprites are less versatile than the objects of an OOP language. First, +Scratch message passing is weak in three respects: Messages can only be +broadcast, not addressed to an individual sprite; messages canā€™t take +inputs; and methods canā€™t return values to their caller. Second, and +more basic, in the OOP paradigm objects are data; they can be the +value of a variable, an element of a list, and so on, but thatā€™s not the +case for Scratch sprites.

+ +

Snap! sprites are ļ¬rst class data. They can be created and deleted by +a script, stored in a variable or list, and sent messages individually. +The children of a sprite can inherit sprite-local variables, methods +(sprite-local procedures), and other attributes (e.g., x position).

+ +

{width=ā€0.9652777777777778inā€ +height=ā€0.19444444444444445inā€}{width=ā€1.0833333333333333inā€ +height=ā€0.19444444444444445inā€}{width=ā€0.6666666666666666inā€ +height=ā€0.19444444444444445inā€}The fundamental means by which programs +get access to sprites is the my reporter block. It has a dropdown-menu +input slot that, when clicked, gives access to all the sprites, plus the +stage. reports a single sprite, the one asking the question. reports a +list of all sprites other than the one asking the question. reports a +list of all sprites that are near the one askingā€”the ones that are +candidates for having collided with this one, for example. The my block +has many other options, discussed below. If you know the name of a +particular sprite, the object reporter will report the sprite itself.

+ +

{width=ā€3.5520833333333335inā€ +height=ā€0.5104166666666666inā€}{width=ā€2.691434820647419inā€ +height=ā€1.25inā€}An object or list of objects reported by my or object +can be used as input to any block that accepts any input type, such as +setā€™s second input. If you say an object, the resulting speech balloon +will contain a smaller image of the objectā€™s costume or (for the stage) +background.

+ +

Permanent and Temporary Clones

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.19444444444444445inā€}The block is used to create and report an +instance (a clone) of any sprite. (There is also a command version, for +historical reasons.) There are two different kinds of situations in +which clones are used. One is that youā€™ve made an example sprite and, +when you start the project, you want a fairly large number of +essentially identical sprites that behave like the example. (Hereafter +weā€™ll call the example sprite the ā€œparentā€ and the others the +ā€œchildren.ā€) Once the game or animation is over, you donā€™t need the +copies any more. (As weā€™ll see, ā€œcopiesā€ is the wrong word because the +parent and the children share a lot of properties. Thatā€™s why we use +the word ā€œclonesā€ to describe the children rather than ā€œcopies.ā€) These +are temporary clones. They are automatically deleted when the user +presses either the green flag or the red stop sign. In Scratch 2.0 and +later, all clones are temporary.

+ +

The other kind of situation is what happens when you want +specializations of sprites. For example, letā€™s say you have a sprite +named Dog. It has certain behaviors, such as running up to a person who +comes near it. Now you decide that the family in your story really likes +dogs, so they adopt a lot of them. Some are cocker spaniels, who wag +their tails when they see you. Others are rottweilers, who growl at you +when they see you. So you make a clone of Dog, perhaps rename it Cocker +Spaniel, and give it a new costume and a script for what to do when +someone gets near. You make another clone of Dog, perhaps rename it +Rottweiler, and give it a new costume, etc. Then you make three clones +of Cocker Spaniel (so there are four altogether) and two clones of +Rottweiler. Maybe you hide the Dog sprite after all this, since itā€™s no +breed in particular. Each dog has its own position, special behaviors, +and so on. You want to save all of these dogs in the project. These are +permanent clones. In BYOB 3.1, the predecessor to Snap!, all clones +are permanent.

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.19444444444444445inā€}One advantage of temporary clones is that +they donā€™t slow down Snap! even when you have a lot of them. (If +youā€™re curious, one reason is that permanent clones appear in the sprite +corral, where their pictures have to be updated to reflect the cloneā€™s +current costume, direction, and so on.) We have tried to anticipate your +needs, as follows: When you make a clone in a script, using the block, +it is ā€œbornā€ temporary. But when you make a clone from the user +interface, for example by right-clicking on a sprite and choosing +ā€œclone,ā€ it is born permanent. The reason this makes sense is that you +donā€™t create 100 kinds of dogs automatically. Each kind has many +different characteristics, programmed by hand. But when your project is +running, it might create 100 rottweilers, and those will be identical +unless you change them in the program.

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.2569444444444444inā€}You can change a temporary sprite to +permanent by right-clicking it and choosing ā€œedit.ā€ (Itā€™s called ā€œeditā€ +rather than, say, ā€œpermanentā€ because it also shifts the scripting area +to reflect that sprite, as if youā€™d pressed its button in the sprite +corral.) You can change a permanent sprite to temporary by +right-clicking it and choosing ā€œrelease.ā€ You can also change the status +of a clone in your program with with true or false as the second input.

+ +

Sending Messages to Sprites

+ +

The messages that a sprite accepts are the blocks in its palettes, +including both all-sprites and this-sprite-only blocks. (For custom +blocks, the corresponding methods are the scripts as seen in the Block +Editor.

+ +

{width=ā€5.702083333333333inā€ +height=ā€0.3611111111111111inā€}The way to send a message to a sprite (or +the stage) is with the tell block (for command messages) or the ask +block (for reporter messages).

+ +

{width=ā€6.236111111111111inā€ +height=ā€0.8055555555555556inā€}A small point to note in the examples +above: all dropdown menus include an empty entry at the top, which can +be selected for use in higher order procedures like the for each and map +examples. Each of the sprites in my neighbors or my other sprites is +used to fill the blank space in turn.

+ +

{width=ā€5.164583333333334inā€ +height=ā€0.2847222222222222inā€}By the way, if you want a list of all +the sprites, including this sprite, you can use either of these:

+ +

{width=ā€3.545138888888889inā€ +height=ā€0.8263888888888888inā€}Tell and ask wait until the other sprite +has carried out its method before this spriteā€™s script continues. (That +has to be the case for ask, since we want to do something with the value +it reports.) So tell is analogous to broadcast and wait. Sometimes the +other spriteā€™s method may take a long time, or may even be a forever +loop, so you want the originating script to continue without waiting. +For this purpose we have the launch block:

+ +

Launch is analogous to broadcast without the ā€œwait.ā€

+ +

Snap! 4.1, following BYOB 3.1, used an extension of the of block to +provide access to other spritesā€™ methods. That interface was designed +back when we were trying hard to avoid adding new primitive blocks; it +allowed us to write ask and tell as tool procedures in Snap! itself. +That technique still works, but is deprecated, because nobody understood +it, and now we have the more straightforward primitives.

+ +

Polymorphism

+ +

{width=ā€1.6736111111111112inā€ +height=ā€1.4020833333333333inā€}Suppose you have a Dog sprite with two +clones CockerSpaniel and PitBull. In the Dog sprite you define this +method (ā€œFor this sprite onlyā€ block):

+ +

Note the location (map-pin) symbol before the blockā€™s name. The symbol +is not part of the block title; itā€™s a visual reminder that this is a +sprite-local block. Sprite-local variables are similarly marked.

+ +

But you donā€™t define greet as friend or greet as enemy in Dog. Each kind +of dog has a different behavior. Hereā€™s what a CockerSpaniel does:

+ +

{width=ā€4.052777777777778inā€ +height=ā€0.7430555555555556inā€}{width=ā€4.074305555555555inā€ +height=ā€0.7013888888888888inā€}And hereā€™s what a PitBull does:

+ +

Greet is defined in the Dog sprite. If Fido is a particular cocker +spaniel, and you ask Fido to greet someone, Fido inherits the greet +method from Dog, but Dog itself couldnā€™t actually run that method, +because Dog doesnā€™t have greet as friend or greet as enemy. And perhaps +only individual dogs such as Fido have friend? methods. Even though the +greet method is defined in the Dog sprite, when itā€™s running it +remembers what specific dog sprite called it, so it knows which greet as +friend to use. Dogā€™s greet block is called a polymorphic method, +because it means different things to different dogs, even though they +all share the same script.

+ +

Local State in Sprites: Variables and Attributes

+ +

A spriteā€™s memory of its own past history takes two main forms. It has +variables, created explicitly by the user with the ā€œMake a variableā€ +button; it also has attributes, the qualities every sprite has +automatically, such as position, direction, and pen color. Each variable +can be examined using its own orange oval block; there is one set block +to modify all variables. Attributes, however, have a less uniform +programming interface in Scratch:

+ + + +

The block, if any, that examines a variable or attribute is called its +getter; a block (there may be more than one, as in the direction +example above) that modifies a variable or attribute is called a +setter.

+ +

{width=ā€2.2381944444444444inā€ +height=ā€2.084722222222222inā€}In Snap! we allow virtually all +attributes to be examined. But instead of adding dozens of reporters, we +use a more uniform interface for attributes: The my blockā€™s menu (in +Sensing; see page 78) includes many of the attributes of a sprite. It +serves as a general getter for those attributes, e.g., my [anchor] to +find the sprite, if any, to which this sprite is attached in a nesting +arrangement (see page 10). Similarly, the same set block used to set +variable values allows setting some sprite attributes.

+ +

Prototyping: Parents and Children

+ +

Most current OOP languages use a class/instance approach to creating +objects. A class is a particular kind of object, and an instance is an +actual object of that type. For example, there might be a Dog class, +and several instances Fido, Spot, and Runt. The class typically +specifies the methods shared by all dogs (RollOver, SitUpAndBeg, Fetch, +and so on), and the instances contain data such as species, color, and +friendliness. Snap! uses a different approach called prototyping, in +which there is no distinction between classes and instances. Prototyping +is better suited to an experimental, tinkering style of work: You make a +single dog sprite, with both methods (blocks) and data (variables); you +can actually watch it and interact with it on the stage; and when you +like it, you use it as the prototype from which to clone other dogs. If +you later discover a bug in the behavior of dogs, you can edit a method +in the parent, and all of the children will automatically share the new +version of the method block. Experienced class/instance programmers may +find prototyping strange at first, but it is actually a more expressive +system, because you can easily simulate a class/instance hierarchy by +hiding the prototype sprite! Prototyping is also a better fit with the +Scratch design principle that everything in a project should be concrete +and visible on the stage; in class/instance OOP the programming process +begins with an abstract, invisible entity, the class, that must be +designed before any concrete objects can be made.7

+ +

{width=ā€7.500694444444444inā€ +height=ā€1.5743055555555556inā€}There are three ways to make a child +sprite. If you control-click or right-click on a sprite in the ā€œsprite +corralā€ at the bottom right corner of the window, you get a menu that +includes ā€œcloneā€ as one of the choices. There is an a new clone of block +in the Control palette that creates and reports a child sprite. And +sprites have a ā€œparentā€ attribute that can be set, like any attribute, +thereby changing the parent of an existing sprite.

+ +

Inheritance by Delegation

+ +

A clone inherits properties of its parent. ā€œPropertiesā€ include +scripts, custom blocks, variables, named lists, system attributes, +costumes, and sounds. Each individual property can be shared between +parent and child, or not shared (with a separate one in the child). The +getter block for a shared property, in the childā€™s palette, is displayed +in a lighter color; separate properties of the child are displayed in +the traditional colors.

+ +
+

When a new clone is created, by default it shares only its methods, +wardrobe, and jukebox with its parent. All other properties are copied +to the clone, but not shared. (One exception is that a new permanent +clone is given a random position. Another is that temporary clones +share the scripts in their parentā€™s scripting area. A third is that +sprite-local variables that the parent creates after cloning are +shared with its children.) If the value of a shared property is +changed in the parent, then the children see the new value. If the +value of a shared property is changed in the child, then the sharing +link is broken, and a new private version is created in that child. +(This is the mechanism by which a child chooses not to share a +property with its parent.) ā€œChangedā€ in this context means using the +set or change block for a variable, editing a block in the Block +Editor, editing a costume or sound, or inserting, deleting, or +reordering costumes or sounds. To change a property from unshared to +shared, the child uses the inherit command block. The pulldown menu in +the block lists all the things this sprite can inherit from its parent +(which might be nothing, if this sprite has no parent) and is not +already inheriting. But that would prevent telling a child to inherit, +so if the inherit block is inside a ring, its pulldown menu includes +all the things a child could inherit from this sprite. Right-clicking +on the scripting area of a permanent clone gives a menu option to +share the entire collection of scripts from its parent, as a temporary +clone does.

+
+ +

The rules are full of details, but the basic idea is simple: Parents can +change their children, but children canā€™t directly change their parents. +Thatā€™s what youā€™d expect from the word ā€œinheritā€: the influence just +goes in one direction. When a child changes some property, itā€™s +declaring independence from its parent (with respect to that one +property). What if you really want the child to be able to make a change +in the parent (and therefore in itself and all its siblings)? Remember +that in this system any object can tell any other object to do +something:

+ +

{width=ā€5.072916666666667inā€ +height=ā€0.5833333333333334inā€}When a sprite gets a message for which it +doesnā€™t have a corresponding block, the message is delegated to that +spriteā€™s parent. When a sprite does have the corresponding block, then +the message is not delegated. If the script that implements a delegated +message refers to my (self), it means the child to which the message was +originally sent, not the parent to which the message was delegated.

+ +

{width=ā€0.7895833333333333inā€ height=ā€3.4680555555555554inā€}List of attributes

+ +

{width=ā€1.19inā€ +height=ā€0.25inā€}{width=ā€1.1756944444444444inā€ +height=ā€6.116666666666666inā€}At the right is a picture of the dropdown +menu of attributes in the my block.

+ +

Several of these are not real attributes, but things related to +attributes:

+ + + +

The others are individual attributes:

+ + + +
+

bounding box, rounded oļ¬€ā€“the geometric center of the costume.

+
+ +

First Class Costumes and Sounds

+ +

Costumes and sounds donā€™t have methods, as sprites do; you canā€™t ask +them to do things. But they are first class: you can make a list of +them, put them in variables, use them as input to a procedure, and so +on. My [costumes] and my [sounds] report lists of them.

+ +

Media Computation with Costumes

+ +

{width=ā€1.6319444444444444inā€ +height=ā€0.1875inā€}The components of a costume are its name, width, +height, and pixels. The block gives access to these components using its +left menu. From its right menu you can choose the current costume, the +Turtle costume, or any costume in the spriteā€™s wardrobe. Since costumes +are first class, you can also drop an expression whose value is a +costume, or a list of costumes, on that second input slot. (Due to a +misfeature, even though you can select Turtle in the right menu, the +block reports 0 for its width and height, and an empty string for the +other components.) The costumeā€™s width and height are in its standard +orientation, regardless of the spriteā€™s current direction. (This is +different from the spriteā€™s width and height, reported by the my +block.)

+ +

But the really interesting part of a costume is its bitmap, a list of +pixels. (A pixel, short for ā€œpicture element,ā€ represents one dot on +your display.) Each pixel is itself a list of four items, the red, +green, and blue components of its color (in the range 0-255) and what is +standardly called its ā€œtransparencyā€ but should be called its opacity, +also in the range 0-255, in which 0 means that the pixel is invisible +and 255 means that itā€™s fully opaque: you canā€™t see anything from a +rearward layer at that point on the stage. (Costume pixels typically +have an opacity of 0 only for points inside the bounding box of the +costume but not actually part of the costume; points in the interior of +a costume typically have an opacity of 255. Intermediate values appear +mainly at the edge of a costume, or at sharp boundaries between colors +inside the costume, where they are used to reduce ā€œjaggiesā€: the +stairstep-like shape of a diagonal line displayed on an array of +discrete rectangular screen coordinates. Note that the opacity of a +sprite pixel is determined by combining the costumeā€™s opacity with the +spriteā€™s ghost effect. (The latter really is a measure of transparency: +0 means opaque and 100 means invisible.)

+ +

{width=ā€6.100694444444445inā€ +height=ā€1.3895833333333334inā€}The bitmap is a one-dimensional list of +pixels, not an array of height rows of width pixels each. Thatā€™s why +the pixel list has to be combined with the dimensions to produce a +costume. This choice partly reflects the way bitmaps are stored in the +computerā€™s hardware and operating system, but also makes it easy to +produce transformations of a costume with map:

+ +

In this simplest possible transformation, the red value of all the +pixels have been changed to a constant 150. Colors that were red in the +original (such as the logo printed on the t-shirt) become closer to +black (the other color components being near zero); the blue jeans +become purple (blue plus red); perhaps counterintuitively, the white +t-shirt, which has the maximum value for all three color components, +loses some of its red and becomes cyan, the color opposite red on the +color wheel. In reading the code, note that the function that is the +first input to map is applied to a single pixel, whose first item is its +red component. Also note that this process works only on bitmap +costumes; if you call pixels of on a vector costume (one with ā€œsvgā€ in +the corner of its picture), it will be converted to pixels first.

+ +

{width=ā€2.2569444444444446inā€ +height=ā€0.2847222222222222inā€}One important point to see here is that a +bitmap (list of pixels) is not, by itself, a costume. The new costume +block creates a costume by combining a bitmap, a width, and a height. +But, as in the example above, switch to costume will accept a bitmap as +input and will automatically use the width and height of the current +costume. Note that thereā€™s no name input; costumes computed in this way +are all named costume. Note also that the use of switch to costume does +not add the computed costume to the spriteā€™s wardrobe; to do that, say

+ +

{width=ā€7.508333333333334inā€ +height=ā€1.2090277777777778inā€}Hereā€™s a more interesting example of color +manipulation:

+ +

{width=ā€4.5625inā€ +height=ā€0.40694444444444444inā€}Each color value is constrained to be 0, +80, 160, or 240. This gives the picture a more cartoonish look. +Alternatively, you can do the computation taking advantage of +hyperblocks:

+ +

Hereā€™s one way to exchange red and green values:

+ +

{width=ā€7.5inā€ +height=ā€0.6555555555555556inā€}{width=ā€0.9583333333333334inā€ +height=ā€0.18055555555555555inā€}Itā€™s the list that determines the +rearrangement of colors: greenāž”red, redāž”green, and the other two +unchanged. That list is inside another list because otherwise it would +be selecting rows of the pixel array, and we want to select columns. +We use pixels of costume current rather than costume apple because the +latter is always a red apple, so this little program would get stuck +turning it green, instead of alternating colors.

+ +

{width=ā€5.569444444444445inā€ +height=ā€0.4236111111111111inā€}{width=ā€1.7222222222222223inā€ +height=ā€0.22916666666666666inā€}The stretch block takes a costume as its +first input, either by selecting a costume from the menu or by dropping +a costume-valued expression such as onto it. The other two inputs are +percents of the original width and height, as advertised, so you can +make fun house mirror versions of costumes:

+ +

The resulting costumes can be used with switch to costume and so on.

+ +

{width=ā€5.330729440069991inā€ +height=ā€0.3541666666666667inā€}Finally, you can use pictures from your +computerā€™s camera in your projects using these blocks:

+ +

{width=ā€1.4722222222222223inā€ +height=ā€0.24305555555555555inā€}Using the video on block turns on the +camera and displays what it sees on the stage, regardless of the inputs +given. The camera remains on until you click the red stop button, your +program runs the stop all block, or you turn it off explicitly with the +block. The video image on the stage is partly ghosted, to an extent +determined by the set video transparency block, whose input really is +transparency and not opacity. (Small numbers make the video more +visible.) By default, the video image is mirrored, like the selfie +camera on your cell phone: When you raise your left hand, your image +raises its right hand. You can control this +{width=ā€1.4027777777777777inā€ +height=ā€0.24305555555555555inā€}mirroring with the block.

+ +

{width=ā€1.2041666666666666inā€ +height=ā€1.6125inā€}The video snap on block then takes a still picture +from the camera, and trims it to fit on the selected sprite. (Video snap +on stage means to use the entire stage-sized rectangle.) For example, +hereā€™s a camera snapshot trimmed to fit Alonzo:

+ +

{width=ā€2.670138888888889inā€ +height=ā€1.2986111111111112inā€}The ā€œVideo Captureā€ project in the +Examples collection repeatedly takes such trimmed snapshots and has the +Alonzo sprite use the current snapshot as its costume, so it looks like +this:

+ +

{width=ā€2.6666666666666665inā€ +height=ā€2.0inā€}{width=ā€3.3333333333333335inā€ +height=ā€2.5inā€}(The picture above was actually taken with transparency +set to 50, to make the background more visible for printing.) Because +the sprite is always still in the place where the snapshot was taken, +its costume exactly fits in with the rest of the full-stage video. If +you were to add a move 100 steps block after the switch to costume, +youā€™d see something like this:

+ +

This time, the spriteā€™s costume was captured at one position, and then +the sprite is shown at a different position. (You probably wouldnā€™t want +to do this, but perhaps itā€™s helpful for explanatory purposes.)

+ +

{width=ā€7.375694444444444inā€ +height=ā€1.6423611111111112inā€}What you would want to do is push the +sprite around the stage:

+ +

{width=ā€3.0902777777777777inā€ +height=ā€1.9236111111111112inā€}(Really these should be Jensā€™s picture; +itā€™s his project. But heā€™s vacationing. ā˜ŗ) Video motion compares two +snapshots a moment apart, looking only at the part within the given trim +(here myself, meaning the current sprite, not the person looking into +the camera), to detect a difference between them. It reports a number, +measuring the number of pixels through which some part of the picture +has moved. Video direction also compares two snapshots to detect motion, +but what it reports is the direction (in the point in direction sense) +of the motion. So the script above moves the sprite in the direction in +which itā€™s being pushed, but only if a significant amount of motion is +found; otherwise the sprite would jiggle around too much. And yes, you +can run the second script without the first to push a balloon around the +stage.

+ +

Media Computation with Sounds {#media-computation-with-sounds .ListParagraph}

+ +

The starting point for computation with sound is the microphone block. +It starts by recording a brief burst of sound from your microphone. (How +brief? On my computer, 0.010667 seconds, but youā€™ll see shortly how to +ļ¬nd out or control the sample size on your computer.)

+ +

{width=ā€1.9652777777777777inā€ +height=ā€0.2569444444444444inā€}{width=ā€5.999305555555556inā€ +height=ā€2.620138888888889inā€}Just as the pixel is the smallest piece +of a picture, the sample is the smallest piece of a sound. It says +here: that on my computer, 48,000 samples are recorded per second, so +each sample is 1/48,000 of a second. The value of a sample is between -1 +and 1, and represents the sound pressure on the microphoneā€”how hard +the air is pushingā€”at that instant. (You can skip the next page or so +if you know about Fourier analysis.) Hereā€™s a picture of 400 samples:

+ +

In this graph, the x axis represents the time at which each sample was +measured; the y axis measures the value of the sample at that time. +The first obvious thing about this graph is that it has a lot of ups and +downs. The most basic up-and-down function is the sine wave:

+ +

Every periodic function (more or less, any sample that sounds like music +rather than sounding like static) is composed of a sum of sine waves of +different frequencies.

+ +

Look back at the graph of our sampled sound. There is a green dot every +seven samples. Thereā€™s nothing magic about the number seven; I tried +different values until I found one that looked right. What ā€œrightā€ means +is that, for the first few dots at least, they coincide almost perfectly +with the high points and low points of the graph. Near the middle +(horizontally) of the graph, the green dots donā€™t seem anywhere near the +high and low points, but if you find the very lowest point of the graph, +about 2/3 of the way along, the dots start lining up almost perfectly +again.

+ +

The red graph above shows two cycles of a sine wave. One cycle goes +up, then down, then up again. The amount of time taken for one cycle is +the period of the sine function. If the green dots match both ups and +downs in the captured sound, then two dotsā€”14 samples, or 14/48000 of +a secondā€”represent the period. The first cycle and a half of the graph +looks like it could be a pure sine wave, but after that, the tops and +bottoms donā€™t line up, and there are peculiar little jiggles, such as +the one before the fifth green dot. This happens because sine waves of +different periods are added together.

+ +

It turns out to be more useful to measure the reciprocal of the period, +in our case, 48000/14 or about 3429 cycles per second. Another name +for ā€œcycles per secondā€ is ā€œHertz,ā€ abbreviated Hz, so our sound has a +component at 3249 Hz. As a musical note, thatā€™s about an A (a little +flat), four octaves above middle C. (Donā€™t worry too much about the note +being a little off; remember that the 14-sample period was just +eyeballed and is unlikely to be exactly right.)

+ +

Four octaves above middle C is really high! That would be a +shrill-sounding note. But remember that a complex waveform is the sum of +multiple sine waves at different frequency. Hereā€™s a different +up-and-down regularity:

+ +

{width=ā€2.795138888888889inā€ +height=ā€1.2222222222222223inā€}{width=ā€2.7847222222222223inā€ +height=ā€1.0486111111111112inā€}Itā€™s not obvious, but in the left part of +the graph, the signal is more above the x axis than below it. Toward +the right, it seems to be more below than above the axis. At the very +right it looks like it might be climbing again.

+ +

The period of the red sine wave is 340 samples, or 340/48000 second. +Thatā€™s a frequency of about 141 Hz, about D below middle C. Again, this +is measuring by eyeball, but likely to be close to the right frequency.

+ +

All this eyeballing doesnā€™t seem very scientific. Canā€™t we just get the +computer to find all the relevant frequencies? Yes, we can, using a +mathematical technique called Fourier analysis. (Jean-Baptiste Joseph +Fourier, 1768ā€“1830, made many contributions to mathematics and physics, +but is best known for working out the nature of periodic functions as a +sum of sine waves.) Luckily we donā€™t have to do the math; the microphone +block will do it for us, if we ask for microphone spectrum:

+ +

{width=ā€7.493055555555555inā€ +height=ā€1.4861111111111112inā€}These are frequency spectra from (samples +of) three different songs. The most obvious thing about these graphs is +that their overall slope is downward; the loudest frequency is the +lowest frequency. Thatā€™s typical of music.

+ +

The next thing to notice is that thereā€™s a regularity in the spacing of +spikes in the graph. This is partly just an artifact; the frequency +(horizontal) axis isnā€™t continuous. There are a finite number of +ā€œbucketsā€ (default: 512), and all the frequencies within a bucket +contribute to the amplitude (vertical axis) of that bucket. The spectrum +is a list of that many amplitudes. But the patterns of alternating +rising and falling values are real; the frequencies that are multiples +of the main note being sampled will have higher amplitude than other +frequencies.

+ +

Samples and spectrum are the two most detailed representations of a +sound. But the microphone block has other, simpler options also:

+ +

volume the instantaneous volume when the block is called

+ +

note the MIDI note number (as in play note) of the main note heard

+ +

frequency the frequency in Hz of the main note heard

+ +

sample rate the number of samples being collected per second

+ +

{width=ā€2.9166666666666665inā€ +height=ā€0.28125inā€}resolution the size of the array in which data are +collected (typically 512, must be a power of 2)

+ +

The block for sounds that corresponds to new picture for pictures is

+ +

Its first input is a list of samples, and its second input specifies how +many samples occupy one second.

+ +

OOP with Procedures

+ +

The idea of object oriented programming is often taught in a way that +makes it seem as if a special object oriented programming language is +necessary. In fact, any language with ļ¬rst class procedures and lexical +scope allows objects to be implemented explicitly; this is a useful +exercise to help demystify objects.

+ +

The central idea of this implementation is that an object is represented +as a dispatch procedure that takes a message as input and reports the +corresponding method. In this section we start with a stripped-down +example to show how local state works, and build up to full +implementations of class/instance and prototyping OOP.

+ +

Local State with Script Variables

+ +

{width=ā€3.473611111111111inā€ +height=ā€3.1805555555555554inā€}{width=ā€2.2395833333333335inā€ +height=ā€1.5104166666666667inā€}This script implements an object class, +a type of object, namely the counter class. In this ļ¬rst simplified +version there is only one method, so no explicit message passing is +necessary. When the make a counter block is called, it reports a +procedure, the ringed script inside its body. That procedure implements +a specific counter object, an instance of the counter class. When +invoked, a counter instance increases and reports its count variable. +Each counter has its own local count:

+ +

This example will repay careful study, because it isnā€™t obvious why each +instance has a separate count. From the point of view of the make a +counter procedure, each invocation causes a new count variable to be +created. Usually such script variables are temporary, going out of +existence when the script ends. But this one is special, because make a +counter returns another script that makes reference to the count +variable, so it remains active. (The script variables block makes +variables local to a script. It can be used in a spriteā€™s script area or +in the Block Editor. Script variables can be ā€œexportedā€ by being used in +a reported procedure, as here.)

+ +

In this approach to OOP, we are representing both classes and instances +as procedures. The make a counter block represents the class, while each +instance is represented by a nameless script created each time make a +counter is called. The script variables created inside the make a +counter block but outside the ring are instance variables, belonging +to a particular counter.

+ +

Messages and Dispatch Procedures

+ +

{width=ā€4.416666666666667inā€ +height=ā€3.1666666666666665inā€}In the simplified class above, there is +only one method, and so there are no messages; you just call the +instance to carry out its one method. Here is a more refined version +that uses message passing:

+ +

Again, the make a counter block represents the counter class, and again +the script creates a local variable count each time it is invoked. The +large outer ring represents an instance. It is a dispatch procedure: +it takes a message (just a text word) as input, and it reports a method. +The two smaller rings are the methods. The top one is the next method; +the bottom one is the reset method. The latter requires an input, named +value.

+ +

In the earlier version, calling the instance did the entire job. In this +version, calling the instance gives access to a method, which must then +be called to finish the job. We can provide a block to do both procedure +calls in one:

+ +

{width=ā€4.010416666666667inā€ +height=ā€0.7077198162729659inā€}

+ +

The ask block has two required inputs: an object and a message. It also +accepts optional additional inputs, which Snap! puts in a list; that +list is named args inside the block. Ask has two nested call blocks. The +inner one calls the object, i.e., the dispatch procedure. The dispatch +procedure always takes exactly one input, namely the message. It reports +a method, which may take any number of inputs; note that this is the +situation in which we drop a list of values onto the arrowheads of a +multiple input (in the outer call block). Note also that this is one of +the rare cases in which we must unringify the inner call block, whose +value when called gives the method.

+ +

{width=ā€3.9069444444444446inā€ +height=ā€1.6125inā€}

+ +

Inheritance via Delegation

+ +

So, our objects now have local state variables and message passing. What +about inheritance? We can provide that capability using the technique of +delegation. Each instance of the child class contains an instance of +the parent class, and simply passes on the messages it doesnā€™t want to +specialize:

+ +

{width=ā€3.8125inā€ +height=ā€3.5833333333333335inā€}

+ +

This script implements the buzzer class, which is a child of counter. +Instead of having a count (a number) as a local state variable, each +buzzer has a counter (an object) as a local state variable. The class +specializes the next method, reporting what the counter reports unless +that result is divisible by 7, in which case it reports ā€œbuzz.ā€ (Yeah, +it should also check for a digit 7 in the number, but this code is +complicated enough already.) If the message is anything other than next, +though, such as reset, then the buzzer simply invokes its counterā€™s +dispatch procedure. So the counter handles any message that the buzzer +doesnā€™t handle explicitly. (Note that in the non-next case we call the +counter, not ask it something, because we want to report a method, not +the value that the message reports.) So, if we ask a buzzer to reset to +a value divisible by 7, it will end up reporting that number, not +ā€œbuzz.ā€

+ +

An Implementation of Prototyping OOP

+ +

In the class/instance system above, it is necessary to design the +complete behavior of a class before you can make any instances of the +class. This is okay for top-down design, but not great for +experimentation. Here we sketch the implementation of a prototyping +OOP system: You make an object, tinker with it, make clones of it, and +keep tinkering. Any changes you make in the parent are inherited by its +children. In effect, that first object is both the class and an instance +of the class. In the implementation below, children share properties +(methods and local variables) of their parent unless and until a child +changes a property, at which point that child gets a private copy. (If a +child wants to change something for its entire family, it must ask the +parent to do it.)

+ +

Because we want to be able to create and delete properties dynamically, +we wonā€™t use Snap! variables to hold an objectā€™s variables or methods. +Instead, each object has two tables, called methods and data, each of +which is an association list: a list of two-item lists, in which each +of the latter contains a key and a corresponding value. We provide a +lookup procedure to locate the key-value pair corresponding to a given +key in a given table.

+ +

{width=ā€3.2152777777777777inā€ +height=ā€2.361111111111111inā€}

+ +

{width=ā€2.625inā€ +height=ā€0.78125inā€}

+ +

{width=ā€5.604166666666667inā€ +height=ā€1.15625inā€}{width=ā€5.604166666666667inā€ +height=ā€1.15625inā€}

+ +

There are also commands to insert and delete entries:

+ +

{width=ā€3.71875inā€ +height=ā€1.8263888888888888inā€}{width=ā€3.2291666666666665inā€ +height=ā€2.1283136482939633inā€}

+ +

As in the class/instance version, an object is represented as a dispatch +procedure that takes a message as its input and reports the +corresponding method. When an object gets a message, it will ļ¬rst look +for that keyword in its methods table. If itā€™s found, the corresponding +value is the method we want. If not, the object looks in its data table. +If a value is found there, what the object returns is not that value, +but rather a reporter method that, when called, will report the value. +This means that what an object returns is always a method.

+ +

If the object has neither a method nor a datum with the desired name, +but it does have a parent, then the parent (that is, the parentā€™s +dispatch procedure) is invoked with the message as its input. +Eventually, either a match is found, or an object with no parent is +found; the latter case is an error, meaning that the user has sent the +object a message not in its repertoire.

+ +

Messages can take any number of inputs, as in the class/instance system, +but in the prototyping version, every method automatically gets the +object to which the message was originally sent as an extra ļ¬rst input. +We must do this so that if a method is found in the parent (or +grandparent, etc.) of the original recipient, and that method refers to +a variable or method, it will use the childā€™s variable or method if the +child has its own version.

+ +

{width=ā€4.375inā€ +height=ā€7.469444444444444inā€}The clone of block below takes an object as +its input and makes a child object. It should be considered as an +internal part of the implementation; the preferred way to make a child +of an object is to send that object a clone message.

+ +

{width=ā€1.5729166666666667inā€ +height=ā€0.6875inā€}Every object is created with predefined methods for +set, method, delete-var, delete-method, and clone. It has one predefined +variable, parent. Objects without a parent are created by calling new +object:

+ +

As before, we provide procedures to call an objectā€™s dispatch procedure +and then call the method. But in this version, we provide the desired +object as the ļ¬rst method input. We provide one procedure for Command +methods and one for Reporter methods:

+ +

{width=ā€6.938888888888889inā€ +height=ā€1.0inā€}(Remember that the ā€œInput list:ā€ variant of the run and +call blocks is made by dragging the input expression over the arrowheads +rather than over the input slot.)

+ +

The script below demonstrates how this prototyping system can be used to +make counters. We start with one prototype counter, called counter1. We +count this counter up a few times, then create a child counter2 and give +it its own count variable, but not its own total variable. The next +method always sets counter1ā€™s total variable, which therefore keeps +count of the total number of times that any counter is incremented. +Running this script should [say] and (think) the following lists:

+ +

{width=ā€4.208333333333333inā€ +height=ā€4.395833333333333inā€}[1 1] [2 2] [3 3] [4 4] (1 5) (2 6) +(3 7) [5 8] [6 9] [7 10] [8 11]

+ +

The Outside World

+ +

{width=ā€1.6201388888888888inā€ +height=ā€0.25inā€}The facilities discussed so far are fine for projects +that take place entirely on your computerā€™s screen. But you may want to +write programs that interact with physical devices (sensors or robots) +or with the World Wide Web. For these purposes Snap! provides a single +primitive block:

+ +

This might not seem like enough, but in fact it can be used to build the +desired capabilities.

+ +

The World Wide Web

+ +

The input to the url block is the URL (Uniform Resource Locator) of a +web page. The block reports the body of the Web serverā€™s response (minus +HTTP header), without interpretation. This means that in most cases +the response is a description of the page in HTML (HyperText Markup +Language) notation. Often, especially for commercial web sites, the +actual information youā€™re trying to find on the page is actually at +another URL included in the reported HTML. The Web page is typically a +very long text string, and so the primitive split block is useful to get +the text in a manageable form, namely, as a list of lines:

+ +

{width=ā€6.520833333333333inā€ +height=ā€4.277777777777778inā€}

+ +

The second input to split is the character to be used to separate the +text string into a list of lines, or one of a set of common cases (such +as line, which separates on carriage return and/or newline characters.

+ +

This might be a good place for a reminder that list-view watchers scroll +through only 100 items at a time. The downarrow near the bottom right +corner of the speech balloon in the picture presents a menu of +hundred-item ranges. (This may seem unnecessary, since the scroll bar +should allow for any number of items, but doing it this way makes +Snap! much faster.) In table view, the entire list is included.

+ +

If you include a protocol name in the input to the url block (such as +http:// or https://), that protocol will be used. If not, the block +first tries HTTPS and then, if that fails, HTTP.

+ +

A security restriction in JavaScript limits the ability of one web site +to initiate communication with another site. There is an official +workaround for this limitation called the CORS protocol (Cross-Origin +Resource Sharing), but the target site has to allow snap.berkeley.edu +explicitly, and of course most donā€™t. To get around this problem, you +can use third-party sites (ā€œcors proxiesā€) that are not limited by +JavaScript and that forward your requests.

+ +

Hardware Devices

+ +

Another JavaScript security restriction prevents Snap! from having +direct access to devices connected to your computer, such as sensors and +robots. (Mobile devices such as smartphones may also have useful devices +built in, such as accelerometers and GPS receivers.) The url block is +also used to interface Snap! with these external capabilities.

+ +

The idea is that you run a separate program that both interfaces with +the device and provides a local HTTP server that Snap! can use to make +requests to the device. Unlike Snap! itself, these programs have +access to anything on your computer, so you have to trust the author of +the software! Our web site, snap.berkeley.edu, provides links to +drivers for several devices, including, at this writing, the Lego NXT, +Finch, Hummingbird, and Parallax S2 robots; the Nintendo Wiimote and +Leap Motion sensors, the Arduino microcomputer, and Super-Awesome +Sylviaā€™s Water Color Bot. The same server technique can be used for +access to third party software libraries, such as the speech synthesis +package linked on our web site.

+ +

Most of these packages require some expertise to install; the links are +to source code repositories. This situation will improve with time.

+ +

Date and Time

+ +

{width=ā€5.305555555555555inā€ +height=ā€0.3194444444444444inā€}The current block in the Sensing palette +can be used to find out the current date or time. Each call to this +block reports one component of the date or time, so you will probably +combine several calls, like this:

+ +

{width=ā€5.305555555555555inā€ +height=ā€0.3194444444444444inā€}for Americans, or like this:

+ +

for Europeans.

+ +

Continuations

+ +

Blocks are usually used within a script. The continuation of a block +within a particular script is the part of the computation that remains +to be completed after the block does its job. A continuation can be +represented as a ringed script. Continuations are always part of the +interpretation of any program in any language, but usually these +continuations are implicit in the data structures of the language +interpreter or compiler. Making continuations explicit is an advanced +but versatile programming technique that allows users to create control +structures such as nonlocal exit and multithreading.

+ +

{width=ā€1.40625inā€ +height=ā€1.5416666666666667inā€}In the simplest case, the continuation of +a command block may just be the part of the script after the block. For +example, in the script

+ +

{width=ā€1.59375inā€ +height=ā€0.7083333333333334inā€}the continuation of the move 100 steps +block is

+ +

{width=ā€1.4784722222222222inā€ +height=ā€0.8020833333333334inā€}But some situations are more complicated. +For example, what is the continuation of move 100 steps in the following +script?

+ +

{width=ā€1.6666666666666667inā€ +height=ā€1.0729166666666667inā€}Thatā€™s a trick question; the move block is +run four times, and it has a different continuation each time. The first +time, its continuation is

+ +

Note that there is no repeat 3 block in the actual script, but the +continuation has to represent the fact that there are three more times +through the loop to go. The fourth time, the continuation is just

+ +

{width=ā€1.59375inā€ +height=ā€0.29791666666666666inā€}What counts is not whatā€™s physically +below the block in the script, but what computational work remains to be +done.

+ +

(This is a situation in which visible code may be a little misleading. +We have to put a repeat 3 block in the picture of the continuation, +but the actual continuation is made from the evaluatorā€™s internal +bookkeeping of where itā€™s up to in a script. So itā€™s really the original +script plus some extra information. But the pictures here do correctly +represent what work the process still has left to do.)
+{width=ā€1.4791666666666667inā€ +height=ā€1.25inā€}When a block is used inside a custom block, its +continuation may include parts of more than one script. For example, if +we make a custom square block

+ +

and then use that block in a script:

+ +

{width=ā€0.7291666666666666inā€ +height=ā€0.59375inā€}then the continuation of the first use of move 100 +steps is

+ +

{width=ā€1.6666666666666667inā€ +height=ā€1.2604166666666667inā€}in which part comes from inside the square +block and part comes from the call to square. Nevertheless, ordinarily +when we display a continuation we show only the part within the +current script.

+ +

{width=ā€2.1875inā€ +height=ā€0.5729166666666666inā€}The continuation of a command block, as +weā€™ve seen, is a simple script with no input slots. But the continuation +of a reporter block has to do something with the value reported by the +block, so it takes that value as input. For example, in the script

+ +

the continuation of the 3+4 block is

+ +

{width=ā€3.5729166666666665inā€ +height=ā€0.5729166666666666inā€}Of course the name result in that picture +is arbitrary; any name could be used, or no name at all by using the +empty-slot notation for input substitution.

+ +

Continuation Passing Style

+ +

Like all programming languages, Snap! evaluates compositions of nested +reporters from the inside out. For example, in the expression +{width=ā€1.3125inā€ +height=ā€0.22916666666666666inā€}Snap! first adds 4 and 5, then +multiplies 3 by that sum. This often means that the order in which the +operations are done is backwards from the order in which they appear in +the expression: When reading the above expression you say ā€œtimesā€ before +you say ā€œplus.ā€ In English, instead of saying ā€œthree times four plus +five,ā€ which actually makes the order of operations ambiguous, you could +say, ā€œtake the sum of four and five, and then take the product of three +and that sum.ā€ This sounds more awkward, but it has the virtue of +putting the operations in the order in which theyā€™re actually performed.

+ +

{width=ā€3.1875inā€ +height=ā€0.3541666666666667inā€}That may seem like overkill in a simple +expression, but suppose youā€™re trying to convey the expression

+ +

to a friend over the phone. If you say ā€œfactorial of three times +factorial of two plus two plus fiveā€ you might mean any of these:

+ +

{width=ā€3.1875inā€ +height=ā€1.71875inā€}{width=ā€7.490277777777778inā€ +height=ā€3.622916666666667inā€}Wouldnā€™t it be better to say, ā€œAdd two and +two, take the factorial of that, add five to that, multiply three by +that, and take the factorial of the resultā€? We can do a similar +reordering of an expression if we first define versions of all the +reporters that take their continuation as an explicit input. In the +following picture, notice that the new blocks are commands, not +reporters.

+ +

{width=ā€4.052777777777778inā€ +height=ā€1.6354166666666667inā€}We can check that these blocks give the +results we want:

+ +

{width=ā€5.533333333333333inā€ +height=ā€2.3180555555555555inā€}The original expression can now be +represented as

+ +

{width=ā€2.1930555555555555inā€ +height=ā€1.0527777777777778inā€}If you read this top to bottom, donā€™t you +get ā€œAdd two and two, take the factorial of that, add five to that, +multiply three by that, and take the factorial of the resultā€? Just what +we wanted! This way of working, in which every block is a command that +takes a continuation as one of its inputs, is called +continuation-passing style (CPS). Okay, it looks horrible, but it has +subtle virtues. One of them is that each script is just one block long +(with the rest of the work buried in the continuation given to that one +block), so each block doesnā€™t have to remember what else to doā€”in the +vocabulary of this section, the (implicit) continuation of each block is +empty. Instead of the usual picture of recursion, with a bunch of little +people all waiting for each other, with CPS what happens is that each +little person hands off the problem to the next one and goes to the +beach, so thereā€™s only one active little person at a time. In this +example, we start with Alfred, an add specialist, who computes the value +4 and then hands off the rest of the problem to Francine, a factorial +specialist. She computes the value 24, then hands the problem off to +Anne, another add specialist, who computes 29. And so on, until finally +Sam, a say specialist, says the value 2.107757298379527Ɨ10^132^, which +is a very large number!

+ +

Go back to the definitions of these blocks. The ones, such as add, that +correspond to primitive reporters are simple; they just call the +reporter and then call their continuation with its result. But the +definition of factorial is more interesting. It doesnā€™t just call our +original factorial reporter and send the result to its continuation. CPS +is used inside factorial too! It says, ā€œSee if my input is zero. Send +the (true or false) result to if. If the result is true, then call my +continuation with the value 1. Otherwise, subtract 1 from my input. Send +the result of that to factorial, with a continuation that multiplies the +smaller numberā€™s factorial by my original input. Finally, call my +continuation with the product.ā€ You can use CPS to unwind even the most +complicated branched recursions.

+ +

By the way, I cheated a bit above. The if/else block should also use +CPS; it should take one true/false input and two continuations. It +will go to one or the other continuation depending on the value of its +input. But in fact the C-shaped blocks (or E-shaped, like if/else) are +really using CPS in the first place, because they implicitly wrap rings +around the sub-scripts within their branches. See if you can make an +explicitly CPS if/else block.

+ +

Call/Run w/Continuation

+ +

To use explicit continuation passing style, we had to define special +versions of all the reporters, add and so on. Snap! provides a +primitive mechanism for capturing continuations when we need to, without +using continuation passing throughout a project.

+ +

Hereā€™s the classic example. We want to write a recursive block that +takes a list of numbers as input, and reports the product of all the +numbers:

+ +

{width=ā€3.8958333333333335inā€ +height=ā€1.9375inā€}{width=ā€3.8958333333333335inā€ +height=ā€1.3416666666666666inā€}But we can improve the efficiency of this +block, in the case of a list that includes a zero; as soon as we see the +zero, we know that the entire product is zero.

+ +

But this is not as efficient as it might seem. Consider, as an example, +the list 1,2,3,0,4,5. We find the zero on the third recursive call (the +fourth call altogether), as the first item of the sublist 0,4,5. What is +the continuation of the report 0 block? Itā€™s

+ +

{width=ā€4.333333333333333inā€ +height=ā€0.4166666666666667inā€}Even though we already know that result is +zero, weā€™re going to do three unnecessary multiplications while +unwinding the recursive calls.

+ +

{width=ā€4.038194444444445inā€ +height=ā€1.9256944444444444inā€}{width=ā€3.9451388888888888inā€ +height=ā€1.0979166666666667inā€}We can improve upon this by capturing the +continuation of the top-level call to product:

+ +

{width=ā€2.7083333333333335inā€ +height=ā€0.2916666666666667inā€}The +{width=ā€1.59125inā€ +height=ā€0.18611111111111112inā€} block takes as its input a one-input +script, as shown in the product example. It calls that script with the +continuation of the call-with-continuation block itself as its input. +In this case, that continuation is

+ +

{width=ā€4.40625inā€ +height=ā€1.15625inā€}reporting to whichever script called product. If the +input list doesnā€™t include a zero, then nothing is ever done with that +continuation, and this version works just like the original product. But +if the input list is 1,2,3,0,4,5, then three recursive calls are made, +the zero is seen, and product-helper runs the continuation, with an +input of 0. The continuation immediately reports that 0 to the caller of +product, without unwinding all the recursive calls and without the +unnecessary multiplications.

+ +

{width=ā€4.385416666666667inā€ +height=ā€0.5104166666666666inā€}I could have written product a little more +simply using a Reporter ring instead of a Command ring:

+ +

but itā€™s customary to use a script to represent the input to +callĀ w/continuation because very often that input takes the form

+ +

so that the continuation is saved permanently and can be called from +anywhere in the project. Thatā€™s why the input slot in call +w/continuation has a Command ring rather than a Reporter ring.

+ +

First class continuations are an experimental feature in Snap! and +there are many known limitations in it. One is that the display of +reporter continuations shows only the single block in which the call +w/continuation is an input.

+ +

Nonlocal exit

+ +

{width=ā€6.268055555555556inā€ +height=ā€1.125inā€}Many programming languages have a break command that +can be used inside a looping construct such as repeat to end the +repetition early. Using first class continuations, we can generalize +this mechanism to allow nonlocal exit even within a block called from +inside a loop, or through several levels of nested loops:

+ +

{width=ā€1.8541666666666667inā€ +height=ā€2.6534722222222222inā€}The upvar break has as its value a +continuation that can be called from anywhere in the program to jump +immediately to whatever comes after the catch block in its script. +Hereā€™s an example with two nested invocations of catch, with the upvar +renamed in the outer one:

+ +

As shown, this will say 1, then 2, then 3, then exit both nested catches +and think ā€œHmm.ā€ If in the run block the variable break is used instead +of outer, then the script will say 1, 2, 3, and ā€œHello!ā€ before thinking +ā€œHmm.ā€

+ +

{width=ā€4.354166666666667inā€ +height=ā€1.4708333333333334inā€}There are corresponding catch and throw +blocks for reporters. The catch block is a reporter that takes an +expression as input instead of a C-shaped slot. But the throw block is a +command; it doesnā€™t report a value to its own continuation, but instead +reports a value (which it takes as an additional input, in addition to +the catch tag) to the corresponding catch blockā€™s continuation:

+ +

Without the throw, the inner call reports 5, the + block reports 8, so +the catch block reports 8, and the Ɨ block reports 80. With the throw, +the inner call doesnā€™t report at all, and neither does the + block. The +throw blockā€™s input of 20 becomes the value reported by the catch block, +and the Ɨ block multiplies 10 and 20.
+Creating a Thread System

+ +

Snap! can be running several scripts at once, within a single sprite +and across many sprites. If you only have one computer, how can it do +many things at once? The answer is that only one is actually running at +any moment, but Snap! switches its attention from one script to +another frequently. At the bottom of every looping block (repeat, repeat +until, forever), there is an implicit ā€œyieldā€ command, which remembers +where the current script is up to, and switches to some other script, +each in turn. At the end of every script is an implicit ā€œend threadā€ +command (a thread is the technical term for the process of running a +script), which switches to another script without remembering the old +one.

+ +

{width=ā€2.9479166666666665inā€ +height=ā€4.254166666666666inā€}{width=ā€6.5569444444444445inā€ +height=ā€2.770138888888889inā€}Since this all happens automatically, there +is generally no need for the user to think about threads. But, just to +show that this, too, is not magic, here is an implementation of a simple +thread system. It uses a global variable named tasks that initially +contains an empty list. Each use of the C-shaped thread block adds a +continuation (the ringed script) to the list. The yield block uses run +w/continuation to create a continuation for a partly done thread, adds +it to the task list, and then runs the first waiting task. The +endĀ thread block (which is automatically added at the end of every +threadā€™s script by the thread block) just runs the next waiting task.

+ +

Here is a sample script using the thread system. One thread says +numbers; the other says letters. The number thread yields after every +prime number, while the letter thread yields after every vowel. So the +sequence of speech balloons is +1,2,a,3,b,c,d,e,4,5,f,g,h,i,6,7,j,k,l,m,n,o,8,9,10,11, +p,q,r,s,t,u,12,13,v,w,x,y,z,14,15,16,17,18,ā€¦30.

+ +

If we wanted this to behave exactly like Snap!ā€™s own threads, weā€™d +define new versions of repeat and so on that run yield after each +repetition.

+ +

Metaprogramming

+ +

The scripts and custom blocks that make up a program can be examined or +created by the program itself.

+ +

{width=ā€7.4945702099737534inā€ height=ā€2.0380686789151357inā€}Reading a block

+ +

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.

+ +

{width=ā€7.4inā€ +height=ā€2.51inā€}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.

+ +

{width=ā€7.496969597550306inā€ +height=ā€2.079861111111111inā€}Using split by blocks to select custom +blocks whose definitions contain another block gives us this debugging +aid:

+ +

Note in passing the my blocks block, which reports a list of all visible +blocks, primitive and custom. (Thereā€™s also a my categories block, which +reports a list of the names of the palette categories.) Also note +custom? of block, which reports True if its input is a custom block.

+ +

Writing a block

+ +

{width=ā€6.071211723534558inā€ +height=ā€2.209722222222222inā€}The inverse function to split by blocks is +provided by the join block, which when given a syntax tree as input +reports the corresponding expression or script.

+ +

Here we are taking the definition of square, modifying the repetition +count (to 6), modifying the turning angle (to 60), using join to turn +the result back into a ringed definition, and using the define block to +create a new hexagon block.

+ +

The define block has three ā€œinputā€ slots. The quotation marks are there +because the first slot is an upvar, i.e., a way for define to provide +information to its caller, rather than the other way around. In this +case, the value of block is the new block itself (the hexagon block, in +this example). The second slot is where you give the label for the new +block. In this example, the label is ā€œhexagon _ā€ in which the +underscore represents an input slot. So, here are a few examples of +block labels:

+ +

set pen _ to _

+ +

for _ = _ to _ _

+ +

ask _ and wait

+ +

_ of _

+ +

Note that the underscores are separated from the block text by spaces. +Note in the case of the for blockā€™s label that the upvar (the i) and the +C-slot both count as inputs. Note also that the label is not meant to be +a unique symbol that represents only this block. For example, +{width=ā€0.8611111111111112inā€ +height=ā€0.19444444444444445inā€} and A picture containing text, hitting
+Description automatically
+generated{width=ā€1.15inā€ +height=ā€0.19inā€} both have the label

+ +

_ of _. The label does not give the input slots names (thatā€™s done in +the body, coming next) or types (thatā€™s done in the set _ of block _ +to _ block, coming in two paragraphs).

+ +

The third slot is for the definition of the new block. This is a +(ringed) script whose input names (formal parameters) will become the +formal parameters of the new block. And the script is its script.

+ +

So far we know the blockā€™s label, parameters, and script. There are +other things to specify about the block, and one purpose of the block +upvar is to allow that. In the example on the previous page, there are +four

+ +

{width=ā€2.83inā€ +height=ā€0.97inā€}set _ of block _ to _ blocks, reproduced below for +your convenience:

+ +

The category of the block can be set to any primitive or custom +category. The default is other. The type is command, reporter, or +predicate. Command is the default, so this setting is redundant, but we +want to show all the choices in the set block. The scope is either +global or sprite, with global as the default. The last input to set +slots is a list of length less than or equal to the number of +underscores in the label. Each item of the list is a type name, like the +ones in the is (5) a (number)? block. If there is only one input, you +can use just the name instead of putting it in a list. An empty or +missing list item means type Any.

+ +

{width=ā€4.31inā€ +height=ā€0.83inā€}It's very important that these set blocks appear in the +same script as the define that creates the block, because the block +upvar is local to that script. You canā€™t later say, for example,

+ +

because the copy of the hexagon block in this instruction counts as +ā€œusingā€ it.

+ +

{width=ā€2.6inā€ +height=ā€0.32inā€}The of block reporter is useful to copy attributes from +one block to another, as we copied the definition of square, modified +it, and used it to define hexagon. Some of the values this block reports +are a little unfriendly:

+ +

ā€œ1ā€? Yes, this block reports numbers instead of names for category, +type, and scope. The reason is that maybe someday weā€™ll have +translations to other languages for custom category names, as we already +do for the built-in categories, types, and scopes; if you translate a +program using this block to another language, the numeric outputs wonā€™t +change, simplifying comparisons in your code. The set block accepts +these numbers as an alternative to the names.

+ +

{width=ā€3.379861111111111inā€ +height=ā€0.3798611111111111inā€}{width=ā€1.02inā€ +height=ā€0.25inā€}There are a few more attributes of a block, less +commonly used.

+ +

{width=ā€3.5194444444444444inā€ +height=ā€0.6194444444444445inā€}{width=ā€1.9314370078740157inā€ +height=ā€0.6102252843394576inā€}{width=ā€3.2909722222222224inā€ +height=ā€0.6097222222222223inā€}{width=ā€2.35inā€ +height=ā€2.56inā€}{width=ā€1.6694444444444445inā€ +height=ā€0.25inā€}The list input is just like the one for set slots except +for default values instead of types. Now for a block with a menu input:

+ +

{width=ā€4.169444444444444inā€ +height=ā€1.2694444444444444inā€}We passed too quickly over how the script +turned the square block into a hexagon block:

+ +

{width=ā€6.677272528433946inā€ +height=ā€3.6666666666666665inā€}Those replace item blocks arenā€™t very +elegant. I had to look at foo by hand to figure out where the numbers I +wanted to change are. This situation can be improved with a little +programming:

+ +

Exercise for the reader: Implement this:Graphical user interface
+Description automatically
+generated{width=ā€3.11inā€ +height=ā€0.57inā€}

+ +

{width=ā€7.501514654418198inā€ +height=ā€2.109722222222222inā€}Returning to the define block, thereā€™s +another reason for the block upvar: Itā€™s helpful in defining a recursive +procedure using define. For a procedure to call itself, it needs a name +for itself. But in the definition input to the define block, define +itself hasnā€™t been called yet, so the new block isnā€™t in the palette +yet. So you do this:

+ +

Yes, you put block in the define, but it gets changed into this script +in the resulting definition. You could use this script directly in a +simple case like this, but in a complicated case with a recursive call +inside a ring inside the one giving the block definition, this script +always means the innermost ring. But the upvar means the outer +{width=ā€7.5inā€ +height=ā€0.5354166666666667inā€}{width=ā€4.809722222222222inā€ +height=ā€0.4inā€}{width=ā€4.809722222222222inā€ +height=ā€1.4895833333333333inā€}ring:

+ +

Itā€™s analogous to using explicit formal parameters when you nest calls +to higher order functions.

+ +

{width=ā€5.76875inā€ height=ā€3.879861111111111inā€}Macros

+ +

Users of languages in the C family have learned to think of macros as +entirely about text strings, with no relation to the syntax of the +language. So you can do things like

+ +

#define foo baz)

+ +

with the result that you can only use the foo macro after an open +parenthesis.

+ +

In the Lisp family of languages we have a different tradition, in which +macros are syntactically just like procedure calls, except that the +ā€œprocedureā€ is a macro, with different evaluation rules from ordinary +procedures. Two things make a macro different: its input expressions are +not evaluated, so a macro can establish its own syntax (but still +delimited by parentheses, in Lisp, or still one block, in Snap! ); and +the result of a macro call is a new expression that is evaluated as if +it appeared in the caller of the macro, with access to the callerā€™s +variables and, implicitly, its continuation.

+ +

Snap! has long had the first part of this, the ability to make inputs +unevaluated. In version 8.0 we add the ability to run code in the +context of another procedure, just as we can run code in the context of +another sprite, using the same mechanism: the of block. In the example +on the previous page, the if _ report _ caller block runs a report +block, but not in its own context; it causes the fizzbuzz block to +report ā€œfizzā€ or ā€œbuzzā€ as appropriate. (Yes, we know that the rules +implemented here are simplified compared to the real game.) It doesnā€™t +just report out of the entire toplevel script; you can see that map is +able to prepend ā€œThe answer isā€ to each reported value.

+ +

This macro capability isnā€™t fully implemented. First, we shouldnā€™t have +to use the calling script as an explicit input to the macro. In a later +release, this will be fixed; when defining a block youā€™ll be able to say +that itā€™s a macro, and it will automatically get its callerā€™s context as +an invisible input. Second, there is a possibility of confusion between +the variables of the macro and the variables of its caller. (What if the +macro wanted to refer to a variable value in its caller?) The one +substantial feature of Scheme that we donā€™t yet implement is hygienic +macros, which make it possible to keep the two namespaces separate.

+ +

User Interface Elements

+ +

In this chapter we describe in detail the various buttons, menus, and +other clickable elements of the Snap! user interface. Here again is +the map of the Snap! window:

+ +

{width=ā€7.494419291338582inā€ +height=ā€4.663194444444445inā€}

+ +

Tool Bar Features

+ +

Holding down the Shift key while clicking on any of the menu buttons +gives access to an extended menu with options, shown in red, that are +experimental or for use by the developers. Weā€™re not listing those extra +options here because they change frequently and you shouldnā€™t rely on +them. But theyā€™re not secrets.

+ +

The Snap! Logo Menu

+ +

The Snap! logo at the left end of the tool bar is clickable. It shows +a menu of options about Snap! itself:

+ +

{width=ā€2.3292213473315835inā€ +height=ā€1.02inā€}

+ +

The About option displays information about Snap! itself, including +version numbers for the source modules, the implementors, and the +license (AGPL: you can do anything with it except create proprietary +versions, basically).

+ +

The Reference manual option downloads a copy of the latest revision of +this manual in PDF format.

+ +

The Snap! website option opens a browser window pointing to +snap.berkeley.edu, the web site for Snap!.

+ +

The Download source option opens a browser window displaying the Github +repository of the source files for Snap!. At the bottom of the page +are links to download the latest official release. Or you can navigate +around the site to find the current development version. You can read +the code to learn how Snap! is implemented, host a copy on your own +computer (this is one way to keep working while on an airplane), or make +a modified version with customized features. (However, access to cloud +accounts is limited to the official version hosted at Berkeley.)

+ +

The File Menu

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}The file icon shows a menu mostly about +saving and loading projects. You may not see all these options, if you +donā€™t have multiple sprites, scenes, custom blocks, and custom +categories.

+ +

The Notes option opens a window in which you can type notes about the +project: How to use it, what it does, whose project you modified to +create it, if any, what other sources of ideas you used, or any other +information about the project. This text is saved with the project, and +is useful if you share it with other users.

+ +

The New option starts a new, empty project. Any project you were working +on before disappears, so you are asked to confirm that this is really +what you want. (It disappears only from the current working Snap! +window; you should save the current project, if you want to keep it, +before using New.)

+ +

Note the \^N at the end of the line. This indicates that you can type +control-N as a shortcut for this menu item. Alas, this is not the case +in every browser. Some Mac browsers require command-N (āŒ˜N) instead, +while others open a new browser window instead of a new project. Youā€™ll +have to experiment. In general, the keyboard shortcuts in Snap! are +the standard ones you expect in other software.

+ +

{width=ā€2.8895833333333334inā€ +height=ā€2.097916666666667inā€}The Openā€¦ option shows a project open +dialog box in which you can choose a project to open:

+ +

In this dialog, the three large buttons at the left select a source of +projects: Cloud means your Snap! accountā€™s cloud storage. Examples +means a collection of sample projects we provide. Computer is for +projects saved on your own computer; when you click it, this dialog is +replaced with your computerā€™s system dialog for opening files. The text +box to the right of those buttons is an alphabetical listing of projects +from that source; selecting a project by clicking shows its thumbnail (a +picture of the stage when it was saved) and its project notes at the +right.

+ +

{width=ā€2.7243055555555555inā€ +height=ā€1.9777777777777779inā€}The search bar at the top can be used to +find a project by name or text in the project notes. So in this example:

+ +

{width=ā€2.723611111111111inā€ +height=ā€1.9777777777777779inā€}I was looking for my ice cream projects +and typed ā€œcreaā€ in the search bar, then wondered why ā€œferrisā€ matched. +But then when I clicked on ferris I saw this:

+ +

My search matched the word ā€œrecreateā€ in the project notes.

+ +

The six buttons at the bottom select an action to perform on the +selected project. In the top row, Recover looks in your cloud account +for older versions of the chosen project. If your project is damaged, +donā€™t keep saving broken versions! Use Recover first thing. You will +see a list of saved versions; choose one to open it. Typically, youā€™ll +see the most recent version before the last save, and the newest version +saved before today. Then come buttons Share/Unshare and +Publish/Unpublish. The labelling of the buttons depends on your +projectā€™s publication status. If a project is neither shared nor +published (the ones in lightface type in the project list), it is +private and nobody can see it except you, its owner. If it is shared +(boldface in the project list), then when you open it youā€™ll see a URL +like this one:

+ +

https://snap.berkeley.edu/snapsource/snap.html#present:Username=bh&ProjectName=count%20change

+ +

but with your username and project name. (ā€œ%20ā€ in the project name +represents a space, which canā€™t be part of a URL.) Anyone who knows this +URL can see your project. Finally, if your project is published +(bold italic in the list), then your project is shown on the +Snap! web site for all the world to see. (In all of these cases, you +are the only one who can write to (save) your project. If another user +saves it, a separate copy will be saved in that userā€™s account. Projects +remember the history of who created the original version and any other +ā€œremixā€ versions along the way.

+ +

In the second row, the first button, Open, loads the project into +Snap! and closes the dialog box. The next button (if Cloud is the +source) is Delete, and if clicked it deletes the selected project. +Finally, the Cancel button closes the dialog box without opening a +project. (It does not undo any sharing, unsharing, or deletion youā€™ve +done.)

+ +

Back to the File menu, the Save menu option saves the project to the +same source and same name that was used when opening the project. (If +you opened another userā€™s shared project or an example project, the +project will be saved to your own cloud account. You must be logged in +to save to the cloud.)

+ +

{width=ā€3.236111111111111inā€ +height=ā€2.3493055555555555inā€}The Save asā€¦ menu option opens a dialog +box in which you can specify where to save the project:

+ +

This is much like the Open dialog, except for the horizontal text box at +the top, into which you type a name for the project. You can also +publish, unpublish, share, unshare, and delete projects from here. There +is no Recover button.

+ +

The Importā€¦ menu option is for bringing some external resource into +the current project, or it can load an entirely separate project, from +your local disk. You can import costumes (any picture format that your +browser supports), sounds (again, any format supported by your browser), +and block libraries or sprites (XML format, previously exported from +Snap! itself). Imported costumes and sounds will belong to the +currently selected sprite; imported blocks are global (for all sprites). +Using the Import option is equivalent to dragging the file from your +desktop onto the Snap! window.

+ +

Depending on your browser, the Export projectā€¦ option either directly +saves to your disk or opens a new browser tab containing your complete +project in XML notation (a plain text format). You can then use the +browserā€™s Save feature to save the project as an XML file, which should +be named something.xml so that Snap! will recognize it as a project +when you later drag it onto a Snap! window. This is an alternative to +saving the project to your cloud account: keeping it on your own +computer. It is equivalent to choosing Computer from the Save dialog +described earlier.

+ +

The Export summaryā€¦ option creates a web page, in HTML, with all of +the information about your project: its name, its project notes, a +picture of whatā€™s on its stage, definitions of global blocks, and then +per-sprite information: name, wardrobe (list of costumes), and local +variables and block definitions. The page can be converted to PDF by the +browser; itā€™s intended to meet the documentation requirements of the +Advanced Placement Computer Science Principles create task.

+ +

The Export blocksā€¦ option is used to create a block library. It +presents a list of all the global (for all sprites) blocks in your +project, and lets you select which to export. It then opens a browser +tab with those blocks in XML format, or stores directly to your local +disk, as with the Export project option. Block libraries can be imported +with the Import option or by dragging the file onto the Snap! window. +This option is shown only if you have defined custom blocks.

+ +

The Unused blocksā€¦ option presents a listing of all the global custom +blocks in your project that arenā€™t used anywhere, and offers to delete +them. As with Export blocks, you can choose a subset to delete with +checkboxes. This option is shown only if you have defined custom blocks.

+ +

The Hide blocksā€¦ option shows all blocks, including primitives, with +checkboxes. This option does not remove any blocks from your project, +but it does hide selected block in your palette. The purpose of the +option is to allow teachers to present students with a simplified +Snap! with some features effectively removed. The hiddenness of +primitives is saved with each project, so students can load a shared +project and see just the desired blocks. But users can always unhide +blocks by choosing this option and unclicking all the checkboxes. +(Right-click in the background of the dialog box to get a menu from +which you can check all boxes or uncheck all boxes.)

+ +

The New categoryā€¦ option allows you to add your own categories to the +palette. It opens a dialog box in which you specify a name and a color +for the category. (A lighter version of the same color will be used for +the zebra coloring feature.)

+ +

The Remove a categoryā€¦ option appears only if youā€™ve created custom +categories. It opens a very small, easy-to-miss menu of category names +just under the file icon in the menu bar. If you remove a category that +has blocks in it, all those blocks are also removed.

+ +

{width=ā€1.1666666666666667inā€ +height=ā€0.19791666666666666inā€}The next group of options concern the +scenes feature, new in Snap! 7.0. A scene is a complete project, +with its own stage, sprites, and code, but several can be merged into +one project, using the block to bring another scene onscreen. The +Scenesā€¦ option presents a menu of all the scenes in your project, +where the File menu was before you clicked it. The New scene option +creates a new, empty scene, which you can rename as you like from its +context menu. Add sceneā€¦ is like Importā€¦ but for scenes. (A complete +project can be imported as a scene into another project, so you have to +specify that youā€™re importing the project as a scene rather than +replacing the current project.)

+ +

The Librariesā€¦ option presents a menu of useful, optional block +libraries:{width=ā€7.401388888888889inā€ +height=ā€3.238888888888889inā€}

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs. The libraries are described in detail in Section I.H, page 25.

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The Costumesā€¦ option opens a browser +into the costume library:

+ +

You can import a single costume by clicking it and then clicking the +Import button. Alternatively, you can import more than one costume by +double-clicking each one, and then clicking Cancel when done. Notice +that some costumes are tagged with ā€œsvgā€ in this picture; those are +vector-format costumes that are not (yet) editable within Snap!.

+ +

If you have the stage selected in the sprite corral, rather than a +sprite, the Costumesā€¦ option changes to a Backgroundsā€¦ option, with +different choices in the browser:

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The costume and background libraries +include both bitmap (go jagged if enlarged) and vector (enlarge +smoothly) images. Thanks to Scratch 2.0/3.0 for most of these images! +Some older browsers refuse to import a vector image, but instead convert +it to bitmap.

+ +

The Soundsā€¦ option opens the third kind of media browser:

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The Play buttons can be used to preview +the sounds.

+ +

Finally, the Undelete spritesā€¦ option appears only if you have deleted +a sprite; it allows you to recover a sprite that was deleted by accident +(perhaps intending to delete only a costume).

+ +

The Cloud Menu

+ +

{width=ā€1.4368055555555554inā€ +height=ā€0.7597222222222222inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.6645833333333333inā€ +height=ā€0.1673611111111111inā€}The cloud icon shows a menu of options +relating to your Snap! cloud account. If you are not logged in, you +see the outline icon and get this menu:

+ +

Choose Loginā€¦ if you have a Snap! account and remember your +password. Choose Signupā€¦ if you donā€™t have an account. Choose Reset +Passwordā€¦ if youā€™ve forgotten your password or just want to change it. +You will then get an email, at the address you gave when you created +your account, with a new temporary password. Use that password to log +in, then you can choose your own password, as shown below. Choose Resend +Verification Emailā€¦ if you have just created a Snap! account but +canā€™t find the email we sent you with the link to verify that itā€™s +really your email. (If you still canā€™t find it, check your spam folder. +If you are using a school email address, your school may block incoming +email from outside the school.) The Open in Community Site option +appears only if you have a project open; it takes you to the community +site page about that project.

+ +

{width=ā€1.6111111111111112inā€ +height=ā€0.6527777777777778inā€}If you are already logged in, youā€™ll see +the solid icon +{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€} and get this menu:

+ +

Logout is obvious, but has the additional benefit of showing you whoā€™s +logged in. Change passwordā€¦ will ask for your old password (the +temporary one if youā€™re resetting your password) and the new password +you want, entered twice because it doesnā€™t echo. Open in Community Site +is the same as above.

+ +

The Settings Menu

+ +

{width=ā€1.2479166666666666inā€ +height=ā€2.5833333333333335inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The settings icon shows a menu of Snap! +options, either for the current project or for you permanently, +depending on the option:

+ +

The Languageā€¦ option lets you see the Snap! user interface (blocks +and messages) in a language other than English. (Note: Translations have +been provided by Snap! users. If your native language is missing, send +us an email!)

+ +

The Zoom blocks... option lets you change the size of blocks, both in +the palettes and in scripts. The standard size is 1.0 units. The main +purpose of this option is to let you take very high-resolution pictures +of scripts for use on posters. It can also be used to improve +readability when projecting onto a screen while lecturing, but bear in +mind that it doesnā€™t make the palette or script areas any wider, so your +computerā€™s command-option-+ feature may be more practical. Note that a +zoom of 2 is gigantic! Donā€™t even try 10.

+ +

The Fade blocksā€¦ option opens a dialog in which you can change the +appearance of blocks:

+ +

{width=ā€7.4847222222222225inā€ +height=ā€2.577777777777778inā€}Mostly this is a propaganda aid to use on +people who think that text languages are somehow better or more grown up +than block languages, but some people do prefer less saturated block +colors. You can use the pulldown menu for preselected fadings, use the +slider to see the result as you change the fading amount, or type a +number into the text box once youā€™ve determined your favorite value.

+ +

The Stage sizeā€¦ option lets you set the size of the full-size stage +in pixels. If the stage is in half-size or double-size (presentation +mode), the stage size values donā€™t change; they always reflect the +full-size stage.

+ +

The Microphone resolutionā€¦ option sets the buffer size used by the +microphone block in Settings. ā€œResolutionā€ is an accurate name if you +are getting frequency domain samples; the more samples, the narrower the +range of frequencies in each sample. In the time domain, the buffer size +determines the length of time over which samples are collected.

+ +

The remaining options let you turn various features on and off. There +are three groups of checkboxes. The first is for temporary settings not +saved in your project nor in your user preferences.

+ +

The JavaScript extensions option enables the use of the JavaScript +function block. Because malicious projects could use JavaScript to +collect private information about you, or to delete or modify your saved +projects, you must enable JavaScript each time you load a project that +uses it.

+ +

{width=ā€1.1895833333333334inā€ +height=ā€0.18958333333333333inā€}{width=ā€1.229861111111111inā€ +height=ā€0.25972222222222224inā€}The Extension blocks option adds two +blocks to the palette:

+ +

These blocks provide assorted capabilities to official libraries that +were formerly implemented with the JavaScript function block. This +allows these libraries to run without requiring the JavaScript +extensions option. Details are subject to change.

+ +

{width=ā€1.104861111111111inā€ +height=ā€2.0833333333333335inā€}{width=ā€1.6388888888888888inā€ +height=ā€0.4131944444444444inā€}Input sliders provides an alternate way to +put values in numeric input slots; if you click in such a slot, a slider +appears that you can control with the mouse:

+ +

The range of the slider will be from 25 less than the inputā€™s current +value to 25 more than the current value. If you want to make a bigger +change than that, you can slide the slider all the way to either end, +then click on the input slot again, getting a new slider with a new +center point. But you wonā€™t want to use this technique to change the +input value from 10 to 1000, and it doesnā€™t work at all for non-integer +input ranges. This feature was implemented because software keyboard +input on phones and tablets didnā€™t work at all in the beginning, and +still doesnā€™t work perfectly on Android devices, so sliders provide a +workaround. It has since found another use in providing ā€œlivelyā€ +response to input changes; if Input sliders is checked, reopening the +settings menu will show an additional option called Execute on slider +change. If this option is also checked, then changing a slider in the +scripting area automatically runs the script in which that input +appears. The project live-tree in the Examples collection shows how this +can be used; it features a fractal tree custom block with several +inputs, and you can see how each input affects the picture by moving a +slider.

+ +

Turbo mode makes many projects run much faster, at the cost of not +keeping the stage display up to date. (Snap! ordinarily spends most of +its time drawing sprites and updating variable watchers, rather than +actually carrying out the instructions in your scripts.) So turbo mode +isnā€™t a good idea for a project with glide blocks or one in which the +user interacts with animated characters, but itā€™s great for drawing a +complicated fractal, or computing the first million digits of šœ‹, so that +you donā€™t need to see anything until the final result. While in turbo +mode, the button that normally shows a green flag instead shows a green +lightning bolt. (But when āš‘ clicked hat blocks still activate when the +button is clicked.)

+ +

Visible stepping enables the slowed-down script evaluation described in +Chapter I. Checking this option is equivalent to clicking the footprint +button above the scripting area. You donā€™t want this on except when +youā€™re actively debugging, because even the fastest setting of the +slider is still slowed a lot.

+ +

Log pen vectors tells Snap! to remember lines drawn by sprites as +exact vectors, rather than remember only the pixels that the drawing +leaves on the stage. This remembered vector picture can be used in two +ways: First, right-clicking on a pen trails block gives an option to +relabel it into a pen vectors block which, when run, reports the logged +lines as a vector (svg) costume. Second, right-clicking on the stage +when there are logged vectors shows an extra option, svgā€¦, that +exports a picture of the stage in vector format. Only lines are logged, +not color regions made with the fill block.

+ +

The next group of four are user preference options, preserved when you +load a new project. Long form input dialog, if checked, means that +whenever a custom block input name is created or edited, you immediately +see the version of the input name dialog that includes the type options, +default value setting, etc., instead of the short form with just the +name and the choice between input name and title text. The default +(unchecked) setting is definitely best for beginners, but more +experienced Snap! programmers may find it more convenient always to +see the long form.

+ +

Plain prototype labels eliminates the plus signs between words in the +Block Editor prototype block. This makes it harder to add an input to a +custom block; you have to hover the mouse where the plus sign would have +been, until a single plus sign appears temporarily for you to click on. +Itā€™s intended for people making pictures of scripts in the block editor +for use in documentation, such as this manual. You probably wonā€™t need +it otherwise.

+ +

Clicking sound causes a really annoying sound effect whenever one block +snaps next to another in a script. Certain very young children, and our +colleague Dan Garcia, like this, but if you are such a child you should +bear in mind that driving your parents or teachers crazy will result in +you not being allowed to use Snap!. It might, however, be useful for +visually impaired users.

+ +

Flat design changes the ā€œskinā€ of the Snap! window to a really hideous +design with white and pale-grey background, rectangular rather than +rounded buttons, and monochrome blocks (rather than the shaded, somewhat +3D-looking normal blocks). The monochrome blocks are the reason for the +ā€œflatā€ in the name of this option. The only thing to be said for this +option is that, because of the white background, it may blend in better +with the rest of a web page when a Snap! project is run in a frame in +a larger page. (I confess I used it to make the picture of blocks faded +all the way to just text two pages ago, though.)

+ +

The final group of settings change the way Snap! interprets your +program; they are saved with the project, so anyone who runs your +project will experience the same behavior. Thread safe scripts changes +the way Snap! responds when an event (clicking the green flag, say) +starts a script, and then, while the script is still running, the same +event happens again. Ordinarily, the running process stops where it is, +ignoring the remaining commands in the script, and the entire script +starts again from the top. This behavior is inherited from Scratch, and +some converted Scratch projects depend on it; thatā€™s why itā€™s the +default. Itā€™s also sometimes the right thing, especially in projects +that play music in response to mouse clicks or keystrokes. If a note is +still playing but you ask for another one, you want the new one to start +right then, not later after the old process finishes. But if your script +makes several changes to a database and is interrupted in the middle, +the result may be that the database is inconsistent. When you select +Thread safe scripts, the same event happening again in the middle of +running a script is simply ignored. (This is arguably still not the +right thing; the event should be remembered and the script run again as +soon as it finishes. Weā€™ll probably get around to adding that choice +eventually.) Keyboard events (when __ key pressed) are always +thread-safe.

+ +

Flat line ends affects the drawing of thick lines (large pen width). +Usually the ends are rounded, which looks best when turning corners. +With this option selected, the ends are flat. Itā€™s useful for drawing a +brick wall or a filled rectangle.

+ +

Codification support enables a feature that can translate a Snap! +project to a text-based (rather than block-based) programming language. +The feature doesnā€™t know about any particular other language; instead, +you can provide a translation for each primitive block using these +special blocks:

+ +

{width=ā€3.120644138232721inā€ +height=ā€0.5451388888888888inā€}

+ +

Using these primitive blocks, you can build a block library to translate +into any programming language. Watch for such libraries to be added to +our library collection (or contribute one). To see some examples, open +the project ā€œCodificationā€ in the Examples project list. Edit the blocks +map to Smalltalk, map to JavaScript, etc., to see examples of how to +provide translations for blocks.

+ +

{width=ā€2.209722222222222inā€ +height=ā€4.969444444444444inā€}{width=ā€1.38inā€ +height=ā€4.79inā€}The Single palette option puts all blocks, regardless of +category, into a single palette. Itā€™s intended mainly for use by +curriculum developers building Parsons problems: projects in which +only a small set of blocks are provided, and the task is to arrange +those blocks to achieve a set goal. In that application, this option is +combined with the hiding of almost all primitive blocks. (See page 119.) +When Single palette is turned on, two additional options (initially on) +appear in the settings menu; the Show categories option controls the +appearance of the palette category names such as +{width=ā€0.36inā€ height=ā€0.16inā€} +and A picture containing logo Description automatically
+generated{width=ā€0.33inā€ +height=ā€0.18inā€}, while the Show buttons option controls the appearance +of the {width=ā€0.61inā€ +height=ā€0.16inā€} and +{width=ā€0.53inā€ height=ā€0.16inā€} +buttons in the palette.

+ +

The HSL pen color model option changes the set pen, change pen, and pen +blocks to provide menu options hue, saturation, and lightness instead of +hue, saturation, and brightness (a/k/a value). Note: the name +ā€œsaturationā€ means something different in HSL from in HSV! See Appendix +A for all the information you need about colors.

+ +

The Disable click-to-run option tells Snap! to ignore user mouse +clicks on blocks and scripts if it would ordinarily run the block or +script. (Right-clicking and dragging still work, and so does clicking in +an input slot to edit it.) This is another Parsons problem feature; the +idea is that there will be buttons displayed that run code only in +teacher-approved ways. But kids can uncheck the checkbox. ā˜ŗļøŽ

+ +

Visible Stepping Controls

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}After the menu buttons youā€™ll see the +project name. After that comes the footprint button used to turn on +visible stepping and, when itā€™s on, the slider to control the speed of +stepping.

+ +

Stage Resizing Buttons

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}Still in the tool bar, but above the left +edge of the stage, are two buttons that change the size of the stage. +The first is the shrink/grow button. Normally it looks like this: +Clicking the button displays the stage at half-normal size horizontally +and vertically (so it takes up Ā¼ of its usual area). When the stage is +half size the button looks like this: and clicking it returns the stage +to normal size. The main reason youā€™d want a half size stage is during +the development process, when youā€™re assembling scripts with wide input +expressions and the normal scripting area isnā€™t wide enough to show the +complete script. Youā€™d typically then switch back to normal size to try +out the project. The next presentation mode button normally looks like +this: Clicking the button makes the stage double size in both dimensions +and eliminates most of the other user interface elements (the palette, +the scripting area, the sprite corral, and most of the tool bar). When +you open a shared project using a link someone has sent you, the project +starts in presentation mode. While in presentation mode, the button +looks like this: Clicking it returns to normal (project development) +mode.

+ +

Project Control Buttons {#project-control-buttons .ListParagraph}

+ +

Above the right edge of the stage are three buttons that control the +running of the project.

+ +

{width=ā€0.38inā€ +height=ā€0.22inā€}Technically, the green flag is no more a project control +than anything else that can trigger a hat block: typing on the keyboard +or clicking on a sprite. But itā€™s a convention that clicking the flag +should start the action of the project from the beginning. Itā€™s only a +convention; some projects have no flag-controlled scripts at all, but +respond to keyboard controls instead. Clicking the green flag also +deletes temporary clones.

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}Whenever any script is running (not necessarily in the +current sprite), the green flag is lit: .

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}{width=ā€1.3590277777777777inā€ +height=ā€0.8840277777777777inā€}Shift-clicking the button enters Turbo +mode, and the button then looks like a lightning bolt: . Shift-clicking +again turns Turbo mode off.

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}Scripts can simulate clicking the green +flag by broadcasting the special message +{width=ā€0.3055555555555556inā€ +height=ā€0.3055555555555556inā€}.

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}The pause button suspends running all +scripts. If clicked while scripts are running, the button changes shape +to become a play button: Clicking it while in this form resumes the +suspended scripts. There is also a pause all block in the Control +palette that can be inserted in a script to suspend all scripts; this +provides the essence of a breakpoint debugging capability. The use of +the pause button is slightly different in visible stepping mode, +described in Chapter I.

+ +

{width=ā€0.5486111111111112inā€ +height=ā€0.17708333333333334inā€}The stop button stops all scripts, like +the stop all block. It does not prevent a script from starting again +in response to a click or keystroke; the user interface is always +active. There is one exception: generic when blocks will not fire after +a stop until some non-generic event starts a script. The stop button +also deletes all temporary clones.

+ +

The Palette Area

+ +

At the top of the palette area are the eight buttons that select which +palette (which block category) is shown: Motion, Looks, Sound, Pen, +Control, Sensing, Operators, and Variables (which also includes the List +and Other blocks). There are no menus behind these buttons.

+ +

Buttons in the Palette

+ +

{width=ā€0.2604166666666667inā€ +height=ā€0.2604166666666667inā€}Under the eight palette selector buttons, +at the top of the actual palette, are two semi-transparent buttons. The +first is the search button, which is equivalent to typing control-F: +It replaces the palette with a search bar into which you can type part +of the title text of the block youā€™re trying to find. To leave this +search mode, click one of the eight palette selectors, or type the +Escape key.

+ +

{width=ā€0.2604166666666667inā€ +height=ā€0.2604166666666667inā€}The other button is equivalent to the +ā€œMake a blockā€ button, except that the dialog window that it opens has +the current palette (color) preselected.

+ +

Context Menus for Palette Blocks

+ +

{width=ā€0.8611111111111112inā€ +height=ā€0.45902777777777776inā€}Most elements of the Snap! display can +be control-clicked/right-clicked to show a context menu, with items +relevant to that element. If you control-click/right-click a primitive +block in the palette, you see this menu:

+ +

The helpā€¦ option displays a box with documentation about the block. +Hereā€™s an example:

+ +

{width=ā€1.6229166666666666inā€ +height=ā€0.8888888888888888inā€}{width=ā€3.3222222222222224inā€ +height=ā€2.4277777777777776inā€}If you control-click/right-click a +custom (user-defined) block in the palette, you see this menu:

+ +

The helpā€¦ option for a custom block displays the comment, if any, +attached to the custom blockā€™s hat block in the Block Editor. Here is an +example of a block with a comment and its help display:

+ +

{width=ā€6.758333333333334inā€ +height=ā€2.451388888888889inā€}If the help text includes a URL, it is +clickable and will open the page in a new tab.

+ +

The delete block definitionā€¦ option asks for confirmation, then +deletes the custom block and removes it from any scripts in which it +appears. (The result of this removal may not leave a sensible script; +itā€™s best to find and correct such scripts before deleting a block.) +Note that there is no option to hide a custom block; this can be done +in the Block Editor by right-clicking on the hat block.

+ +

The duplicate block definitionā€¦ option makes a copy of the block and +opens that copy in the Block Editor. Since you canā€™t have two custom +blocks with the same title text and input types, the copy is created +with ā€œ(2)ā€ (or a higher number if necessary) at the end of the block +prototype.

+ +

The export block definitionā€¦ option writes a file in your browserā€™s +downloads directory containing the definition of this block and any +other custom blocks that this block invokes, directly or indirectly. So +the resulting file can be loaded later without the risk of red +Undefined! blocks because of missing dependencies.

+ +

The editā€¦ option opens a Block Editor with the definition of the +custom block.

+ +

Context Menu for the Palette Background

+ +

{width=ā€0.9895833333333334inā€ +height=ā€0.5895833333333333inā€}Right-click/control-click on the grey +background of the palette area shows this menu:

+ +

{width=ā€1.6inā€ +height=ā€2.1597222222222223inā€}The find blocksā€¦ option does the same +thing as the magnifying-glass button. The hide blocksā€¦ option opens a +dialog box in which you can choose which blocks (custom as well as +primitive) should be hidden. (Within that dialog box, the context menu +of the background allows you to check or uncheck all the boxes at once.)

+ +

The make a categoryā€¦ option, which is intended mainly for authors of +snap extensions, lets you add custom categories to the palette. It +opens a small dialog window in which you specify a name and a color +for the new category:

+ +

{width=ā€1.429861111111111inā€ +height=ā€2.9097222222222223inā€}{width=ā€1.53inā€ +height=ā€1.13inā€}Pick a dark color, because it will be lightened for +zebra coloring when users nest blocks of the same category. Custom +categories are shown below the built-in categories in the category +selector:

+ +

{width=ā€1.35inā€ +height=ā€1.8395833333333333inā€}This example comes from Eckart Modrowā€™s +SciSnap! library. Note that the custom category list has its own +scroll bar, which appears if you have more than six custom categories. +Note also that the buttons to select a custom category occupy the full +width of the palette area, unlike the built-in categories, which occupy +only half of the width. Custom categories are listed in alphabetical +order; this is why Prof. Modrow chose to start each category name with a +number, so that he could control their order.

+ +

If there are no blocks visible in a category, the category name is +dimmed in the category selector:

+ +

Here we see that category foo has blocks in it, but categories bar and +garply are empty. The built-in categories are also subject to dimming, +if all of the blocks of a category are hidden.

+ +


+Palette Resizing

+ +

At the right end of the palette area, just to the left of the scripting +area, is a resizing +handle{width=ā€1.4166666666666667inā€ +height=ā€1.5138888888888888inā€} that can be dragged rightward to increase +the width of the palette area. This is useful if you write custom blocks +with very long names. You canā€™t reduce the width of the palette below +its standard value.

+ +

The Scripting Area

+ +

The scripting area is the middle vertical region of the Snap! window, +containing scripts and also some controls for the appearance and +behavior of a sprite. There is always a current sprite, whose scripts +are shown in the scripting area. A dark grey rounded rectangle in the +sprite corral shows which sprite (or the stage) is current. Note that +itā€™s only the visible display of the scripting area that is ā€œcurrentā€ +for a sprite; all scripts of all sprites may be running at the same +time. Clicking on a sprite thumbnail in the sprite corral makes it +current. The stage itself can be selected as current, in which case the +appearance is different, with some primitives not shown.

+ +

Sprite Appearance and Behavior Controls

+ +

At the top of the scripting area are a picture of the sprite and some +controls for it:

+ +

{width=ā€3.486111111111111inā€ +height=ā€1.0416666666666667inā€}

+ +

Note that the sprite picture reflects its rotation, if any. There are +three things that can be controlled here:

+ +

1. The three circular buttons in a column at the left control the +spriteā€™s rotation behavior. Sprite costumes are designed to be +right-side-up when the sprite is facing toward the right (direction = +90). If the topmost button is lit, the default as shown in the picture +above, then the spriteā€™s costume rotates as the sprite changes +direction. If the middle button is selected, then the costume is +reversed left-right when the spriteā€™s direction is roughly leftward +(direction between 180 and 359, or equivalently, between -180 and -1). +If the bottom button is selected, the costumeā€™s orientation does not +change regardless of the spriteā€™s direction.

+ +

2. The spriteā€™s name can be changed in the text box that, in this +picture, says ā€œSprite.ā€

+ +

3. Finally, if the draggable checkbox is checked, then the user can move +the sprite on the stage by clicking and dragging it. The common use of +this feature is in game projects, in which some sprites are meant to be +under the playerā€™s control but others are not.

+ +

Scripting Area Tabs

+ +

{width=ā€3.0972222222222223inā€ +height=ā€0.25inā€}Just below the sprite controls are three tabs that +determine what is shown in the scripting area:

+ +

Scripts and Blocks Within Scripts

+ +

Most of whatā€™s described in this section also applies to blocks and +scripts in a Block Editor.

+ +

Clicking on a script (which includes a single unattached block) runs it. +If the script starts with a hat block, clicking on the script runs it +even if the event in the hat block doesnā€™t happen. (This is a useful +debugging technique when you have a dozen sprites and they each have +five scripts with green-flag hat blocks, and you want to know what a +single one of those scripts does.) The script will have a green ā€œhaloā€ +around it while itā€™s running. If the script is shared with clones, then +while it has the green halo it will also have a count of how many +instances of the script are running. Clicking a script with such a halo +stops the script. (If the script includes a warp block, which might be +inside a custom block used in the script, then Snap! may not respond +immediately to clicks.)

+ +

{width=ā€0.3333333333333333inā€ +height=ā€0.2604166666666667inā€}If a script is shown with a red halo, +that means that an error was caught in that script, such as using a list +where a number was needed, or vice versa. Clicking the script will turn +off the halo.

+ +

{width=ā€0.3125inā€ +height=ā€0.23958333333333334inā€}{width=ā€0.3333333333333333inā€ +height=ā€0.2604166666666667inā€}If any blocks have been dragged into the +scripting area, then in its top right corner youā€™ll see an undo and/or +redo button that can be used to undo or redo block and script drops. +When you undo a drop into an input slot, whatever used to be in the slot +is restored. The redo button appears once youā€™ve used undo.

+ +

The third button starts keyboard editing mode (Section D, page 130).

+ +

Control-click/right-clicking a primitive block within a script shows a +menu like this one:

+ +

{width=ā€0.6208333333333333inā€ +height=ā€1.0625inā€}{width=ā€0.6263888888888889inā€ +height=ā€1.0902777777777777inā€}

+ +

command block: reporter block:

+ +

The helpā€¦ option shows the help screen for the block, just as in the +palette. The other options appear only when a block is +right-clicked/control-clicked in the scripting area.

+ +

{width=ā€1.53inā€ +height=ā€2.13inā€}Not every primitive block has a relabelā€¦ option. When +present, it allows the block to be replaced by another, similar block, +keeping the input expressions in place. For example, hereā€™s what happens +when you choose relabelā€¦ for an arithmetic operator:

+ +

Note that the inputs to the existing ā€“ block are displayed in the menu +of alternatives also. Click a block in the menu to choose it, or click +outside the menu to keep the original block. Note that the last three +choices are not available in the palette; you must use the relabel +feature to access them.

+ +

Not every reporter has a compile option; it exists only for the higher +order functions. When selected, a lightning bolt appears before the +block name: +{width=ā€1.4027777777777777inā€ +height=ā€0.2013888888888889inā€} and Snap! tries to compile the function +inside the ring to JavaScript, so it runs at primitive speed. This works +only for simple functions (but the higher order function still works +even if the compilation doesnā€™t). The function to be compiled must be +quick, because it will be uninterruptable; in particular, if itā€™s an +infinite loop, you may have to quit your browser to recover. Therefore, +save your project before you experiment with the compilation +feature. The right-click menu for a compiled higher order function will +have an uncompile option. This is an experimental feature.

+ +

The duplicate option for a command block makes a copy of the entire +script starting from the selected block. For a reporter, it copies only +that reporter and its inputs. The copy is attached to the mouse, and you +can drag it to another script (or even to another Block Editor window), +even though you are no longer holding down the mouse button. Click the +mouse to drop the script copy.

+ +

The block picture underneath the word duplicate for a command block is +another duplication option, but it duplicates only the selected block, +not everything under it in the script. Note that if the selected block +is a C-shaped control block, the script inside its C-shaped slot is +included. If the block is at the end of its script, this option does not +appear. (Use duplicate instead.)

+ +

The extract option removes the selected block from the script and leaves +you holding it with the mouse. In other words, itā€™s like the block +picture option, but it doesnā€™t leave a copy of the block in the original +script. If the block is at the end of its script, this option does not +appear. (Just grab the block with the mouse.) A shorthand for this +operation is to shift-click and drag out the block.

+ +

The delete option deletes the selected block from the script.

+ +

The add comment option creates a comment, like the same option in the +background of the scripting area, but attaches it to the block you +clicked.

+ +

The script picā€¦ option saves a picture of the entire script, not just +from the selected block to the end, into your download folder; or, in +some browsers, opens a new browser tab containing the picture. In the +latter case, you can use the browserā€™s Save feature to put the picture +in a file. This is a super useful feature if you happen to be writing a +Snap! manual! (If you have a Retina display, consider turning off +Retina support before making script pictures; if not, they end up huge.) +For reporters not inside a script, there is an additional result picā€¦ +option that calls the reporter and includes a speech balloon with the +result in the picture. Note: The downloaded file is a ā€œsmart pictureā€: +It also contains the code of the script, as if youā€™d exported the +project. If you later drag the file into the costumes tab, it will be +loaded as a costume. But if you drag it into the scripts tab, it will +be loaded as a script, which you can drop wherever you want it in the +scripting area.

+ +

If the script does not start with a hat block, or you clicked on a +reporter, then thereā€™s one more option: ringify (and, if there is +already a grey ring around the block or script, unringify). Ringify +surrounds the block (reporter) or the entire script (command) with a +grey ring, meaning that the block(s) inside the ring are themselves +data, as an input to a higher order procedure, rather than something to +be evaluated within the script. See Chapter VI, Procedures as Data.

+ +

{width=ā€0.9736111111111111inā€ +height=ā€1.2986111111111112inā€}Clicking a custom block in a script +gives a similar but different menu:

+ +

The relabelā€¦ option for custom blocks shows a menu of other same-shape +custom blocks with the same inputs. At present you canā€™t relabel a +custom block to a primitive block or vice versa. The two options at the +bottom, for custom blocks only, are the same as in the palette. The +other options are the same as for primitive commands.

+ +

{width=ā€0.88125inā€ +height=ā€1.0833333333333333inā€}If a reporter block is in the scripting +area, possibly with inputs included, but not itself serving as input to +another block, then the menu is a little different again:

+ +

Whatā€™s new here is the result picā€¦ option. Itā€™s like script picā€¦ but +it includes in the picture a speech balloon with the result of calling +the block.

+ +

Broadcast and broadcast and wait blocks in the scripting area have an +additional option: receiversā€¦. When clicked, it causes a momentary (be +looking for it when you click!) halo around the picture in the sprite +corral of those sprites that have a when I receive hat block for the +same message. Similarly, when I receive blocks have a sendersā€¦ option +that light up the sprite corral icons of sprites that broadcast the same +message.

+ +

Scripting Area Background Context Menu

+ +

{width=ā€1.2895833333333333inā€ +height=ā€1.2777777777777777inā€}Control-click/right-click on the grey +striped background of the scripting area gives this menu:

+ +

{width=ā€0.8416666666666667inā€ +height=ā€0.18819444444444444inā€}The undrop option is a sort of ā€œundoā€ +feature for the common case of dropping a block somewhere other than +where you meant it to go. It remembers all the dragging and dropping +youā€™ve done in this spriteā€™s scripting area (that is, other sprites have +their own separate drop memory), and undoes the most recent, returning +the block to its former position, and restoring the previous value in +the relevant input slot, if any. Once youā€™ve undropped something, the +redrop option appears, and allows you to repeat the operation you just +undid. These menu options are equivalent to the and buttons described +earlier.

+ +

The clean up option rearranges the position of scripts so that they are +in a single column, with the same left margin, and with uniform spacing +between scripts. This is a good idea if you canā€™t read your own project!

+ +

{width=ā€1.3888888888888888inā€ +height=ā€0.7083333333333334inā€}The add comment option puts a comment box, +like the picture to the right, in the scripting area. Itā€™s attached to +the mouse, as with duplicating scripts, so you position the mouse where +you want the comment and click to release it. You can then edit the text +in the comment as desired.

+ +

{width=ā€1.3888888888888888inā€ +height=ā€0.2361111111111111inā€}You can drag the bottom right corner of +the comment box to resize it. Clicking the arrowhead at the top left +changes the box to a single-line compact form, , so that you can have a +number of collapsed comments in the scripting area and just expand one +of them when you want to read it in full.

+ +

If you drag a comment over a block in a script, the comment will be +attached to the block with a yellow line:

+ +

{width=ā€1.4861111111111112inā€ +height=ā€0.8472222222222222inā€}{width=ā€3.3333333333333335inā€ +height=ā€0.9333333333333333inā€}Comments have their own context menu, with +obvious meanings:

+ +

Back to the options in the menu for the background of the scripting area +(picture on the previous page):

+ +

The scripts picā€¦ option saves, or opens a new browser tab with, a +picture of all scripts in the scripting area, just as they appear, but +without the grey striped background. Note that ā€œall scripts in the +scripting areaā€ means just the top-level scripts of the current sprite, +not other spritesā€™ scripts or custom block definitions. This is also a +ā€œsmart pictureā€; if you drag it into the scripting area, it will create +a new sprite with those scripts in its scripting area.

+ +

Finally, the make a blockā€¦ option does the same thing as the ā€œMake a +blockā€ button in the palettes. Itā€™s a shortcut so that you donā€™t have to +keep scrolling down the palette if you make a lot of blocks.

+ +

Controls in the Costumes Tab

+ +

{width=ā€1.9631944444444445inā€ +height=ā€2.1319444444444446inā€}If you click on the word ā€œCostumesā€ under +the sprite controls, youā€™ll see something like this:

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The Turtle costume is always present in +every sprite; it is costume number 0. Other costumes can be painted +within Snap! or imported from files or other browser tabs if your +browser supports that. Clicking on a costume selects it; that is, the +sprite will look like the selected costume. Clicking on the paint brush +icon
+opens the Paint Editor, in which you can create a new costume. +Clicking on the camera icon opens a window in which you see what your +computerā€™s camera is seeing, and you can take a picture (which will be +the full size of the stage unless you shrink it in the Paint Editor). +This works only if you give Snap! permission to use the camera, and +maybe only if you opened Snap! in secure (HTTPS) mode, and then only +if your browser loves you.

+ +

{width=ā€3.5694444444444446inā€ +height=ā€3.1805555555555554inā€} Brianā€™s bedroom when heā€™s staying at +Paulā€™s house.

+ +

Control-clicking/right-clicking on the turtle picture gives this menu:

+ +

{width=ā€1.0555555555555556inā€ +height=ā€0.9027777777777778inā€}In this menu, you choose the turtleā€™s +rotation point, which is also the point from which the turtle draws +lines. The two pictures below show what the stage looks like after +drawing a square in each mode; tip (otherwise known as ā€œJens modeā€) is +on the left in the pictures below, middle (ā€œBrian modeā€) on the right:

+ +

{width=ā€3.134027777777778inā€ +height=ā€1.1743055555555555inā€}As you see, ā€œtipā€ means the front tip of +the arrowhead; ā€œmiddleā€ is not the middle of the shaded region, but +actually the middle of the four vertices, the concave one. (If the shape +were a simple isosceles triangle instead of a fancier arrowhead, it +would mean the midpoint of the back edge.) The advantage of tip mode is +that the sprite is less likely to obscure the drawing. The advantage of +middle mode is that the rotation point of a sprite is rarely at a tip, +and students are perhaps less likely to be confused about just what will +happen if you ask the turtle to turn 90 degrees from the position shown. +(Itā€™s also the traditional rotation point of the Logo turtle, which +originated this style of drawing.)

+ +

{width=ā€0.9833333333333333inā€ +height=ā€1.3194444444444444inā€}Costumes other than the turtle have a +different context menu:

+ +

The edit option opens the Paint Editor on this costume. The rename +option opens a dialog box in which you can rename the costume. (A +costumeā€™s initial name comes from the file from which it was imported, +if any, or is something like costume5.) Duplicate makes a copy of the +costume, in the same sprite. (Presumably youā€™d do that because you +intend to edit one of the copies.) Delete is obvious. The get blocks +option appears only for a smart costume, and brings its script to the +scripting area. The export option saves the costume as a file on your +computer, in your usual downloads folder.

+ +

You can drag costumes up and down in the Costumes tab in order to +renumber them, so that next costume will behave as you prefer.

+ +

{width=ā€1.2804921259842519inā€ +height=ā€0.8694444444444445inā€}If you drag a smart picture of a script +into the Costumes tab, its icon will display the text ā€œ</>ā€ in the +corner to remind you that it includes code:

+ +

Its right-click menu will have an extra get blocks option that switches +to the Scripts tab with the script ready to be dropped there.

+ +

The Paint Editor

+ +

{width=ā€3.938888888888889inā€ +height=ā€2.577777777777778inā€}Here is a picture of a Paint Editor window:

+ +

If youā€™ve used any painting program, most of this will be familiar to +you. Currently, costumes you import can be edited only if they are in a +bitmap format (png, jpeg, gif, etc.). There is a vector editor, but it +works only for creating a costume, not editing an imported vector (svg) +picture. Unlike the case of the Block Editor, only one Paint Editor +window can be open at a time.

+ +

The ten square buttons in two rows of five near the top left of the +window are the tools. The top row, from left to right, are the +paintbrush tool, the outlined rectangle tool, the outlined ellipse tool, +the eraser tool, and the rotation point tool. The bottom row tools are +the line drawing tool, the solid rectangle tool, the solid ellipse tool, +the floodfill tool, and the eyedropper tool. Below the tools is a row of +four buttons that immediately change the picture. The first two change +its overall size; the next two flip the picture around horizontally or +vertically. Below these are a color palette, a greyscale tape, and +larger buttons for black, white, and transparent paint. Below these is a +solid bar displaying the currently selected color. Below that is a +picture of a line showing the brush width for painting and drawing, and +below that, you can set the width either with a slider or by typing a +number (in pixels) into the text box. Finally, the checkbox constrains +the line tool to draw horizontally or vertically, the rectangle tools to +draw squares, and the ellipse tools to draw circles. You can get the +same effect temporarily by holding down the shift key, which makes a +check appear in the box as long as you hold it down. (But the Caps Lock +key doesnā€™t affect it.)

+ +

You can correct errors with the undo button, which removes the last +thing you drew, or the clear button, which erases the entire picture. +(Note, it does not revert to what the costume looked like before you +started editing it! If thatā€™s what you want, click the Cancel button at +the bottom of the editor.) When youā€™re finished editing, to keep your +changes, click OK.

+ +

Note that the ellipse tools work more intuitively than ones in other +software you may have used. Instead of dragging between opposite corners +of the rectangle circumscribing the ellipse you want, so that the +endpoints of your dragging have no obvious connection to the actual +shape, in Snap! you start at the center of the ellipse you want and +drag out to the edge. When you let go of the button, the mouse cursor +will be on the curve. If you drag out from the center at 45 degrees to +the axes, the resulting curve will be a circle; if you drag more +horizontally or vertically, the ellipse will be more eccentric. (Of +course if you want an exact circle you can hold down the shift key or +check the checkbox.) The rectangle tools, though, work the way you +expect: You start at one corner of the desired rectangle and drag to the +opposite corner.

+ +

Using the eyedropper tool, you can click anywhere in the Snap! window, +even outside the Paint Editor, and the tool will select the color at the +mouse cursor for use in the Paint Editor. You can only do this once, +because the Paint Editor automatically selects the paintbrush when you +choose a color. (Of course you can click on the eyedropper tool button +again.)

+ +

The only other non-obvious tool is the rotation point tool. It shows in +the Paint Editor where the spriteā€™s current rotation center is (the +point around which it turns when you use a turn block); if you click or +drag in the picture, the rotation point will move where you click. +(Youā€™d want to do this, for example, if you want a character to be able +to wave its arm, so you use two sprites connected together. You want the +rotation point of the arm sprite to be at the end where it joins the +body, so it remains attached to the shoulder while waving.)

+ +

{width=ā€3.8361111111111112inā€ +height=ā€2.548611111111111inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}The vector editorā€™s controls are much like +those in the bitmap editor. One point of difference is that the bitmap +editor has two buttons for solid and outline rectangles, and similarly +for ellipses, but in the vector editor there is always an edge color and +a fill color, even if the latter is ā€œtransparent paint,ā€ and so only one +button per shape is needed. Since each shape that you draw is a separate +layer (like sprites on the stage), there are controls to move the +selected shape up (frontward) or down (rearward) relative to other +shapes. There is a selection tool to drag out a rectangular area and +select all the shapes within that area.

+ +

###

+ +

Controls in the Sounds Tab

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}There is no Sound Editor in Snap!, and also no current +sound the way thereā€™s a current costume for each sprite. (The sprite +always has an appearance unless hidden, but it doesnā€™t sing unless +explicitly asked.) So the context menu for sounds has only rename, +delete, and export options, and it has a clickable button labeled Play +or Stop as appropriate. There is a sound recorder, which appears if +you click the red record button ( ):

+ +

{width=ā€2.325inā€ +height=ā€1.0333333333333334inā€}The first, round button starts recording. +The second, square button stops recording. The third, triangular button +plays back a recorded sound. If you donā€™t like the result, click the +round button again to re-record. When youā€™re satisfied, push the Save +button. If you need a sound editor, consider the free (both senses) +http://audacity.sourceforge.net.

+ +

Keyboard Editing

+ +

An ongoing area of research is how to make visual programming languages +usable by people with visual or motoric disabilities. As a first step in +this direction, we provide a keyboard editor, so that you can create and +edit scripts without tracking the mouse. So far, not every user +interface element is controllable by keyboard, and we havenā€™t even begun +providing output support, such as interfacing with a speech +synthesizer. This is an area in which we know we have a long way to go! +But itā€™s a start. The keyboard editor may also be useful to anyone who +can type faster than they can drag blocks.

+ +

Starting and stopping the keyboard editor

+ +

There are three ways to start the keyboard editor. Shift-clicking +anywhere in the scripting area will start the editor at that point: +either editing an existing script or, if you shift-click on the +background of the scripting area, editing a new script at the mouse +position. Alternatively, typing shift-enter will start the editor on an +existing script, and you can use the tab key to switch to another +script. Or you can click the keyboard button at the top of the scripting +area.

+ +

When the script editor is running, its position is represented by a +blinking white bar:

+ +

{width=ā€2.2083333333333335inā€ +height=ā€1.59375inā€}To leave the keyboard editor, type the escape key, or +just click on the background of the scripting area.

+ + + +

To move to a different script, type the tab key. Shift-tab to move +through the scripts in reverse order.

+ +

A script is a vertical stack of command blocks. A command block may have +input slots, and each input slot may have a reporter block in it; the +reporter may itself have input slots that may have other reporters. You +can navigate through a script quickly by using the up arrow and down +arrow keys to move between command blocks. Once you find the command +block that you want to edit, the left and right arrow keys move between +editable items within that command. (Left and right arrow when there are +no more editable items within the current command block will move up or +down to another command block, respectively.) Here is a sequence of +pictures showing the results of repeated right arrow keys starting from +the position shown above:

+ +

{width=ā€7.313888888888889inā€ +height=ā€1.2527777777777778inā€}You can rearrange scripts within the +scripting area from the keyboard. Typing shift-arrow keys (left, right, +up, or down) will move the current script. If you move it onto another +script, the two wonā€™t snap together; the one youā€™re moving will overlap +the one already there. This means that you can move across another +script to get to a free space.

+ +

Editing a script

+ +

Note that the keyboard editor focus, the point shown as a white bar or +halo, is either between two command blocks or on an input slot. The +editing keys do somewhat different things in each of those two cases.

+ +

The backspace key deletes a block. If the focus is between two commands, +the one before (above) the blinking bar is deleted. If the focus is on +an input slot, the reporter in that slot is deleted. (If that input slot +has a default value, it will appear in the slot.) If the focus is on a +variadic input (one that can change the number of inputs by clicking +on arrowheads), then one input slot is deleted. (When you right-arrow +into a variadic input, the focus first covers the entire thing, +including the arrowheads; another right-arrow focuses on the first slot +within that input group. The focus is ā€œon the variadic inputā€ when it +covers the entire thing.)

+ +

The enter key does nothing if the focus is between commands, or on a +reporter. If the focus is on a variadic input, the enter key adds one +more input slot. If the focus is on a white input slot (one that doesnā€™t +have a reporter in it), then the enter key selects that input slot for +editing; that is, you can type into it, just as if youā€™d clicked on +the input slot. (Of course, if the focus is on an input slot containing +a reporter, you can use the backspace key to delete that reporter, and +then use the enter key to type a value into it.) When you finish typing +the value, type the enter key again to accept it and return to +navigation, or the escape key if you decide not to change the value +already in the slot.

+ +

The space key is used to see a menu of possibilities for the input slot +in focus. It does nothing unless the focus is on a single input slot. If +the focus is on a slot with a pulldown menu of options, then the space +key shows that menu. (If itā€™s a block-colored slot, meaning that only +the choices in the menu can be used, the enter key will do the same +thing. But if itā€™s a white slot with a menu, such as in the turn blocks, +then enter lets you type a value, while space shows the menu.) +Otherwise, the space key shows a menu of variables available at this +point in the script. In either case, use the up and down arrow keys to +navigate the menu, use the enter key to accept the highlighted entry, or +use the escape key to leave the menu without choosing an option.

+ +

{width=ā€1.5347222222222223inā€ +height=ā€1.6944444444444444inā€}Typing any other character key (not +special keys on fancy keyboards that do something other than generating +a character) activates the block search palette. This palette, which +is also accessible by typing control-F or command-F outside the keyboard +editor, or by clicking the search button floating at the top of the +palette, has a text entry field at the top, followed by blocks whose +title text includes what you type. The character key you typed to start +the block search palette is entered into the text field, so you start +with a palette of blocks containing that character. Within the palette, +blocks whose titles start with the text you type come first, then +blocks in which a word of the title starts with the text you type, and +finally blocks in which the text appears inside a word of the title. +Once you have typed enough text to see the block you want, use the arrow +keys to navigate to that block in the palette, then enter to insert that +block, or escape to leave the block search palette without inserting the +block. (When not in the keyboard editor, instead of navigating with the +arrow keys, you drag the block you want into the script, as you would +from any other palette.)

+ +

{width=ā€2.8333333333333335inā€ +height=ā€0.8409722222222222inā€}If you type an arithmetic operator (+-*/) +or comparison operator (<=>) into the block search text box, you can +type an arbitrarily complicated expression, and a collection of +arithmetic operator blocks will be constructed to match:

+ +

As the example shows, you can also use parentheses for grouping, and +non-numeric operands are treated as variables or primitive functions. (A +variable name entered in this way may or may not already exist in the +script. Only round and the ones in the pulldown menu of the sqrt block +can be used as function names.)

+ +

Running the selected script

+ +

Type control-shift-enter to run the script with the editor focus, like +clicking the script.

+ +

Controls on the Stage

+ +

The stage is the area in the top right of the Snap! window in which +sprites move.

+ +

Sprites

+ +

{width=ā€0.6013888888888889inā€ +height=ā€1.0833333333333333inā€}Most sprites can be moved by clicking and +dragging them. (If you have unchecked the draggable checkbox for a +sprite, then dragging it has no effect.) Control-clicking/right-clicking +a sprite shows this context menu:

+ +

The duplicate option makes another sprite with copies of the same +scripts, same costumes, etc., as this sprite. The new sprite starts at a +randomly chosen position different from the original, so you can see +quickly which is which. The new sprite is selected: It becomes the +current sprite, the one shown in the scripting area. The clone option +makes a permanent clone of this sprite, with some shared attributes, and +selects it.

+ +

The delete option deletes the sprite. Itā€™s not just hidden; itā€™s gone +for good. (But you can undelete it by clicking the wastebasket just +below the right edge of the stage.) The edit option selects the sprite. +It doesnā€™t actually change anything about the sprite, despite the name; +itā€™s just that making changes in the scripting area will change this +sprite.

+ +

{width=ā€0.6527777777777778inā€ +height=ā€0.8888888888888888inā€}The move option shows a ā€œmove handleā€ +inside the sprite (the diagonal striped square in the middle):

+ +

You can ordinarily just grab and move the sprite without this option, +but there are two reasons you might need it: First, it works even if the +ā€œdraggableā€ checkbox above the scripting area is unchecked. Second, it +works for part sprites relative to their anchor; ordinarily, dragging a +part moves the entire nested sprite.

+ +

The rotate option displays a rotation menu:

+ +

{width=ā€0.9333333333333333inā€ +height=ā€1.5833333333333333inā€}You can choose one of the four compass +directions in the lower part (the same as in the point in direction +block) or use the mouse to rotate the handle on the dial in 15Ā° +increments.

+ +

{width=ā€0.6527777777777778inā€ +height=ā€0.8472222222222222inā€}The pivot option shows a crosshair inside +the sprite:

+ +

You can click and drag the crosshair anywhere onstage to set the +costumeā€™s pivot point. (If you move it outside the sprite, then turning +the sprite will revolve as well as rotate it around the pivot.) When +done, click on the stage not on the crosshair. Note that, unlike moving +the pivot point in the Paint Editor, this technique does not visibly +move the sprite on the stage. Instead, the values of x position and y +position will change.

+ +

The edit option makes this the selected sprite, highlighting it in the +sprite corral and showing its scripting area. If the sprite was a +temporary clone, it becomes permanent.

+ +

The exportā€¦ option saves, or opens a new browser tab containing, the +XML text representation of the sprite. (Not just its costume, but all of +its costumes, scripts, local variables and blocks, and other +properties.) You can save this tab into a file on your computer, and +later import the sprite into another project. (In some browsers, the +sprite is directly saved into a file.)

+ +

{width=ā€0.9583333333333334inā€ height=ā€1.4479166666666667inā€}Variable watchers

+ +

Right-clicking on a variable watcher shows this menu:

+ +

The first section of the menu lets you choose one of three +visualizations of the watcher:

+ +

{width=ā€2.3159722222222223inā€ +height=ā€0.3263888888888889inā€}

+ +

The first (normal) visualization is for debugging. The second (large) is +for displaying information to the user of a project, often the score in +a game. And the third (slider) is for allowing the user to control the +program behavior interactively. When the watcher is displayed as a +slider, the middle section of the menu allows you to control the range +of values possible in the slider. It will take the minimum value when +the slider is all the way to the left, the maximum value when all the +way to the right.

+ +

The third section of the menu allows data to be passed between your +computer and the variable. The importā€¦ option will read a computer +text file. Its name must end with .txt, in which case the text is read +into the variable as is, or .csv or .json, in which case the text is +converted into a list structure, which will always be a two-dimensional +array for csv (comma-separated values) data, but can be any shape for +json data. The raw dataā€¦ option prevents that conversion to list form. +The exportā€¦ option does the opposite conversion, passing a text-valued +variable value into a .txt file unchanged, but converting a list value +into csv format if the list is one- or two-dimensional, or into json +format if the list is more complicated. (The scalar values within the +list must be numbers and/or text; lists of blocks, sprites, costumes, +etc. cannot be exported.)

+ +

An alternative to using the importā€¦ option is simply to drag the file +onto the Snap! window, in which case a variable will be created if +necessary with the same name as the file (but without the extension).

+ +

If the value of the variable is a list, then the menu will include an +additional blockify option; clicking it will generate an expression with +nested list blocks that, if evaluated, will reconstruct the list. Itā€™s +useful if you imported a list and then want to write code that will +construct the same list later.

+ +

The stage itself

+ +

Control-clicking/right-clicking on the stage background (that is, +anywhere on the stage except on a sprite or watcher) shows the stageā€™s +own context menu:

+ +

{width=ā€0.8215277777777777inā€ +height=ā€0.8472222222222222inā€}The stageā€™s edit option selects the stage, +so the stageā€™s scripts and backgrounds are seen in the scripting area. +Note that when the stage is selected, some blocks, especially the Motion +ones, are not in the palette area because the stage canā€™t move.

+ +

The show all option makes all sprites visible, both in the sense of the +show block and by bringing the sprite onstage if it has moved past the +edge of the stage.

+ +

The picā€¦ option saves, or opens a browser tab with, a picture of +everything on the stage: its background, lines drawn with the pen, and +any visible sprites. What you see is what you get. (If you want a +picture of just the background, select the stage, open its costumes tab, +control-click/right-click on a background, and export it.)

+ +

The pen trails option creates a new costume for the currently selected +sprite consisting of all lines drawn on the stage by the pen of any +sprite. The costumeā€™s rotation center will be the current position of +the sprite.

+ +

If you previously turned on the log pen vectors option, and there are +logged vectors, the menu includes an extra option, svgā€¦, that exports +a picture of the stage in vector format. Only lines are logged, not +color regions made with the fill block.

+ +

The Sprite Corral and Sprite Creation Buttons

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.20555555555555555inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Between the stage and the sprite corral +at the bottom right of the Snap! window is a dark grey bar containing +three buttons at the left and one at the right. The first three are used +to create a new sprite. The first button makes a sprite with just the +turtle costume, with a randomly chosen position and pen color. (If you +hold down the Shift key while clicking, the new spriteā€™s direction will +also be random.) The second button makes a sprite and opens the Paint +Editor so that you can make your own costume for it. (Of course you +could click the first button and then click the paint button in its +costumes tab; this paint button is a shortcut for all that.) Similarly, +the third button uses your camera, if possible, to make a costume for +the new sprite.

+ +

The trash can button +{width=ā€0.2916666666666667inā€ +height=ā€0.1736111111111111inā€} at the right has two uses. You can drag a +sprite thumbnail onto it from the sprite corral to delete that sprite, +or you can click it to undelete a sprite you deleted by accident.

+ +

In the sprite corral, you click on a spriteā€™s ā€œthumbnailā€ picture to +select that sprite (to make it the one whose scripts, costumes, etc. are +shown in the scripting area). You can drag sprite thumbnails (but not +the stage one) to reorder them; this has no special effect on your +project, but lets you put related ones next to each other, for example. +Double-clicking a thumbnail flashes a halo around the actual sprite on +the stage.

+ +

You can right-click/control-click a spriteā€™s thumbnail to get this +context menu:

+ +

{width=ā€0.6770833333333334inā€ +height=ā€1.1090277777777777inā€}The show option makes the sprite visible, +if it was hidden, and also brings it onto the stage, if it had moved +past the stage boundary. The next three options are the same as in the +context menu of the actual sprite on the stage, discussed above.

+ +

The parentā€¦ option displays a menu of all other sprites, showing which +if any is this spriteā€™s parent, and allowing you to choose another +sprite (replacing any existing parent). The release option is shown only +if this sprite is a (permanent, or it wouldnā€™t be in the sprite corral) +clone; it changes the sprite to a temporary clone. (The name is supposed +to mean that the sprite is released from the corral.) The exportā€¦ +option exports the sprite, like the same option on the stage.

+ +

The context menu for the stage thumbnail has only one option, picā€¦, +which takes a picture of everything on the stage, just like the same +option in the context menu of the stage background. If pen trails are +being logged, there will also be an svgā€¦ option.

+ +

If your project includes scenes, then under the stage icon in the sprite +corral will be the scene corral:

+ +

{width=ā€3.3333333333333335inā€ +height=ā€1.7083333333333333inā€}Clicking on a scene will select it; +right-clicking will present a menu in which you can rename, delete, or +export the scene.

+ +

Preloading a Project when Starting Snap!

+ +

There are several ways to include a pointer to a project in the URL when +starting Snap! in order to load a project automatically. You can think +of such a URL as just running the project rather than as running +Snap!, especially if the URL says to start in presentation mode and +click the green flag. The general form is

+ +

http://snap.berkeley.edu/run#verb:project&flag&flagā€¦

+ +

The ā€œverbā€ above can be any of open, run, cloud, present, or dl. The +last three are for shared projects in the Snap! cloud; the first two +are for projects that have been exported and made available anywhere on +the Internet.

+ +

Hereā€™s an example that loads a project stored at the Snap! web site +(not the Snap! cloud!):

+ +

http://snap.berkeley.edu/run#open:http://snap.berkeley.edu/snapsource/Examples/vee.xml

+ +

The project file will be opened, and Snap! will start in edit mode +(with the program visible). Using #run: instead of #open: will start +in presentation mode (with only the stage visible) and will ā€œstartā€ the +project by clicking the green flag. (ā€œStartā€ is in quotation marks +because there is no guarantee that the project includes any scripts +triggered by the green flag. Some projects are started by typing on the +keyboard or by clicking a sprite.)

+ +

If the verb is run, then you can also use any subset of the following +flags:

+ +

&editMode Start in edit mode, not presentation mode.

+ +

&noRun Donā€™t click the green flag.

+ +

&hideControls Donā€™t show the row of buttons above the stage (edit mode, +green flag, pause, stop).

+ +

&lang=fr Set language to (in this example) French.

+ +

&noCloud Donā€™t allow cloud operations from this project (for running +projects from unknown

+ +

sources that include JavaScript code)

+ +

&noExitWarning When closing the window or loading a different URL, donā€™t +show the browser

+ +

ā€œare you sure you want to leave this pageā€ message.

+ +

&blocksZoom=n Like the Zoom blocks option in the Settings menu.

+ +

The last of these flags is intended for use on a web page in which a +Snap! window is embedded.

+ +

Hereā€™s an example that loads a shared (public) project from the Snap! +cloud:

+ +

http://snap.berkeley.edu/run#present:Username=jens&ProjectName=tree%20animation

+ +

(Note that ā€œUsernameā€ and ā€œProjectNameā€ are TitleCased, even though the +flags such as ā€œnoRunā€ are camelCased. Note also that a space in the +project name must be represented in Unicode as %20.) The verb present +behaves like run: it ordinarily starts the project in presentation mode, +but its behavior can be modified with the same four flags as for run. +The verb cloud (yes, we know itā€™s not a verb in its ordinary use) +behaves like open except that it loads from the Snap! cloud rather +than from the Internet in general. The verb dl (short for ā€œdownloadā€) +does not start Snap! but just downloads a cloud-saved project to your +computer as an .xml file. This is useful for debugging; sometimes a +defective project that Snap! wonā€™t run can be downloaded, edited, and +then re-saved to the cloud.

+ +

Mirror Sites

+ +

If the site snap.berkeley.edu is ever unavailable, you can load Snap! +at the following mirror sites:

+ + + +

Appendix A. Snap! color library {#appendix-a.-snap-color-library .ListParagraph}

+ +

{width=ā€5.8inā€ +height=ā€2.1791666666666667inā€}The Colors and Crayons library provides +several tools for manipulating color. Although its main purpose is +controlling a spriteā€™s pen color, it also establishes colors as a first +class data type:

+ +

{width=ā€3.1333333333333333inā€ +height=ā€0.5166666666666667inā€}For people who just want colors in their +projects without having to be color experts, we provide two simple +mechanisms: a color number scale with a broad range of continuous +color variation and a set of 100 crayons organized by color family +(ten reds, ten oranges, etc.) The crayons include the block colors:

+ +

{width=ā€7.166666666666667inā€ +height=ā€1.1inā€}For experts, we provide color selection by RGB, HSL, HSV, +X11/W3C names, and variants on those scales.

+ +

Introduction to Color

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.4444444444444444inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}Your computer monitor can display millions +of colors, but you probably canā€™t distinguish that many. For example, +hereā€™s red 57, green 180, blue 200: And hereā€™s red 57, green 182, blue +200: You might be able to tell them apart if you see them side by side: +ā€¦ but maybe not even then.

+ +

Color spaceā€”the collection of all possible colorsā€”is +three-dimensional, but there are many ways to choose the dimensions. RGB +(red-green-blue), the one most commonly used in computers, matches the +way TVs and displays produce color. Behind every dot on the screen are +three tiny lights: a red one, a green one, and a blue one. But if you +want to print colors on paper, your printer probably uses a different +set of three colors: CMY (cyan-magenta-yellow). You may have seen the +abbreviation CMYK, which represents the common technique of adding black +ink to the collection. (Mixing cyan, magenta, and yellow in equal +amounts is supposed to result in black ink, but typically it comes out a +muddy brown instead, because chemistry.) Other systems that try to mimic +human perception are HSL (hue-saturation-lightness) and HSV +(hue-saturation-value). There are many, many more, each designed for a +particular purpose.

+ +

If you are a color professionalā€”a printer, a web designer, a graphic +designer, an artistā€”then you need to understand all this. It can also +be interesting to learn about. For example, there are colors that you +can see but your computer display canā€™t generate. If that intrigues you, +look up color theory in +Wikipedia.

+ +

Crayons and Color Numbers

+ +

{width=ā€5.995833333333334inā€ +height=ā€0.825inā€}But if you just want some colors in your project, we +provide a simple, one-dimensional subset of the available colors. Two +subsets, actually: crayons and color numbers. Hereā€™s the difference:

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}The first row shows 100 distinct colors. +They have names; this is pumpkin, and this is denim. Youā€™re supposed to +think of them as a big box of 100 crayons. Theyā€™re arranged in families: +grays, pinks, reds, browns, oranges, etc. But theyā€™re not consistently +ordered within a family; youā€™d be unlikely to say ā€œnext crayonā€ in a +project. (But look at the crayon spiral on page 145.) Instead, youā€™d +think ā€œI want this to look like a really old-fashioned photoā€ and so +youā€™d find sepia as crayon number 33. You donā€™t have to memorize the +numbers! You can find them in a menu with a submenu for each family.

+ +

{width=ā€2.1597222222222223inā€ +height=ā€0.2569444444444444inā€}{width=ā€7.55inā€ +height=ā€2.1527777777777777inā€}Or, if you know the crayon name, just .

+ +

{width=ā€5.793055555555555inā€ +height=ā€0.3inā€}The crayon numbers are chosen so that skipping by 10 +gives a sensible box of ten crayons:

+ +

Alternatively, skipping by 5 gives a still-sensible set of twenty +crayons:

+ +

{width=ā€5.8inā€ height=ā€0.3inā€}

+ +

{width=ā€6.245138888888889inā€ +height=ā€0.25625inā€}The set of color numbers is arranged so that each +color number is visually near each of its neighbors. Bright and dark +colors alternate for each family. Color numbers range from 0 to 99, like +crayon numbers, but you can use fractional numbers to get as tiny a step +as you like:

+ +

(ā€œAs tiny as you likeā€ isnā€™t quite true because in the end, your color +has to be rounded to integer RGB values for display.)

+ +

Both of these scales include the range of shades of gray, from black to +white. Since black is the initial pen color, and black isnā€™t a hue, +Scratch and Snap! users would traditionally try to use set color to +escape from black, and it wouldnā€™t work. By including black in the same +scale as other colors, we eliminate the Black Hole problem if people use +only the recommended color scales.

+ +

We are making a point of saying ā€œcolor numberā€ for what was sometimes +called just ā€œcolorā€ in earlier versions of the library, because we now +reserve the name ā€œcolorā€ for an actual color, an instance of the color +data type.
+How to Use the Library

+ +

There are three library blocks specifically about controlling the pen. +They have the same names as three of the primitive Pen blocks:

+ +

{width=ā€6.066666666666666inā€ +height=ā€0.30833333333333335inā€}

+ +

{width=ā€7.4875inā€ +height=ā€1.1inā€}The first (Pen block-colored) input slot is used to +select which color scale you want to use. (These blocks also allow +reading or setting two block properties that are not colors: the pen +size and its transparency.) The pen reporter requires no other inputs; +it reports the state of the pen in whatever dimension you choose.

+ +

As the last example shows, you canā€™t ask for the pen color in a scale +incompatible with how you set it, unless the block can deduce what you +want from what it knows about the current pen color.

+ +

The change pen block applies only to numeric scales (including vectors +of three or four numbers). It adds its numeric or list input to the +current pen value(s), doing vector (item-by-item) addition for vector +scales.

+ +

{width=ā€7.491666666666666inā€ +height=ā€1.1069444444444445inā€}The set pen block changes the pen color to +the value(s) you specify. The meaning of the white input slots depends +on which attribute of the pen youā€™re setting:

+ +

In the last example, the number 37 sets the transparency, on the scale +0=opaque, 100=invisible. (All color attributes are on a 0ā€“100 scale +except for RGB components, which are 0ā€“255.) A transparency value can +be combined with any of these attribute scales.

+ +

{width=ā€5.383333333333334inā€ +height=ā€0.23333333333333334inā€}The library also includes two +constructors and a selector for colors as a data type:

+ +

{width=ā€1.8055555555555556inā€ +height=ā€0.19444444444444445inā€}The latter two are inverses of each +other, translating between colors and their attributes. The color from +blockā€™s attribute menu has fewer choices than the similar set pen block +because you can, for example, set the Red value of the existing pen +color leaving the rest unchanged, but when creating a color out of +nothing you have to provide its entire specification, e.g., all of Red, +Green, and Blue, or the equivalent in other scales. (As youā€™ll see on +the next page, we provide two linear (one-dimensional) color scales +that allow you to specify a color with a single number, at the cost of +including only a small subset of the millions of colors your computer +can generate.) If you have a color and want another color thatā€™s the +same except for one number, as in the Red example, you can use this +block:

+ +

Finally, the library includes the mix block and a helper:

+ +

{width=ā€6.113194444444445inā€ +height=ā€0.23333333333333334inā€}Weā€™ll have more to say about these after +a detour through color theory.

+ +

Thatā€™s all you have to know about colors! Crayons for specific +interesting ones, color numbers for gradual transformation from one +color to the next. But thereā€™s a bit more to say, if youā€™re interested. +If not, stop here. (But look at the samples of the different scales on +page 145.)
+More about Colors: Fair Hues and Shades

+ +

Several of the three-dimensional arrangements of colors use the concept +of ā€œhue,ā€ which more or less means where a color would appear in a +rainbow (magenta, near the right, is a long +story):

+ +

{width=ā€5.806666666666667inā€ +height=ā€0.30666666666666664inā€}

+ +

These are called ā€œspectralā€ colors, after the spectrum of rainbow +colors. But these colors arenā€™t equally distributed. Thereā€™s an awful +lot of green, hardly any yellow, and just a sliver of orange. And no +brown at all.

+ +

And this is already a handwave, because the range of colors that can be +generated by RGB monitors doesnā€™t include some of the true spectral +colors. See Spectral +color in Wikipedia for +all the gory details.

+ +

This isnā€™t a problem with the physics of rainbows. Itā€™s in the human eye +and the human brain that certain ranges of wavelength of light waves are +lumped together as named colors. The eye is just ā€œtunedā€ to recognize a +wide range of colors as green. (See Rods and +Cones.) And +different human cultures give names to different color ranges. +Nevertheless, in old Scratch projects, youā€™d say change pen color by 1 +and itā€™d take forever to reach a color that wasnā€™t green.

+ +

{width=ā€5.9944444444444445inā€ +height=ā€0.29930555555555555inā€}For color professionals, there are good +reasons to want to work with the physical rainbow hue layout. But for +amateurs using a simplified, one-dimensional color model, thereā€™s no +reason not to use a more programmer-friendly hue scale:

+ +

{width=ā€1.4597222222222221inā€ +height=ā€1.3583333333333334inā€}In this scale, each of the seven rainbow +colors and brown get an equal share. (Redā€™s looks too small, but thatā€™s +because itā€™s split between the two ends: hue 0 is pure red, brownish +reds are to its right, and purplish reds are wrapped around to the right +end.) We call this scale ā€œfair hueā€ because each color family gets a +fair share of the total hue range. (By the way, you were probably taught +ā€œā€¦ green, blue, indigo, violetā€ in school, but it turns out that color +names were different in Isaac Newtonā€™s day, and the color he called +ā€œblueā€ is more like modern cyan, while his ā€œindigoā€ is more like modern +blue. See Wikipedia Indigo.)

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}Our color number scale is based on fair +hues, adding a range of grays from black (color number 0) to white +(color number14) and also adding shades of the spectral colors. (In +color terminology, a shade is a darker version of a color; a lighter +version is called a tint.) Why do we add shades but not tints? Partly +because I find shades more exciting. A shade of red can be dark candy +apple red or maroon , but a tint is just some kind of pink . This +admitted prejudice is supported by an objective fact: Most projects are +made on a white background, so dark colors stand out better than light +ones.

+ +

{width=ā€5.999305555555556inā€ +height=ā€1.507638888888889inā€}So, in our color number scale, color +numbers 0 to 14 are kinds of gray; the remaining color numbers go +through the fair hues, but alternating full-strength colors with shades.

+ +

This chart shows how the color scales discussed so far are related. Note +that all scales range from 0 to 100; the fair hues scale has been +compressed in the chart so that similar colors line up vertically. (Its +dimensions are different because it doesnā€™t include the grays at the +left. Since there are eight color families, the pure, named fair hues +are at multiples of 100/8=12.5, starting with red=0.)

+ +

{width=ā€1.85inā€ +height=ā€1.0798611111111112inā€}White is crayon 14 and color number 14. +This value was deliberately chosen not to be a multiple of 5 so that +the every-fifth-crayon and every-tenth-crayon selections donā€™t include +it, so that all of the crayons in those smaller boxes are visible +against a white stage background.

+ +

Among purples, the official spectral violet (crayon 90) is the end of +the spectrum. Magenta, brighter than violet, isnā€™t a spectral color at +all. (In the picture at the left, the top part is the spectrum of white +light spread out through a prism; the middle part is a photograph of a +rainbow, and the bottom part is a digital simulation of a rainbow.) +Magenta is a mixture of red and blue. (attribution: Wikipedia user +Andys. CC BY-SA.)

+ +

The light gray at color number 10 is slightly different from crayon 10 +just because of roundoff in computing crayon values. Color number 90 is +different from crayon 90 because the official RGB violet (equal parts +red and blue) is actually lighter than spectral violet. The purple +family is also unusual because magenta, crayon and color number 95, is +lighter than the violet at 90. In other families, the color numbers, +crayons, and (scaled) fair hues all agree at multiples of ten. These +multiple-of-ten positions are the standard RGB primary and secondary +colors, e.g., the yellow at color number 50 is (255, 255, 0) in RGB. +(Gray, brown, and orange donā€™t have such simple RGB settings.)

+ +

The color numbers at odd multiples of five are generally darker shades +than the corresponding crayons. The latter are often official named +shades, e.g., teal, crayon 65, is a half-intensity shade of cyan. The +odd-five color numbers, though, are often darker, since they are +chosen to be the darkest color in a given family thatā€™s visibly +different from black. The pink at color number 15, though, is quite +different from crayon 15, because the former is a pure tint of red, +whereas the crayon, to get a more interesting pink, has a little magenta +mixed in. Color numbers at multiples of five are looked up in a table; +other color values are determined by linear interpolation in RGB space. +(Crayons are of course all found by table lookup.)

+ +

The from color block behaves specially when you ask for the color +number of a color. Most colors donā€™t exactly match a color number, and +for other attributes of a color (crayon number, X11 name) you donā€™t get +an answer unless the color exactly matches one of the names or numbers +in that attribute. But for color number, the block tries to find the +nearest color number to the color you specify. The result will be only +approximate; you canā€™t use the number you get to recreate the input +color. But you can start choosing nearby color numbers as you animate +the sprite.

+ +

Perceptual Spaces: HSV and HSL

+ +

{width=ā€0.7361111111111112inā€ +height=ā€0.7222222222222222inā€}RGB is the right way to think about colors +if youā€™re building or programming a display monitor; CMYK is the right +way if youā€™re building or programming a color printer. But neither of +those coordinate systems is very intuitive if youā€™re trying to +understand what color you see if, for example, you mix 37% red light, +52% green, and 11% blue. The hue scale is one dimension of most +attempts at a perceptual scale. The square at the right has pale blues +along the top edge, dark blues along the right edge, various shades of +gray toward the left, black at the bottom, and pure spectral blue in the +top right corner. Although no other point in the square is pure blue, +you can tell at a glance that no other spectral color is mixed with the +blue.

+ +

{width=ā€2.691666666666667inā€ +height=ā€1.1902777777777778inā€}Aside from hue, the other two dimensions +of a color space have to represent how much white and/or black is mixed +with the spectral color. (Bear in mind that ā€œmixing blackā€ is a metaphor +when it comes to monitors. There really is black paint, but thereā€™s no +such thing as black light.) One such space, HSV, has one dimension for +the amount of color (vs. white), called saturation, and one for the +amount of black, imaginatively called value. HSV stands for +Hue-Saturation-Value. (Value is also called brightness.) The value +is actually measured backward from the above description; that is, if +value is 0, the color is pure black; if value is 100, then a saturation +of 0 means all white, no spectral color; a saturation of 100 means no +white at all. In the square in the previous paragraph, the x axis is +the saturation and the y axis is the value. The entire bottom edge is +black, but only the top left corner is white. HSV is the traditional +color space used in Scratch and Snap!. Set pen color set the hue; set +pen shade set the value. There was originally no Pen block to set the +saturation, but thereā€™s a set brightness effect Looks block to control +the saturation of the spriteā€™s costume. (I speculate that the Scratch +designers, like me, thought tints were less vivid than shades against a +white background, so they made it harder to control tinting.)

+ +

{width=ā€1.5638888888888889inā€ +height=ā€0.29305555555555557inā€}{width=ā€1.5555555555555556inā€ +height=ā€0.2659722222222222inā€}{width=ā€0.7638888888888888inā€ +height=ā€0.7638888888888888inā€}But if youā€™re looking at colors on a +computer display, HSV isnā€™t really a good match for human perception. +Intuitively, black and white should be treated symmetrically. This is +the HSL (hue-saturation-lightness) color space. Saturation, in HSL, is +a measure of the grayness or dullness of a color (how close it comes +to being on a black-and-white scale) and lightness measures +spectralness with pure white at one end, pure black at the other end, +and spectral color in the middle. The saturation number is actually +the opposite of grayness: 0 means pure gray, and 100 means pure spectral +color, provided that the lightness is 50, midway between black and +white. Colors with lightness other than 50 have some black or white +mixed in, but saturation 100 means that the color is as fully saturated +as it can be, given the amount of white or black needed to achieve that +lightness. Saturation less than 100 means that both white and black +are mixed with the spectral color. (Such mixtures are called tones of +the spectral color. Perceptually, colors with saturation 100% donā€™t look +gray: but colors with saturation 75% do:

+ +

Note that HSV and HSL both have a dimension called ā€œsaturation,ā€ but +theyā€™re not the same thing! In HSV, ā€œsaturationā€ means non-whiteness, +whereas in HSL it means non-grayness (vividness).

+ +

More fine print: Itā€™s misleading to talk about the spectrum of light +wavelengths as if it were the same as perceived hue. If your computer +display is showing you a yellow area, for example, itā€™s doing it by +turning on its red and green LEDs over that area, and what hits your +retina is still two wavelengths of light, red and green, superimposed. +You could make whatā€™s perceptually the same yellow by using a single +intermediate wavelength. Your eye and brain donā€™t distinguish between +those two kinds of yellow. Also, your brain automatically adjusts +perceived hue to correct for differences in illumination. When you place +a monochrome object so that itā€™s half in sunlight and half in the shade, +you see it as one even though whatā€™s reaching your eyes from the two +regions differs a lot. And, sadly, itā€™s HSL whose use of ā€œsaturationā€ +disagrees with the official international color vocabulary +standardization committee. I learned all this from this +tutorial, which you might find +more coherent than jumping around Wikipedia if youā€™re interested.

+ +

{width=ā€1.64375inā€ +height=ā€0.8416666666666667inā€}Although traditional Scratch and Snap! +use HSV in programs, they use HSL in the color picker. The horizontal +axis is hue (fair hue, in this version) and the vertical axis is +lightness, the scale with black at one end and white at the other end. +It would make no sense to have only the bottom half of this selector +(HSV Value) or only the top half (HSV Saturation). And, given that you +can only fit two dimensions on a flat screen, it makes sense to pick HSL +saturation (vividness) as the one to keep at 100%. (In this fair-hue +picker, some colors appear twice: ā€œspectralā€ (50% lightness) browns as +shades (ā‰ˆ33% lightness) of red or orange, and shades of those browns.)

+ +

{width=ā€0.20277777777777778inā€ +height=ā€0.20277777777777778inā€}{width=ā€0.18888888888888888inā€ +height=ā€0.18888888888888888inā€}Software that isnā€™t primarily about +colors (so, not including Photoshop, for example) typically use HSV or +HSL, with web-based software more likely to use HSV because thatā€™s +whatā€™s built into the JavaScript programming language provided by +browsers. But if the goal is to model human color perception, neither of +these color spaces is satisfactory, because they assume that all +full-intensity spectral colors are equally bright. But if youā€™re like +most people, you see spectral yellow as much brighter than spectral blue +. There are better perceptual color spaces with names like L*u*v* and +L*a*b* that are based on research with human subjects to determine +true perceived brightness. Wikipedia explains all this and more at HSL +and HSV, where they +recommend ditching both of these simplistic color spaces.

+ +

Mixing Colors

+ +

Given first class colors, the next question is, what operations apply to +them, the way arithmetic operators apply to numbers and higher order +functions apply to lists? The equivalent to adding numbers is mixing +colors, but unfortunately there isnā€™t a simple answer to what that +means.

+ +

{width=ā€4.347222222222222inā€ +height=ā€0.5625inā€}The easiest kind of color mixing to understand is +additive mixing, which is what happens when you shine two colored +lights onto a (white) wall. Itā€™s also what happens in your computer +screen, where each dot (pixel) of an image is created by a tiny red +light, a tiny green light, and a tiny blue light that can be combined at +different strengths to make different colors. Essentially, additive +mixing of two colors is computed by adding the two red components, the +two green components, and the two blue components. Itā€™s not quite that +simple only because each component of the result must be in the range 0 +to 255. So, red (255, 0, 0) mixed with green (0, 255, 0) gives (255, +255, 0), which is yellow. But red (255, 0, 0) plus yellow (255, 255, 0) +canā€™t give (510, 255, 0). Just limiting the red in the result to 255 +would mean that red plus yellow is yellow, which doesnā€™t make sense. +Instead, if the red value has to be reduced by half (from 510 to 255), +then all three values must be reduced by half, so the result is (255, +128, 0), which is orange. (Half of 255 is 127.5, but each RGB value must +be an integer.)

+ +

{width=ā€4.492361111111111inā€ +height=ā€0.55inā€}A different kind of color mixing based on light is done +when different colored transparent plastic sheets are held in front of a +white light, as is done in theatrical lighting. In that situation, the +light that gets through both filters is what remains after some light is +filtered out by the first one and some of whatā€™s left is filtered out by +the second one. In red-green-blue terms, a red filter filters out green +and blue; a yellow filter allows red and green through, filtering out +blue. But there isnā€™t any green light for the yellow filter to pass; it +was filtered out by the red filter. Each filter can only remove light, +not add light, so this is called subtractive mixing:

+ +

Perhaps confusingly, the numerical computation of subtractive mixing is +done by multiplying the RGB values, taken as fractions of the maximum +255, so red (1, 0, 0) times yellow (1, 1, 0) is red again.

+ +

Those are both straightforward to compute. Much, much more complicated +is trying to simulate the result of mixing paints. Itā€™s not just that +weā€™d have to compute a more complicated function of the red, green, and +blue values; itā€™s that RGB values (or any other three-dimensional color +space) are inadequate to describe the behavior of paints. Two paints can +look identical, and have the same RGB values, but may still behave very +differently when mixed with other colors. The differences are mostly due +to the chemistry of the paints, but are also affected by exactly how the +colors are mixed. The mixing is mostly subtractive; red paint absorbs +most of the colors other than red, so whatā€™s reflected off the surface +is whatever isnā€™t absorbed by the colors being mixed. But there can be +an additive component also.

+ +

{width=ā€7.5inā€ +height=ā€0.875inā€}The proper mathematical abstraction to describe a paint +is a reflectance graph, like this:

+ +

(These arenā€™t paints, but minerals, and one software-generated spectrum, +from the US Geological Surveyā€™s Spectral +Library. +The details donā€™t matter, just the fact that a graph like these gives +much more information than three RGB numbers.) To mix two paints +properly, you multiply the y values (as fractions) at each matching +x coordinate of the two graphs.

+ +

{width=ā€4.627777777777778inā€ +height=ā€0.5763888888888888inā€} Having said all that, the mix block takes +the colors it is given as inputs and converts them into what we hope are +typical paint reflectance spectra that would look like those colors, +and then mixes those spectra and converts back to RGB.

+ +

But unlike the other two kinds of mixing, in this case we canā€™t say that +these colors are ā€œthe right answerā€; what would happen with real paints +depends on their chemical composition and how theyā€™re mixed. There are +three more mixing options, but these three are the ones that correspond +to real-world color mixing.

+ +

{width=ā€4.340277777777778inā€ +height=ā€0.6527777777777778inā€}The mix block will accept any number of +colors, and will mix them in equal proportion. If (for any kind of +mixing) you want more of one color than another, use the color at weight +block to make a ā€œweighted colorā€:

+ +

{width=ā€5.166666666666667inā€ +height=ā€0.4305555555555556inā€}This mixes four parts red paint to one +part green paint. All colors in a mixture can be weighted:

+ +

(Thanks to Scott +Burns for his help in +understanding paint mixing, along with David +Briggsā€™s tutorial. Remaining +mistakes are bhā€™s.)

+ +

tl;dr

+ +

{width=ā€1.9326388888888888inā€ +height=ā€2.220833333333333inā€}{width=ā€2.227777777777778inā€ +height=ā€2.267361111111111inā€}For normal people, Snap! provides three +simple, one-dimensional scales: [crayons]{.underline} for specific +interesting colors, [color numbers]{.underline} for a continuum of +high-contrast colors with a range of hues and shading, and [fair +hues]{.underline} for a continuum without shading. For color nerds, it +provides three-dimensional color spaces RGB, HSL, HSV, and fair-hue +variants of the latter two. We recommend ā€œfair HSLā€ for zeroing in on a +desired color.

+ +

{width=ā€1.5347222222222223inā€ +height=ā€1.8472222222222223inā€}

+ +

{width=ā€2.2111111111111112inā€ height=ā€2.267361111111111inā€}{width=ā€2.061111111111111inā€ height=ā€2.2222222222222223inā€}{width=ā€1.9152777777777779inā€ height=ā€2.234722222222222inā€} Subappendix: Geeky details on fair hue

+ +

{width=ā€6.2375inā€ +height=ā€2.5inā€}The left graph shows that, unsurprisingly, all of the +brown fair hues make essentially no progress in real hue, with the +orange-brown section actually a little retrograde, since browns are +really shades of orange and so the real hues overlap between fair browns +and fair oranges. Green makes up some of the distance, because there are +too many green real hues and part of the goal of the fair hue scale is +to squeeze that part of the hue spectrum. But much of the catching up +happens very quickly, between pure magenta at fair hue 93.75 and the +start of the purple-red section at fair hue 97. This abrupt change is +unfortunate, but the alternatives involve either stealing space from red +or stealing space from purple (which already has to include both +spectral violet and RGB magenta). The graph has discontinuous derivative +at the table-lookup points, of which there are two in each color family, +one at the pure-named-RGB colors at multiples of 12.5, and the other +roughly halfway to the next color family, except for the purple +family, which has lookup points at 87.5 (approximate spectral violet), +93.75 (RGB magenta), and 97 (turning point toward the red family). (In +the color picker, blue captures cyan and purple space in dark shades. +This, too, is an artifact of human vision.)

+ +

The right graph shows the HSV saturation and value for all the fair +hues. Saturation is at 100%, as it should be in a hue scale, except for +a very slight drop in part of the browns. (Browns are shades of orange, +not tints, so one would expect full saturation, except that some of the +browns are actually mixtures with related hues.) But value, also as +expected, falls substantially in the browns, to a low of about 56% +(halfway to black) for the ā€œpureā€ brown at 45Ā° (fair hue 12.5). But the +curve is smooth, without inflection points other than that minimum-value +pure brown.

+ +

ā€œFair saturationā€ and ā€œfair valueā€ are by definition 100% for the entire +range of fair hues. This means that in the browns, the real saturation +and value are the product (in percent) of the innate shading of the +specific brown fair hue and the userā€™s fair saturation/value setting. +When the userā€™s previous color setting was in a real scale and the new +setting is in a fair scale, the program assumes that the previous +saturation and value were entirely user-determined; when the previous +color setting was in a brown fair hue and the new setting is also in a +fair scale, the program remembers the userā€™s intention from the previous +setting. (Internal calculations are based on HSV, even though we +recommend HSL to users, because HSV comes to us directly from the +JavaScript color management implementation.) This is why the set pen +block includes options for ā€œfair saturationā€ and so on.

+ +

{width=ā€5.9875inā€ +height=ā€0.3784722222222222inā€}For the extra-geeky, here are the exact +table lookup points (fair hue, [0,100]):

+ +

and here are the RGB settings at those points:

+ +

{width=ā€5.9840277777777775inā€ height=ā€1.3736111111111111inā€} Subappendix: Geeky details on color numbers

+ +

{width=ā€2.0833333333333335inā€ +height=ā€2.2916666666666665inā€}Here is a picture of integer color +numbers, but remember that color numbers are continuous. (As usual, +ā€œcontinuousā€ values are ultimately converted to integer RGB values, so +thereā€™s really some granularity.) Color numbers 0-14 are continuously +varying grayscale, from 0=black to 14=white. Color numbers 14+Īµ to 20 +are linearly varying shades of pink, with RGB Red at color number 20.

+ +

Beyond that point, in each color family, the multiple of ten color +number in the middle is the RGB standard color of that family, in which +each component is either 255 or 0. (Exceptions are brown, which is of +course darker than any of those colors; orange, with its green component +half-strength: [255, 127, 0]; and violet, discussed below.) The +following multiple of five is the number of the darkest color in that +family, although not necessarily the same hue as the multiple of ten +color number. Color numbers between the multiple of ten and the +following multiple of five are shades of colors entirely within the +family. Color numbers in the four before the multiple of ten are +mixtures of this family and the one before it. So, for example, in the +green family, we have

+ +

55 Darkest yellow.

+ +

(55, 60) shades of yellow-green mixtures. As the color number increases, +both the hue and the lightness (or value, depending on your religion) +increase, so we get brighter and greener colors.

+ +

60 Canonical green, [0, 255, 0], whose W3C color name is ā€œlime,ā€ not +ā€œgreen.ā€

+ +

(60, 65) Shades of green. No cyan mixed in.

+ +

65 Darkest green.

+ +

(65,70) Shades of green-cyan mixtures.

+ +

In the color number chart, all the dark color numbers look a lot like +black, but theyā€™re quite different. Here are the darkest colors in each +color number family.

+ +

{width=ā€1.3888888888888888inā€ +height=ā€1.3888888888888888inā€}Darkest yellow doesnā€™t look entirely +yellow. You might see it as greenish or brownish. As it turns out, the +darkest color that really looks yellow is hardly dark at all. This color +was hand-tweaked to look neither green nor brown to me, but ymmv.

+ +

In some families, the center+5 crayon is an important named darker +version of the center color: In the red family, [128, 0, 0] is +ā€œmaroon.ā€ In the cyan family, [0, 128, 128] is ā€œteal.ā€ An early +version of the color number scale used these named shades as the +center+5 color number also. But on this page we use the word ā€œdarkestā€ +advisedly: You canā€™t find a darker shade of this family anywhere in the +color number scale, but you can find lighter shades. Teal is color +number 73.1, ($70 + 5 \bullet \frac{255 - 128}{255 - 50}$), because +darkest cyan, color 75, is [0, 50, 50]. The color number for maroon is +left as an exercise for the reader.

+ +

The purple family is different from the others, because it has to +include both spectral violet and extraspectral RGB magenta. Violet is +usually given as RGB [128, 0, 255], but thatā€™s much brighter than the +violet in an actual spectrum (see page 142). We use [80, 0, 90], a +value hand-tweaked to look as much as possible like the violet in +rainbow photos, as color number 90. (Crayon 90 is [128, 0, 255].) +Magenta, [255, 0, 255], is color number 95. This means that the colors +get brighter, not darker, between 90 and 95. The darkest violet is +actually color number 87.5, so itā€™s bluer than standard violet, but +still plainly a purple and not a blue. Itā€™s [39,0,76]. Itā€™s not +hand-tweaked; itā€™s a linear interpolation between darkest blue, [0, 0, +64], and the violet at color number 90. I determined by experiment that +color number 87.5 is the darkest one thatā€™s still unambiguously purple. +(According to Wikipedia, ā€œvioletā€ names only the spectral color, while +ā€œpurpleā€ is the name of the whole color family.)

+ +

Here are the reference points for color numbers that are multiples of +five, except for item 4, which is used for color 14, not color 15:

+ +

{width=ā€4.583333333333333inā€ +height=ā€1.2777777777777777inā€}

+ +

Appendix B. APL features {#appendix-b.-apl-features .ListParagraph}

+ +

The book A Programming Language was published by mathematician Kenneth +E. Iverson in 1962. He wanted a formal language that would look like +what mathematicians write on chalkboards. The then-unnamed language +would later take its name from the first letters of the words in the +bookā€™s title. It was little-known until 1964, when a formal description +of the just-announced IBM System/360 in the IBM Systems Journal used +APL notation. (Around the same time, Iversonā€™s associate Adin Falkoff +gave a talk on APL to a New York Association for Computing Machinery +chapter, with an excited 14-year-old Brian Harvey in the audience.) But +it wasnā€™t until 1966 that the first public implementation of the +language for the System/360 was published by IBM. (It was called +ā€œAPL\360ā€ because the normal slash character / represents the ā€œreduceā€ +operator in APL, while backslash is ā€œexpand.ā€)

+ +

The crucial idea behind APL is that mathematicians think about +collections of numbers, one-dimensional vectors and two-dimensional +matrices, as valid objects in themselves, what computer scientists +later learned to call ā€œfirst class data.ā€ A mathematician who wants to +add two vectors writes v~1~ + v~2~, not ā€œfor i = 1 to +length(v1), result[i]=v1[i]+v2[i].ā€ Same for a programmer using +APL.

+ +

There are three kinds of function in APL: scalar functions, mixed +functions, and operators. A scalar function is one whose natural +domain is individual numbers or text characters. A mixed function is +one whose domain includes arrays (vectors, matrices, or +higher-dimensional collections). In Snap!, scalar functions are +generally found in the green Operators palette, while mixed functions +are in the red Lists palette. The third category, confusingly for +Snap! users, is called operators in APL, but corresponds to what we +call higher order functions: functions whose domain includes functions.

+ +

Snap! hyperblocks are scalar functions that behave like APL scalar +functions: they can be called with arrays as inputs, and the underlying +function is applied to each number in the arrays. (If the function is +monadic, meaning that it takes one input, then thereā€™s no complexity +to this idea. Take the square root of an array, and you are taking the +square root of each number in the array. If the function is dyadic, +taking two inputs, then the two arrays must have the same shape. Snap! +is more forgiving than APL; if the arrays donā€™t agree in number of +dimensions, called the rank of the array, the lower-rank array is +matched repeatedly with subsets of the higher-rank one; if they donā€™t +agree in length along one dimension, the result has the shorter length +and some of the numbers in the longer-length array are ignored. An +exception in both languages is that if one of the two inputs is a +scalar, then it is matched with every number in the other array input.)

+ +

As explained in Section I.G, this termwise extension of scalar functions +is the main APL-like feature built into Snap! itself. We also include +an extension of the item block to address multiple dimensions, an +extension to the length block with five list functions from APL, and a +new primitive reshape block. The APL library extends the implementation +of APL features to include a few missing scalar functions and several +missing mixed functions and operators.

+ +

Programming in APL really is very different in style from programming +in other languages, even Snap!. This appendix canā€™t hope to be a +complete reference for APL, let alone a tutorial. If youā€™re interested, +find one of those in a library or a (probably used) bookstore, read it, +and do the exercises. Sorry to sound like a teacher, but the notation +is sufficiently weird as to take a lot of practice before you start to +think in APL.

+ +

A note on versions: There is a widely standardized APL2, several +idiosyncratic extensions, and a successor language named J. The latter +uses plain ASCII characters, unlike the ones with APL in their names, +which use the mathematicianā€™s character set, with Greek letters, +typestyles (boldface and/or italics in books; underlined, upper case, or +lower case in APL) as loose type declarations, and symbols not part of +anyoneā€™s alphabet, such as āŒŠ for floor and āŒˆ for ceiling. To use the +original APL, you needed expensive special computer terminals. (This was +before you could download fonts in software. Today the more unusual APL +characters are in Unicode at U+2336 to U+2395.) The character set was +probably the main reason APL didnā€™t take over the world. APL2 has a lot +to recommend it for Snap! users, mainly because it moves from the +original APL idea that all arrays must be uniform in dimension, and the +elements of arrays must be numbers or single text characters, to our +idea that a list can be an element of another list, and that such +elements donā€™t all have to have the same dimensions. Nevertheless, its +mechanism for allowing both old-style APL arrays and more general +ā€œnested arraysā€ is complicated and hard for an APL beginner (probably +all but two or three Snap! users) to understand. So we are starting +with plain APL. If it turns out to be wildly popular, we may decide +later to include APL2 features.

+ +

Here are some of the guiding ideas in the design of the APL library:

+ +

{width=ā€4.451388888888889inā€ +height=ā€0.5208333333333334inā€}Goal:Ā  Enable interested Snap! users +to learn the feel and style of APL programming. Itā€™s really worth the +effort. For example, we didnā€™t hyperize the = block because Snap! +users expect it to give a single yes-or-no answer about the equality of +two complete structures, whatever their types and shapes. In APL, = is a +scalar function; it compares two numbers or two characters. How could +APL users live without the ability to ask if two structures are equal? +Because in APL you can say āˆ§/,a=b to get that answer. Reading from +right to left, a=b reports an array of Booleans (represented in APL as 0 +for False, 1 for True); the comma operator turns the shape of the array +into a simple vector; and āˆ§/ means ā€œreduce with andā€; ā€œreduceā€ is +our combine function. That six-character program is much less effort +than the equivalent

+ +

{width=ā€0.9930555555555556inā€ +height=ā€0.20833333333333334inā€}in Snap!. Note in passing that if you +wanted to know how many corresponding elements of the two arrays are +equal, youā€™d just use +/ instead of āˆ§/. Note also that our APLish +blocks are a little verbose, because they include up to three notations +for the function: the usual Snap! name (e.g., flatten), the name APL +programmers use when talking about it (ravel), and, in yellow type, the +symbol used in actual APL code (,). Weā€™re not consistent about it; seems +self-documenting. And LCM (and) is different even though it has two +names; it turns out that if you represent Boolean values as 0 and 1, +then the algorithm to compute the least common multiple of two integers +computes the and function if the two inputs happen to be Boolean. +Including the APL symbols serves two purposes: the two or three Snap! +users whoā€™ve actually programmed in APL will be sure what function +theyā€™re using, but more importantly, the ones who are reading an APL +tutorial while building programs in Snap! will find the block that +matches the APL theyā€™re reading.
+
+Goal:Ā  Bring the best and most general APL ideas into ā€œmainstreamā€ +Snap! programming style. Media computation, in particular, becomes +much simpler when scalar functions can be applied to an entire picture +or sound. Yes, map provides essentially the same capability, but the +notation gets complicated if you want to map over columns rather than +rows. Also, Snap! lists are fundamentally one-dimensional, but real +data often have more dimensions. A Snap! programmer has to be thinking +all the time about the convention that we represent a matrix as a list +of rows, each of which is a list of individual cells. That is, row 23 of +a spreadsheet is item 23 of spreadsheet, but column 23 is map (item 23 +of _) over spreadsheet. APL treats rows and columns more +symmetrically.
+
+Non-goal:Ā  Allow programs written originally in APL to run in +Snap! essentially unchanged.Ā  For example, in APL the atomic text +unit is a single character, and strings of characters are lists. We +treat a text string as scalar, and that isnā€™t going to change. Because +APL programmers rarely use conditionals, instead computing functions +involving arrays of Boolean values to achieve the same effect, the +notation they do have for conditionals is primitive (in the sense of +Paleolithic, not in the sense of built in). Weā€™re not changing ours.
+
+Non-goal:Ā  Emulate the terse APL syntax. Itā€™s too bad, in a way; as +noted above, the terseness of expressing a computation affects APL +programmersā€™ sense of whatā€™s difficult and what isnā€™t. But you canā€™t say +ā€œterseā€ and ā€œblock languageā€ in the same sentence. Our whole raison +dā€™ĆŖtre is to make it possible to build a program without having to +memorize the syntax or the names of functions, and to allow those names +to be long enough to be self-documenting. And APLā€™s syntax has its own +issues, of which the biggest is that itā€™s hard to use functions with +more than two inputs; because most mathematical dyadic functions use +infix notation (the function symbol between the two inputs), the notion +of ā€œleft argumentā€ and ā€œright argumentā€ is universal in APL +documentation. The thing people most complain about, that there is no +operator precedence (like the multiplication-before-addition rule in +normal arithmetic notation), really doesnā€™t turn out to be a problem. +Function grouping is strictly right to left, so 2Ɨ3+4 means two times +seven, not six plus four. That takes some getting used to, but it really +doesnā€™t take long if you immerse yourself in APL. The reason is that +there are too many infix operators for people to memorize a precedence +table. But in any case, block notation eliminates the problem, +especially with Snap!ā€™s zebra coloring. You can see and control the +grouping by which block is inside which other blockā€™s input slot. +Another problem with APLā€™s syntax is that it bends over backward not to +have reserved words, as opposed to Fortran, its main competition back +then. So the dyadic ā—‹ ā€œcircular functionsā€ function uses the left +argument to select a trig function. 1ā—‹x is sin(x), 2ā—‹x is +cos(x), and so on. ā€¾1ā—‹x is arcsin(x). Whatā€™s 0ā—‹x? Glad you +asked; itā€™s$\ \sqrt{1 - x^{2}}$.

+ +

Boolean values

+ +

Snap! uses distinct Boolean values true and false that are different +from other data types. APL uses 1 and 0, respectively. The APL style of +programming depends heavily on doing arithmetic on Booleans, although +their conditionals insist on only 0 or 1 in a Boolean input slot, not +other numbers. Snap! arithmetic functions treat false as 0 and true +as 1, so our APL library tries to report Snap! Boolean values from +predicate functions.

+ +

{width=ā€5.733333333333333inā€ height=ā€1.1066666666666667inā€}Scalar functions

+ +

{width=ā€2.566666666666667inā€ +height=ā€0.21666666666666667inā€}These are the scalar functions in the APL +library. Most of them are straightforward to figure out. The scalar = +block provides an APL-style version of = (and other exceptions) as a +hyperblock that extends termwise to arrays. Join, the only non-predicate +non-hyper scalar primitive, has its own scalar join block. 7 deal 52 +reports a random vector of seven numbers from 1 to 52 with no +repetitions, as in dealing a hand of cards. Signum of a number reports 1 +if the number is positive, 0 if itā€™s zero, or -1 if itā€™s negative. Roll +6 reports a random roll of a six-sided die. To roll 8 dice, use , which +would look much more pleasant as ?8ā“6. But perhaps our version is more +instantly readable by someone who didnā€™t grow up with APL. All the +library functions have help messages available.

+ +

Mixed functions

+ +

Mixed functions include lists in their natural domain or range. That is, +one or both of its inputs must be a list, or it always reports a list. +Sometimes both inputs are naturally lists; sometimes one input of a +dyadic mixed function is naturally a scalar, and the function treats a +list in that input slot as an implicit map, as for scalar functions. +This means you have to learn the rule for each mixed function +individually.

+ +

{width=ā€4.275inā€ +height=ā€1.1inā€}{width=ā€1.0666666666666667inā€ +height=ā€0.18333333333333332inā€}The shape of function takes any input and +reports a vector of the maximum size of the structure along each +dimension. For a vector, it returns a list of length 1 containing the +length of the input. For a matrix, it returns a two-item list of the +number of rows and number of columns of the input. And so on for higher +dimensions. If the input isnā€™t a list at all, then it has zero +dimensions, and shape of reports an empty vector.

+ +

Equivalent to the dimensions of primitive, as of 6.6.

+ +

{width=ā€1.0416666666666667inā€ +height=ā€0.18333333333333332inā€}{width=ā€2.033333333333333inā€ +height=ā€0.18333333333333332inā€}Rank of isnā€™t an actual APL primitive, +but the composition ā“ā“ (shape of shape of a structure), which reports +the number of dimensions of the structure (the length of its shape +vector), is too useful to omit. (Itā€™s very easy to type the same +character twice on the APL keyboard, but less easy to drag blocks +together.) Equivalent to the rank of primitive, as of 6.6.

+ +

{width=ā€7.325inā€ +height=ā€0.8333333333333334inā€}Reshape takes a shape vector (such as +shape might report) on the left and any structure on the right. It +ignores the shape of the right input, stringing the atomic elements into +a vector in row-major order (that is, all of the first row left to +right, then all of the second row, etc.). (The primitive reshape takes +the inputs in the other order.) It then reports an array with the shape +specified by the first input containing the items of the second:

+ +

{width=ā€6.575inā€ +height=ā€1.0416666666666667inā€}If the right input has more atomic +elements than are required by the left-input shape vector, the excess +are ignored without reporting an error. If the right input has too few +atomic elements, the process of filling the reported array starts again +from the first element. This is most useful in the specific case of an +atomic right input, which produces an array of any desired shape all of +whose atomic elements are equal. But other cases are sometimes useful +too:

+ +

{width=ā€5.508333333333334inā€ +height=ā€1.25inā€}
+{width=ā€1.4333333333333333inā€ +height=ā€0.18333333333333332inā€}Flatten takes an arbitrary structure as +input and reports a vector of its atomic elements in row-major order. +Lispians call this flattening the structure, but APLers call it ā€œravelā€ +because of the metaphor of pulling on a ball of yarn, so what they +really mean is ā€œunravel.ā€ (But the snarky sound of that is uncalled-for, +because a more advanced version that we might implement someday is more +like raveling.) One APL idiom is to apply this to a scalar in order to +turn it into a one-element vector, but we canā€™t use it that way because +you canā€™t type a scalar value into the List-type input slot. Equivalent +to the primitive flatten of block.

+ +

{width=ā€3.3618055555555557inā€ +height=ā€0.25inā€}

+ +

{width=ā€7.204166666666667inā€ +height=ā€0.5833333333333334inā€}Catenate is like our primitive append, +with two differences: First, if either input is a scalar, it is treated +like a one-item vector. Second, if the two inputs are of different rank, +the catenate function is recursively mapped over the higher-rank input:

+ +

{width=ā€0.5333333333333333inā€ +height=ā€0.25inā€}Catenate vertically is similar, but it adds new rows +instead of adding new columns.

+ +

{width=ā€6.341666666666667inā€ +height=ā€1.0416666666666667inā€}Integers (I think thatā€™s what it stands +for, although APLers just say ā€œiotaā€) takes a positive integer input and +reports a vector of the integers from 1 to the input. This is an example +of a function classed as ā€œmixedā€ not because of its domain but because +of its range. The difference between this block and the primitive +numbers from block is in its treatment of lists as inputs. Numbers from +is a hyperblock, applying itself to each item of its input list:

+ +

{width=ā€6.025inā€ +height=ā€0.8333333333333334inā€}Iota has a special meaning for list +inputs: The input must be a shape vector; the result is an array with +that shape in which each item is a list of the indices of the cell along +each dimension. A picture is worth 10^3^ words, but Snap! isnā€™t so +good at displaying arrays with more than two dimensions, so here we +reduce each cellā€™s index list to a string:

+ +

{width=ā€1.475inā€ +height=ā€0.25inā€}

+ +

{width=ā€5.95inā€ +height=ā€1.1inā€}Dyadic iota is like the index of primitive except for its +handling of multi-dimensional arrays. It looks only for atomic elements, +so a vector in the second input doesnā€™t mean to search for that vector +as a row of a matrix, which is what it means to index of, but rather to +look separately for each item of the vector, and report a list of the +locations of each item. If the first input is a multi-dimensional array, +then the location of an item is a vector with the indices along each +row.

+ +

In this example, the 4 is in the second row, second column. (This is +actually an extension of APL iota, which is more like a hyperized index +of.) Generalizing, if the rank of the second input is less than the rank +of the first input by two or more, then iota looks for the entire second +input in the first input. The reported position is a vector +{width=ā€5.841666666666667inā€ +height=ā€0.35inā€}whose length is equal to the difference between the two +ranks. If the rank of the second input is one less than the rank of the +first, the reported value is a scalar, the index of the entire second +input in the first.

+ +

{width=ā€5.383333333333334inā€ +height=ā€1.1inā€}

+ +

{width=ā€5.375inā€ +height=ā€3.2416666666666667inā€}Why the strange design decision to report +length+1 when something isnā€™t found, instead of a more obvious flag +value such as 0 or false? Hereā€™s why:

+ +

{width=ā€2.175inā€ +height=ā€0.225inā€}Note that code has 27 items, not 26. The asterisk at +the end is the ciphertext is the translation of all non-alphabet +characters (spaces and the apostrophe in ā€œdoesnā€™tā€). This is a silly +example, because it makes up a random cipher every time itā€™s called, and +it doesnā€™t report the cipher, so the recipient canā€™t decipher the +message. And you wouldnā€™t want to make the spaces in the message so +obvious. But despite being silly, the example shows the benefit of +reporting length+1 as the position of items not found.

+ +

{width=ā€7.485416666666667inā€ +height=ā€0.6597222222222222inā€}The contained in block is like a hyperized +contains with the input order reversed. It reports an array of Booleans +the same shape as the left input. The shape of the right input doesnā€™t +matter; the block looks only for atomic elements.

+ +

{width=ā€2.6645833333333333inā€ +height=ā€0.31666666666666665inā€}The blocks grade up and grade down are +used for sorting data. Given an array as input, it reports a vector of +the indices in which the items (the rows, if a matrix) should be +rearranged in order to be sorted. This will be +{width=ā€7.4944444444444445inā€ +height=ā€1.8069444444444445inā€}clearer with an example:

+ +

The result from grade up tells us that item 3 of foo comes first in +sorted order, then item 4, then 2, then 1. When we actually select items +of foo based on this ordering, we get the desired sorted version. +The result reported by grade down is almost the reverse of that from +grade up, but not quite, if there are equal items in the list. (The sort +is stable, so if there are equal items, then whichever comes first in +the input list will also be first in the sorted list.)

+ +

Why this two-step process? Why not just have a sort primitive in APL? +One answer is that in a database application you might want to sort one +array based on the order of another array:

+ +

This is the list of employees of a small company. (Taken from Structure +and Interpretation of Computer Programs by Abelson and Sussman. +Creative Commons licensed.) Each of the smaller lists contains a +person's name, job title, and yearly salary. +{width=ā€5.483333333333333inā€ +height=ā€2.2inā€}We would like to sort the employeesā€™ names in +big-to-small order of salary. First we extract column 3 of the database, +the salaries:

+ +

{width=ā€3.5590277777777777inā€ +height=ā€1.976388888888889inā€}
+Then we use grade down to get the reordering indices:

+ +

{width=ā€5.333333333333333inā€ +height=ā€2.3733333333333335inā€}{width=ā€4.978472222222222inā€ +height=ā€2.2333333333333334inā€}At this point we could use the index +vector to sort the salaries:

+ +

{width=ā€5.593333333333334inā€ +height=ā€2.3inā€}But what we actually want is a list of names, sorted by +salary:

+ +

{width=ā€2.308333333333333inā€ +height=ā€0.275inā€}{width=ā€2.9166666666666665inā€ +height=ā€0.325inā€}By taking the index vector from grade down of column 3 +and telling item to apply it to column 1, we get what we set out to +find. As usual the code is more elegant in APL: +database[ā’database[;3];1].

+ +

{width=ā€2.9472222222222224inā€ +height=ā€0.22569444444444445inā€}In case youā€™ve forgotten, or would select +the third row of the database; we need the list 3 in the second input +slot of the outer list to select by columns rather than by rows.

+ +

Select (if take) or select all but (if drop) the first (if n>0) or +last (if n<0) |n| items from a vector, or rows from a matrix. +Alternatively, if the left input is a two-item vector, select rows with +the first item and columns with the second.

+ +

The compress block selects a subset of its right input based on the +Boolean values in its left input, which must be a vector of Booleans +whose length equals the length of the array (the number of rows, for a +matrix) in the right input. The block reports an array of the same rank +as the right input, but containing only those rows whose corresponding +Boolean value is true. The columns version āŒæ is the same but +selecting columns rather than selecting rows.

+ +

{width=ā€6.452083333333333inā€ +height=ā€0.25inā€}A word about the possibly confusing names of these +blocks: There are two ways to think about what they do. Take the +standard / version, to avoid talking about both at once. One way to +think about it is that it selects some of the rows. The other way is +that it shortens the columns. For Lispians, which includes you since +youā€™ve learned about keep, the natural way to think about / is that it +keeps some of the rows. Since we represent a matrix as a list of rows, +that also fits with how this function is implemented. (Read the code; +youā€™ll find a keep inside.) But APL people think about it the other way, +so when you read APL documentation, / is described as operating on the +last dimension (the columns), while āŒæ is described as operating on +rows. We were more than a month into this project before I understood +all this. You get long block names so it wonā€™t take you a month!

+ +

{width=ā€3.175inā€ +height=ā€0.18333333333333332inā€}{width=ā€2.9944444444444445inā€ +height=ā€0.23333333333333334inā€}{width=ā€1.1118055555555555inā€ +height=ā€0.23333333333333334inā€}Donā€™t confuse this block with the reduce +block, whose APL symbol is also a slash. In that block, what comes to +the left of the slash is a dyadic combining function; itā€™s the APL +equivalent of combine. This block is more nearly equivalent to keep. But +keep takes a predicate function as input, and calls the function for +each item of the second input. With compress, the predicate function, if +any, has already been called on all the items of the right input in +parallel, resulting in a vector of Boolean values. This is a typical APL +move; since hyperblocks are equivalent to an implicit map, itā€™s easy to +make the vector of Booleans, because any scalar function, including +predicates, can be applied to a list instead of to a scalar. The reason +both blocks use the / character is that both of them reduce the size of +the input array, although in different ways.

+ +

{width=ā€5.875inā€ +height=ā€2.9944444444444445inā€}The reverse row order, reverse column +order, and transpose blocks form a group: the group of reflections of a +matrix. The APL symbols are all a circle with a line through it; the +lines are the different axes of reflection. So the reverse row order +block reverses which row is where; the reverse column order block +reverses which column is where; and the transpose block turns rows into +columns and vice versa:

+ +

Except for reverse row order, these work only on full arrays, not +ragged-right lists of lists, because the result of the other two would +be an array in which some rows had ā€œholesā€: items 1 and 3 exist, but not +item 2. We donā€™t have a representation for that. (In APL, all arrays are +full, so itā€™s even more restrictive.)

+ +

Higher order functions

+ +

The final category of function is operatorsā€”APL higher order +functions. APL has no explicit map function, because the hyperblock +capability serves much the same need. But APL2 did add an explicit map, +which we might get around to adding to the library next time around. Its +symbol is ĀØ (diaeresis or umlaut).

+ +

The APL equivalent of keep is compress, but itā€™s not a higher order +function. You create a vector of Booleans (0s and 1s, in APL) before +applying the function to the array you want to compress.

+ +

{width=ā€4.258333333333334inā€ +height=ā€0.6131944444444445inā€}But APL does have a higher order version +of combine:

+ +

{width=ā€6.683333333333334inā€ +height=ā€1.0416666666666667inā€}The reduce block works just like combine, +taking a dyadic function and a list. The / version translates each row +to a single value; the āŒæ version translates each column to a single +value. Thatā€™s the only way to think about it from the perspective of +combining individual elements: you are adding up, or whatever the +function is, the numbers in a single row (/) or in a single column +(āŒæ). But APLers think of a matrix as made up of vectors, either row +vectors or column vectors. And if you think of what these blocks do as +adding vectors, rather than adding individual numbers, itā€™s clear that +in

+ +

{width=ā€5.833333333333333inā€ +height=ā€1.1inā€}

+ +

{width=ā€4.808333333333334inā€ +height=ā€1.1inā€}the vector (10, 26, 42) is the sum of column vectors +(1, 5, 9)+(2, 6, 10)+(3, 7, 11)+(4, 8, 12). In pre-6.0 Snap!, weā€™d get +the same result this way:

+ +

mapping over the rows of the matrix, applying combine to each row. +Combining rows, reducing column vectors.
+The outer product block takes two arrays (vectors, typically) and a +dyadic scalar function as inputs. It reports an array whose rank is the +sum of the ranks of the inputs (so, typically a matrix), in which each +item is the result of applying the function to an atomic element of each +array. The third element of the second row of the result is the value +reported by the function with the second element of the left input and +the third element of the right input. (The APL symbol ā—¦. is pronounced +ā€œjot dot.ā€) The way to think about this block is ā€œmultiplication tableā€ +from elementary school:

+ +

{width=ā€7.24inā€ height=ā€1.52inā€}

+ +

{width=ā€2.1666666666666665inā€ +height=ā€0.24166666666666667inā€}

+ +

{width=ā€2.6166666666666667inā€ +height=ā€0.24166666666666667inā€}

+ +

{width=ā€7.338611111111111inā€ +height=ā€1.0069444444444444inā€}The inner product block takes two matrices +and two operations as input. The number of columns in the left matrix +must equal the number of rows in the right matrix. When the two +operations are + and Ɨ, this is the matrix multiplication familiar to +mathematicians:

+ +

But other operations can be used. One common inner product is āˆØ.āˆ§ (ā€œor +dot andā€) applied to Boolean matrices, to find rows and columns that +have corresponding items in common.

+ +

{width=ā€0.9583333333333334inā€ +height=ā€0.18333333333333332inā€}The printable block isnā€™t an APL +function; itā€™s an aid to exploring APL-in-Snap!. It transforms arrays +to a compact representation that still makes the structure clear:

+ +

{width=ā€5.997916666666667inā€ +height=ā€0.3333333333333333inā€}Experts will recognize this as the Lisp +representation of list structure,

+ +

Index

+ +

! block Ā· 32.csv file Ā· 134.json file Ā· 134.txt file Ā· 134# variable Ā· +25#1 Ā· 69+ block Ā· 22Ɨ block Ā· 22ā‰  block Ā· 20ā‰¤ block Ā· 20ā‰„ block Ā· 20āš” +(lightning bolt) Ā· 123Aa new clone of block Ā· 77A Programming Language +Ā· 148Abelson, Hal Ā· 4About option Ā· 107add comment option Ā· 124, 125Add +sceneā€¦ option Ā· 111additive mixing Ā· 144Advanced Placement Computer +Science Principles Ā· 110AGPL Ā· 107all but first blocks Ā· 27all but first +of block Ā· 49all but first of stream block Ā· 26all but last blocks Ā· +27all of block Ā· 28Alonzo Ā· 9, 55anchor Ā· 10anchor (in my block) Ā· +78animate block Ā· 33animation Ā· 12animation library Ā· 33anonymous list Ā· +46Any (unevaluated) type Ā· 72any of block Ā· 28Any type Ā· 60APL Ā· 4, 58, +148APL character set Ā· 149APL library Ā· 35, 148APL2 Ā· 149APL\360 Ā· +148Arduino Ā· 92arithmetic Ā· 11array, dynamic Ā· 49arrow, upward-pointing +Ā· 63arrowheads Ā· 46, 63, 69ask and wait block Ā· 24ask block Ā· 86assoc +block Ā· 25association list Ā· 88associative function Ā· 51at block Ā· +19atan2 block Ā· 20atomic data Ā· 57attribute Ā· 76attributes, list of Ā· +78audio comp library Ā· 34Bbackground blocks Ā· 19Backgroundsā€¦ option Ā· +112backspace key (keyboard editor) Ā· 131Ball, Michael Ā· 4bar chart block +Ā· 28bar charts library Ā· 28base case Ā· 44BIGNUMS block Ā· 32binary tree Ā· +47bitmap Ā· 79, 112bitwise library Ā· 36bjc.edc.org Ā· 137Black Hole +problem Ā· 139block Ā· 6; command Ā· 6; C-shaped Ā· 7; hat Ā· 6; predicate Ā· +12; reporter Ā· 10; sprite-local Ā· 75Block Editor Ā· 41, 42, 59block label +Ā· 102block library Ā· 45, 110block picture option Ā· 124block shapes Ā· 40, +60block variable Ā· 43block with no name Ā· 32blockify option Ā· 134blocks, +color of Ā· 40Boole, George Ā· 12Boolean Ā· 12Boolean (unevaluated) type Ā· +72Boolean constant Ā· 12box of ten crayons Ā· 139box of twenty crayons Ā· +139break command Ā· 99breakpoint Ā· 17, 118Briggs, David Ā· 145broadcast +and wait block Ā· 125broadcast and wait block Ā· 9broadcast block Ā· 21, +23, 73, 125brown dot Ā· 9Build Your Own Blocks Ā· 40Burns, Scott Ā· +145button: pause Ā· 17; recover Ā· 39; visible stepping Ā· 18CC programming +language Ā· 68call block Ā· 65, 68call w/continuation block Ā· 97camera +icon Ā· 126Cancel button Ā· 129carriage return character Ā· 20cascade +blocks Ā· 26case-independent comparisons block Ā· 33cases block Ā· 28catch +block Ā· 26, 99catch errors library Ā· 31catenate block Ā· 152catenate +vertically block Ā· 152center of the stage Ā· 22center x (in my block) Ā· +78center y (in my block) Ā· 78Chandra, Kartik Ā· 4change background block +Ā· 22Change passwordā€¦ option Ā· 113change pen block Ā· 24, 29, 117, +140child class Ā· 87children (in my block) Ā· 78Church, Alonzo Ā· 9class Ā· +85class/instance Ā· 76clean up option Ā· 125clear button Ā· 129clicking on +a script Ā· 122Clicking sound option Ā· 116clone: permanent Ā· 74; +temporary Ā· 74clone of block Ā· 89clones (in my block) Ā· 78cloud (startup +option) Ā· 136Cloud button Ā· 37, 108cloud icon Ā· 113cloud storage Ā· 37CMY +Ā· 138CMYK Ā· 138codification support option Ā· 117color at weight block Ā· +145color block Ā· 140color chart Ā· 147color from block Ā· 29, 140color +nerds Ā· 145color numbers Ā· 29, 138, 139color of blocks Ā· 40color palette +Ā· 128color picker Ā· 143color scales Ā· 141color space Ā· 138color theory Ā· +138Colors and Crayons library Ā· 138colors library Ā· 29columns of block Ā· +57combine block Ā· 50combine block (APL) Ā· 157command block Ā· 6comment +box Ā· 125compile menu option Ā· 123compose block Ā· 26compress block Ā· +156Computer Science Principles Ā· 110cond in Lisp Ā· 28conditional +library: multiple-branch Ā· 28constant functions Ā· 71constructors Ā· +47contained in block Ā· 153context menu Ā· 119context menu for the palette +background Ā· 120context menus for palette blocks Ā· 119continuation Ā· +93continuation passing style Ā· 94Control palette Ā· 7controls in the +Costumes tab Ā· 126controls in the Sounds tab Ā· 130controls on the stage +Ā· 132control-shift-enter (keyboard editor) Ā· 132copy of a list Ā· 50CORS +Ā· 92cors proxies Ā· 92costume Ā· 6, 8costume from text block Ā· 31costume +with background block Ā· 31costumes (in my block) Ā· 78Costumes tab Ā· 9, +126costumes, first class Ā· 79Costumesā€¦ option Ā· 112counter class Ā· +85CPS Ā· 96crayon library Ā· 31crayons Ā· 29, 138, 139create var block Ā· +32create variables library Ā· 32Cross-Origin Resource Sharing Ā· +92crossproduct Ā· 70cs10.org Ā· 137C-shaped block Ā· 7, 67C-shaped slot Ā· +72CSV (comma-separated values) Ā· 54CSV format Ā· 20csv of block Ā· +57current block Ā· 92current date or time Ā· 92current location block Ā· +34current sprite Ā· 122custom block in a script Ā· 124custom? of block +block Ā· 102cyan Ā· 142Ddangling rotation Ā· 10dangling? (in my block) Ā· +78dark candy apple red Ā· 141data hiding Ā· 73data structure Ā· 47data +table Ā· 88data type Ā· 19, 59database library Ā· 34date Ā· 92Dave, Achal Ā· +4deal block Ā· 150debugging Ā· 118Debugging Ā· 17deep copy of a list Ā· +50default value Ā· 63define block Ā· 102define of recursive procedure Ā· +104definition (of block) Ā· 102definition of block Ā· 101delegation Ā· +87Delete a variable Ā· 14delete block definitionā€¦ option Ā· 120delete +option Ā· 124, 128, 133delete var block Ā· 32denim Ā· 139design principle Ā· +46, 77devices Ā· 91, 92dialog, input name Ā· 42dimensions of block Ā· +57Dinsmore, Nathan Ā· 4direction to block Ā· 22Disable click-to-run option +Ā· 117dispatch procedure Ā· 85, 86, 88distance to block Ā· 22dl (startup +option) Ā· 136do in parallel block Ā· 31does var exist block Ā· 32down +arrow (keyboard editor) Ā· 131Download source option Ā· 108drag from +prototype Ā· 43draggable checkbox Ā· 122, 132dragging onto the arrowheads +Ā· 69drop block Ā· 155duplicate block definitionā€¦ option Ā· 120duplicate +option Ā· 124, 128, 132dynamic array Ā· 49Eeasing block Ā· 33easing +function Ā· 33edge color Ā· 129edit option Ā· 128, 133, 135editā€¦ option Ā· +120editMode (startup option) Ā· 137effect block Ā· 19ellipse tool Ā· 128, +129ellipsis Ā· 63else block Ā· 28else if block Ā· 28empty input slots, +filling Ā· 66, 68, 70enter key (keyboard editor) Ā· 131equality of +complete structures Ā· 149eraser tool Ā· 128error block Ā· 31error catching +library Ā· 31escape key (keyboard editor) Ā· 130Examples button Ā· +108Execute on slider change option Ā· 115export block definitionā€¦ +option Ā· 120Export blocksā€¦ option Ā· 110export option Ā· 128, 133Export +projectā€¦ option Ā· 110exportā€¦ option Ā· 134, 136expression Ā· +11Extension blocks option Ā· 115extract option Ā· 124eyedropper tool Ā· +128, 129Ffactorial Ā· 44, 71factorial Ā· 32Fade blocksā€¦ option Ā· 114fair +HSL Ā· 145fair hue Ā· 29, 141, 143, 146fair hue table Ā· 146fair saturation +Ā· 146fair value Ā· 146Falkoff, Adin Ā· 148false block Ā· 19file icon menu Ā· +108fill color Ā· 129Finch Ā· 92find blocksā€¦ option Ā· 120find first Ā· +50first class data Ā· 148first class data type Ā· 46ļ¬rst class procedures +Ā· 65ļ¬rst class sprites Ā· 73first word block Ā· 27flag, green Ā· 6Flat +design option Ā· 116flat line ends option Ā· 117flatten block Ā· 152flatten +of block Ā· 57floodfill tool, Ā· 128focus (keyboard editor) Ā· 131footprint +button Ā· 117for block Ā· 13, 19, 26, 64, 65for each block Ā· 20for each +item block Ā· 25For this sprite only Ā· 15formal parameters Ā· 69frequency +distribution analysis library Ā· 34from color block Ā· 29, 140, +142function, associative Ā· 51function, higher order Ā· 49, 148function, +mixed Ā· 148, 151function, scalar Ā· 55, 148functional programming style Ā· +48
+Ggeneric hat block Ā· 6generic when Ā· 6get blocks option Ā· 128getter Ā· +76getter/setter library Ā· 32glide block Ā· 115global variable Ā· 14, 15go +to block Ā· 22grade down block Ā· 154grade up block Ā· 154graphics effect Ā· +19gray Ā· 139, 141green flag Ā· 6green flag button Ā· 118green halo Ā· +123GuillĆ©n i Pelegay, Joan Ā· 4Hhalo Ā· 11, 123; red Ā· 69hat block Ā· 6, +41; generic Ā· 6helpā€¦ option Ā· 119, 123helpā€¦ option for custom block +Ā· 119hexagonal blocks Ā· 41, 60hexagonal shape Ā· 12hide and show +primitives Ā· 17hide blocks option Ā· 120Hide blocksā€¦ option Ā· 111hide +var block Ā· 32hide variable block Ā· 17hideControls (startup option) Ā· +137higher order function Ā· 49, 70, 148, 157higher order procedure Ā· +66histogram Ā· 34Hotchkiss. Kyle Ā· 4HSL Ā· 138, 143HSL color Ā· 29HSL pen +color model option Ā· 117HSV Ā· 138, 142HTML (HyperText Markup Language) Ā· +91HTTP Ā· 92HTTPS Ā· 92, 126Hudson, Connor Ā· 4hue Ā· 141Huegle, Jadga Ā· +4Hummingbird Ā· 92hyperblocks Ā· 148Hyperblocks Ā· 55Hz for block Ā· 34IIBM +System/360 Ā· 148ice cream Ā· 109icons in title text Ā· 64id block Ā· 71id +option Ā· 22identical to Ā· 20identity function Ā· 71if block Ā· 12if do and +pause all block Ā· 26if else block Ā· 71if else reporter block Ā· 19ignore +block Ā· 26imperative programming style Ā· 48importā€¦ option Ā· +134Importā€¦ option Ā· 110in front of block Ā· 49in front of stream block +Ā· 26index of block (APL) Ā· 152index variable Ā· 19indigo Ā· 141infinite +precision integer library Ā· 32Ingalls, Dan Ā· 4inherit block Ā· +77inheritance Ā· 73, 87inner product block Ā· 158input Ā· 6input list Ā· 68, +69input name Ā· 69input name dialog Ā· 42, 59Input sliders option Ā· +115input-type shapes Ā· 59instance Ā· 85integers block Ā· 152interaction Ā· +15internal variable Ā· 63iota block Ā· 152is _ a _ ? block Ā· 19is flag +block Ā· 20is identical to Ā· 20item 1 of block Ā· 49item 1 of stream block +Ā· 26item block Ā· 148item of block Ā· 56iteration library Ā· 26Iverson, +Kenneth E. Ā· 4, 148Jjaggies Ā· 79Java programming language Ā· 68JavaScript +Ā· 19, 143JavaScript extensions option Ā· 115JavaScript function block Ā· +115jigsaw-piece blocks Ā· 40, 60join block Ā· 102JSON (JavaScript Object +Notation) file Ā· 54JSON format Ā· 20json of block Ā· 57jukebox Ā· 9KKay, +Alan Ā· 4key:value: block Ā· 34keyboard editing button Ā· 123keyboard +editor Ā· 130keyboard shortcuts Ā· 108key-value pair Ā· 88LL*a*b* Ā· +143L*u*v* Ā· 143label, block Ā· 102lambda Ā· 67lang= (startup option) Ā· +137Languageā€¦ option Ā· 114large option Ā· 134last blocks Ā· 27layout, +window Ā· 5Leap Motion Ā· 92left arrow (keyboard editor) Ā· 131Lego NXT Ā· +92length block Ā· 148length of block Ā· 57length of text block Ā· 22letter +(1) of (world) block Ā· 27lexical scope Ā· 85lg option Ā· 22Librariesā€¦ +option Ā· 25, 111library: block Ā· 45license Ā· 107Lieberman, Henry Ā· +77Lifelong Kindergarten Group Ā· 4lightness Ā· 143lightness option Ā· +117lightning bolt symbol Ā· 25, 123line break in block Ā· 64line drawing +tool Ā· 128lines of block Ā· 57linked list Ā· 49Lisp Ā· 58list āž” sentence +block Ā· 27list āž” word block Ā· 27list block Ā· 46list comprehension +library Ā· 35list copy Ā· 50list library Ā· 25list of procedures Ā· 70List +type Ā· 60list view Ā· 51list, linked Ā· 49list, multi-dimensional Ā· +55listify block Ā· 34lists of lists Ā· 47little people Ā· 44, 96loading +saved projects Ā· 38local state Ā· 73local variables Ā· 19location-pin Ā· +15Loginā€¦ option Ā· 113Logo tradition Ā· 27Logout option Ā· 113Long form +input dialog option Ā· 116long input name dialog Ā· 59Mmacros Ā· 105magenta +Ā· 141, 142Make a block Ā· 40Make a block button Ā· 119make a blockā€¦ +option Ā· 126Make a list Ā· 46Make a variable Ā· 14make internal variable +visible Ā· 63Maloney, John Ā· 4map block Ā· 50, 65map library Ā· 35map over +stream block Ā· 26map to code block Ā· 117map-pin symbol Ā· 75maroon Ā· +141Massachusetts Institute of Technology Ā· 4mathematicians Ā· 148matrices +Ā· 148matrix multiplication Ā· 158max block Ā· 20McCarthy, John Ā· 4media +computation Ā· 55, 149Media Lab Ā· 4memory Ā· 16menus library Ā· 36message Ā· +73message passing Ā· 73, 86method Ā· 73, 75, 86methods table Ā· +88microphone Ā· 82microphone block Ā· 82middle option Ā· 127min block Ā· +20mirror sites Ā· 137MIT Artificial Intelligence Lab Ā· 4MIT Media Lab Ā· +4mix block Ā· 140mix colors block Ā· 29mixed function Ā· 148, 151mixing +paints Ā· 144Modrow, Eckart Ā· 121monadic negation operator Ā· 22Morphic Ā· +4Motyashov, Ivan Ā· 4mouse position block Ā· 21move option Ā· 133MQTT +library Ā· 36multiline block Ā· 33multimap block Ā· 25multiple input Ā· +63multiple-branch conditional library Ā· 28multiplication table Ā· +158multiplication, matrix Ā· 158mutation Ā· 48mutators Ā· 47my block Ā· 73, +76my blocks block Ā· 102my categories block Ā· 102Nname (in my block) Ā· +78name box Ā· 122name, input Ā· 69nearest color number Ā· 142neg option Ā· +22negation operator Ā· 22neighbors (in my block) Ā· 78nested calls Ā· +70Nesting Sprites Ā· 10New categoryā€¦ option Ā· 111new costume block Ā· +80new line character Ā· 64New option Ā· 108New scene option Ā· 111new sound +block Ā· 84new sprite button Ā· 8newline character Ā· 20Nintendo Ā· +92noExitWarning (startup option) Ā· 137nonlocal exit Ā· 99normal option Ā· +134normal people Ā· 145noRun (startup option) Ā· 137Number type Ā· +60numbers from block Ā· 20Oobject block Ā· 73Object Logo Ā· 77object +oriented programming Ā· 73, 85Object type Ā· 60objects, building +explicitly Ā· 85of block (operators) Ā· 22of block (sensing) Ā· 24, 106of +costume block Ā· 79open (startup option) Ā· 136Open in Community Site +option Ā· 113Openā€¦ option Ā· 108operator (APL) Ā· 148, 157orange oval Ā· +13other clones (in my block) Ā· 78other sprites (in my block) Ā· 78outer +product block Ā· 158outlined ellipse tool Ā· 128outlined rectangle tool Ā· +128oval blocks Ā· 40, 60Ppaint brush icon Ā· 126Paint Editor Ā· 126Paint +Editor window Ā· 128paintbrush tool Ā· 128paints Ā· 144Paleolithic Ā· +150palette Ā· 6palette area Ā· 119palette background Ā· 120Parallax S2 Ā· +92parallelism Ā· 8, 48parallelization library Ā· 31parent (in my block) Ā· +78parent attribute Ā· 77parent class Ā· 87parentā€¦ option Ā· 136Parsons +problems Ā· 117parts (in my block) Ā· 78parts (of nested sprite) Ā· +10pause all block Ā· 17, 118pause button Ā· 17, 118pen block Ā· 24, 29, +117, 140pen down? block Ā· 19pen trails block Ā· 18pen trails option Ā· +135pen vectors block Ā· 18permanent clone Ā· 74, 136physical devices Ā· +91picā€¦ option Ā· 135, 136picture of script Ā· 124picture with speech +balloon Ā· 124picture, smart Ā· 124pink Ā· 141pivot option Ā· 133pixel Ā· +79pixel, screen Ā· 19pixels library Ā· 27Plain prototype labels option Ā· +116play block Ā· 34play sound block Ā· 9playing sounds Ā· 9plot bar chart +block Ā· 28plot sound block Ā· 34point towards block Ā· 22points as inputs +Ā· 22polymorphism Ā· 75position block Ā· 21, 33Predicate block Ā· +12preloading a project Ā· 136present (startup option) Ā· 136presentation +mode button Ā· 118primitive block within a script Ā· 123printable block Ā· +27, 158procedure Ā· 12, 66Procedure type Ā· 72procedures as data Ā· +9product block Ā· 22, 28project control buttons Ā· 118Project notes option +Ā· 108Prolog Ā· 58prototype Ā· 41prototyping Ā· 76, 88pulldown input Ā· +61pumpkin Ā· 139purple Ā· 142Rrainbow Ā· 141rank Ā· 148rank of block Ā· 57, +151ravel block Ā· 149raw dataā€¦ option Ā· 134ray length block Ā· +22read-only pulldown input Ā· 61receiversā€¦ option Ā· 125recover button Ā· +39rectangle tool Ā· 128recursion Ā· 43recursive call Ā· 68recursive +operator Ā· 71recursive procedure using define Ā· 104red halo Ā· 68, 69, +123redo button Ā· 123redrop option Ā· 125reduce block Ā· 156, 157Reference +manual option Ā· 108reflectance graph Ā· 144relabel option Ā· 20relabelā€¦ +option Ā· 123, 124release option Ā· 136Remove a categoryā€¦ option Ā· +111remove duplicates from block Ā· 25rename option Ā· 128renaming +variables Ā· 15repeat block Ā· 7, 67repeat blocks Ā· 26repeat until +block Ā· 12report block Ā· 44Reporter block Ā· 10reporter if block Ā· +12reporter if else block Ā· 19reporters, recursive Ā· 44Reset Passwordā€¦ +option Ā· 113reshape block Ā· 56, 148, 151Restore unsaved project option Ā· +39result picā€¦ option Ā· 124, 125reverse block Ā· 156reverse columns +block Ā· 156Reynolds, Ian Ā· 4RGB Ā· 138RGBA option Ā· 19right arrow +(keyboard editor) Ā· 131ring, gray Ā· 49, 66, 68ringify Ā· 66ringify option +Ā· 124Roberts, Eric Ā· 44robots Ā· 91, 92rods and cones Ā· 141roll block Ā· +150Romagosa, Bernat Ā· 4rotation buttons Ā· 122rotation point tool Ā· 128, +129rotation x (in my block) Ā· 78rotation y (in my block) Ā· 78run +(startup option) Ā· 136run block Ā· 65, 68run w/continuation Ā· 99Ssafely +try block Ā· 31sample Ā· 82saturation Ā· 143Save asā€¦ option Ā· 110Save +option Ā· 110save your project in the cloud Ā· 37scalar = block Ā· +150scalar function Ā· 55, 148, 150scalar join block Ā· 150scenes Ā· 111, +136Scenesā€¦ option Ā· 111Scheme Ā· 4Scheme number block Ā· 32SciSnap! Ā· +121SciSnap! library Ā· 36scope: lexical Ā· 85Scratch Ā· 5, 9, 40, 46, 47, +48, 59Scratch Team Ā· 4screen pixel Ā· 19script Ā· 5script pic Ā· 43script +picā€¦ option Ā· 124script variables block Ā· 15, 19, 86scripting area +Ā· 6, 122scripting area background context menu Ā· 125scripts picā€¦ +option Ā· 126search bar Ā· 109search button Ā· 119secrets Ā· 107select block +Ā· 156selectors Ā· 47self (in my block) Ā· 78sendersā€¦ option Ā· 125sensors +Ā· 91sentence āž” list block Ā· 27sentence block Ā· 25sentence library Ā· +27sentenceāž”list block Ā· 25separator: menu Ā· 62sepia Ā· 139serial-ports +library Ā· 33Servilla, Deborah Ā· 4set _ of block _ to _ block Ā· 102set +background block Ā· 22set block Ā· 15set flag block Ā· 20, 32set pen +block Ā· 24, 29, 117, 139, 140set pen to crayon block Ā· 30, 139set value +block Ā· 32set var block Ā· 32setter Ā· 76setting block Ā· 32settings icon Ā· +114shade Ā· 141shallow copy of a list Ā· 50shape of block Ā· 151shapes of +blocks Ā· 40shift-arrow keys (keyboard editor) Ā· 131Shift-click (keyboard +editor) Ā· 130shift-click on block Ā· 124shift-clicking Ā· 107shift-enter +(keyboard editor) Ā· 130Shift-tab (keyboard editor) Ā· 130shortcut Ā· 126, +135shortcuts: keyboard Ā· 108show all option Ā· 135Show buttons option Ā· +117Show categories option Ā· 117show option Ā· 136show primitives option Ā· +121show stream block Ā· 26show var block Ā· 32show variable block Ā· +17shown? block Ā· 19shrink/grow button Ā· 118sieve block Ā· 26sign option Ā· +22Signada library Ā· 36signum block Ā· 150Signupā€¦ option Ā· 113simulation +Ā· 73sine wave Ā· 83Single palette option Ā· 117single stepping Ā· 18slider: +stepping speed Ā· 18slider maxā€¦ option Ā· 134slider minā€¦ option Ā· +134slider option Ā· 134Smalltalk Ā· 58smart picture Ā· 124snap block Ā· +27snap option Ā· 22Snap! logo menu Ā· 107Snap! manual Ā· 124Snap! +program Ā· 5Snap! website option Ā· 108snap.berkeley.edu Ā· 108solid +ellipse tool Ā· 128solid rectangle tool Ā· 128sophistication Ā· 72sort +block Ā· 25sound Ā· 82sound manipulation library Ā· 34sounds (in my block) +Ā· 78sounds, first class Ā· 79Soundsā€¦ option Ā· 113source files for +Snap! Ā· 108space key (keyboard editor) Ā· 131speak block Ā· 31special +form Ā· 72spectral colors Ā· 141speech balloon Ā· 124speech synthesis +library Ā· 31split block Ā· 20, 91split by blocks block Ā· 101split by line +block Ā· 57spreadsheet Ā· 149sprite Ā· 6, 73sprite appearance and behavior +controls Ā· 122sprite corral Ā· 8, 135sprite creation buttons Ā· 135sprite +nesting Ā· 10sprite-local block Ā· 75sprite-local variable Ā· 14, 15square +stop sign Ā· 6squiral Ā· 13stack of blocks Ā· 6stage Ā· 6, 73stage (in my +block) Ā· 78stage blocks Ā· 19Stage resizing buttons Ā· 118Stage sizeā€¦ +option Ā· 114Stanford Artificial Intelligence Lab Ā· 4starting Snap! Ā· +136Steele, Guy Ā· 4stop all block Ā· 118stop block Ā· 22stop block block Ā· +44stop button Ā· 118stop script block Ā· 44stop sign Ā· 8stop sign, square +Ā· 6Stream block Ā· 26stream library Ā· 26Stream with numbers from block Ā· +26stretch block Ā· 80string processing library Ā· 33Structure and +Interpretation of Computer Programs Ā· 4submenu Ā· 62substring block Ā· +33subtractive mixing Ā· 144sum block Ā· 22, 28Super-Awesome Sylvia Ā· +92Sussman, Gerald J. Ā· 4Sussman, Julie Ā· 4svgā€¦ option Ā· 135switch in C +Ā· 28symbols in title text Ā· 64synchronous rotation Ā· 10system +getter/setter library Ā· 32Ttab character Ā· 20tab key (keyboard editor) Ā· +130table Ā· 158table view Ā· 51take block Ā· 155teal Ā· 142temporary clone Ā· +74, 133Terms of Service Ā· 38termwise extension Ā· 148text costume library +Ā· 31text input Ā· 9Text type Ā· 60text-based language Ā· 117text-to-speech +library Ā· 31Thinking Recursively Ā· 44thread Ā· 100thread block Ā· +100Thread safe scripts option Ā· 116throw block Ā· 26thumbnail Ā· 122time Ā· +92tint Ā· 141tip option Ā· 127title text Ā· 42to block Ā· 22tool bar Ā· 6tool +bar features Ā· 107touching block Ā· 22transient variable Ā· 16translation +Ā· 114translations option Ā· 43transparency Ā· 30, 79, 140transparent paint +Ā· 129transpose block Ā· 156true block Ā· 19TuneScope library Ā· 36Turbo +mode option Ā· 115turtle costume Ā· 126Turtle costume Ā· 9turtleā€™s rotation +point Ā· 127two-item (x,y) lists Ā· 22type Ā· 19UUndefined! blocks Ā· +120Undelete spritesā€¦ option Ā· 113undo button Ā· 123, 129undrop option Ā· +125unevaluated procedure types Ā· 61unevaluated type Ā· 72Unicode Ā· +149Uniform Resource Locator Ā· 91unringify Ā· 66, 86unringify option Ā· +124Unused blocksā€¦ option Ā· 111up arrow (keyboard editor) Ā· 131upvar Ā· +64upward-pointing arrow Ā· 63url block Ā· 34, 91USE BIGNUMS block Ā· 32use +case-independent comparisons block Ā· 33user interface elements Ā· 107user +name Ā· 37Vvalue Ā· 143value at key block Ā· 34var block Ā· 32variable Ā· 13, +76; block Ā· 43; global Ā· 14; renaming Ā· 15; script-local Ā· 15; +sprite-local Ā· 14, 15; transient Ā· 16variable watcher Ā· 14variable-input +slot Ā· 68variables in ring slots Ā· 66variables library Ā· 32variables, +local Ā· 19variadic Ā· 22variadic input Ā· 46, 63variadic library Ā· +28vector Ā· 112vector editor Ā· 129vectors Ā· 148video block Ā· 22video on +block Ā· 80violet Ā· 142visible stepping Ā· 45, 117visible stepping button +Ā· 18visible stepping option Ā· 115visual representation of a sentence Ā· +27Wwardrobe Ā· 9warp block Ā· 19, 123watcher Ā· 15Water Color Bot Ā· 92web +services library Ā· 34when I am block Ā· 23when I am stopped script Ā· +23when I receive block Ā· 23when, generic Ā· 6white Ā· 142white background +Ā· 141whitespace Ā· 20Wiimote Ā· 92window layout Ā· 5with inputs Ā· 66word āž” +list block Ā· 27word and sentence library Ā· 27world map library Ā· 35World +Wide Web Ā· 91write block Ā· 18writeable pulldown inputs Ā· 61XX position Ā· +11X11/W3C color names Ā· 29Xerox PARC Ā· 4YY position Ā· 11yield block Ā· +100Yuan, Yuan Ā· 4Zzebra coloring Ā· 11Zoom blocks... option Ā· 114

+ +
+
    +
  1. +

    One of the hat blocks, the generic ā€œwhen anythingā€ block , is +subtly different from the others. When the stop sign is clicked, or +when a project or sprite is loaded, this block doesnā€™t test whether +the condition in its hexagonal input slot is true, so the script +beneath it will not run, until some other script in the project +runs (because, for example, you click the green flag). When generic +when blocks are disabled, the stop sign will be square instead of +octagonal.Ā 

    +
  2. +
  3. +

    The hide variable and show variable blocks can also be used to +hide and show primitives in the palette. The pulldown menu doesnā€™t +include primitive blocks, but thereā€™s a generally useful technique +to give a block input values it wasnā€™t expecting using run or +call:{width=ā€3.9375inā€ +height=ā€0.3888888888888889inā€}

    + +

    In order to use a block as an input this way, you must explicitly +put a ring around it, by right-clicking on it and choosing ringify. +More about rings in Chapter VI.Ā 

    +
  4. +
  5. +

    This use of the word ā€œprototypeā€ is unrelated to the prototyping +object oriented programming discussed later.Ā 

    +
  6. +
  7. +

    Note to users of earlier versions: From the beginning, there has +been a tension in our work between the desire to provide tools such +as for (used in this example) and the higher order functions +introduced on the next page as primitives, to be used as easily as +other primitives, and the desire to show how readily such tools can +be implemented in Snap! itself. This is one instance of our +general pedagogic understanding that learners should both use +abstractions and be permitted to see beneath the abstraction +barrier. Until version 5.0, we used the uneasy compromise of a +library of tools written in Snap! and easily, but not easily +enough, loaded into a project. By not loading the tools, users or +teachers could explore how to program them. In 5.0 we made them true +primitives, partly because thatā€™s what some of us wanted all along +and partly because of the increasing importance of fast performance +as we explore ā€œbig dataā€ and media computation. But this is not the +end of the story for us. In a later version, after we get the design +firmed up, we intend to introduce ā€œhybridā€ primitives, implemented +in high speed Javascript but with an ā€œEditā€ option that will open, +not the primitive implementation, but the version written in +Snap!. The trick is to ensure that this can be done without +dramatically slowing usersā€™ projects.Ā 

    +
  8. +
  9. +

    In Scratch, every block that takes a Text-type input has a default +value that makes the rectangles for text wider than tall. The blocks +that arenā€™t specifically about text either are of Number type or +have no default value, so those rectangles are taller than wide. At +ļ¬rst some of us (bh) thought that Text was a separate type that +always had a wide input slot; it turns out that this isnā€™t true in +Scratch (delete the default text and the rectangle narrows), but we +thought it a good idea anyway, so we allow Text-shaped boxes even +for empty input slots. (This is why Text comes just above Any in the +input type selection box.)Ā 

    +
  10. +
  11. +

    There is a primitive id function in the menu of the sqrt of block, +but we think seeing its (very simple) implementation will make this +example easier to understand.Ā 

    +
  12. +
  13. +

    Some languages popular in the ā€œreal worldā€ today, such as +JavaScript, claim to use prototyping, but their object system is +much more complicated than what we are describing (weā€™re guessing +itā€™s because they were designed by people too familiar with +class/instance programming); that has, in some circles, given +prototyping a bad name. Our prototyping design comes from Object +Logo, and before that, from Henry Lieberman. [Lieberman, H., Using +Prototypical Objects to Implement Shared Behavior in Object-Oriented +Systems, First Conference on Object-Oriented Programming Languages, +Systems, and Applications [OOPSLA-86], ACM SigCHI, Portland, OR, +September, 1986. Also in Object-Oriented Computing, Gerald +Peterson, Ed., IEEE Computer Society Press, 1987.]Ā 

    +
  14. +
  15. +

    Neighbors are all other sprites whose bounding boxes intersect +the doubled dimensions of the requesting sprite's bounds.Ā 

    +
  16. +
+
+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/71/0907dceb30385b3e063ece9c8f35fafea293a026f9ea08317572606fb0a87a b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/71/0907dceb30385b3e063ece9c8f35fafea293a026f9ea08317572606fb0a87a new file mode 100644 index 0000000..f733712 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/71/0907dceb30385b3e063ece9c8f35fafea293a026f9ea08317572606fb0a87a @@ -0,0 +1,2 @@ +I"

First Class Lists

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/7e/5842207401323dd2d96ba6744cbac051a68116ea5c19e8a82cf5c22232e386 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/7e/5842207401323dd2d96ba6744cbac051a68116ea5c19e8a82cf5c22232e386 new file mode 100644 index 0000000..7c5c2bf --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/7e/5842207401323dd2d96ba6744cbac051a68116ea5c19e8a82cf5c22232e386 @@ -0,0 +1,2 @@ +I"%

Appendix B. APL Features

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/89/5392f18b81f851903581f910efe40e4751e30d31dd6ae3fb9cf6a2a77ed5c1 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/89/5392f18b81f851903581f910efe40e4751e30d31dd6ae3fb9cf6a2a77ed5c1 new file mode 100644 index 0000000..eca162e --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/89/5392f18b81f851903581f910efe40e4751e30d31dd6ae3fb9cf6a2a77ed5c1 @@ -0,0 +1,2 @@ +I"5

Object Oriented Programming with Sprites

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/93/66531cad248164c6a36166ec0a0db0baa16c560a03af8e5d4bdd1a9c10ffc6 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/93/66531cad248164c6a36166ec0a0db0baa16c560a03af8e5d4bdd1a9c10ffc6 new file mode 100644 index 0000000..3d8eb58 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/93/66531cad248164c6a36166ec0a0db0baa16c560a03af8e5d4bdd1a9c10ffc6 @@ -0,0 +1,2 @@ +I"

The Outside World

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/96/0785eded3775fe4e5a844b63e0da2dcc74ddc80ccb4b78a117647e32c0ee80 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/96/0785eded3775fe4e5a844b63e0da2dcc74ddc80ccb4b78a117647e32c0ee80 new file mode 100644 index 0000000..d3c64dc --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/96/0785eded3775fe4e5a844b63e0da2dcc74ddc80ccb4b78a117647e32c0ee80 @@ -0,0 +1,8265 @@ +I"d«
+

title: Reference Manual +layout: home +has_children: true +has_toc: true +nav_order: 4 +ā€”

+ +

{width=ā€96pxā€ +height=ā€53pxā€}

+ +

Build Your Own Blocks

+ +

{#section .TOCHeading}

+ +

{width=ā€526pxā€ height=ā€432pxā€} Table of Contents {#table-of-contents .TOCHeading}

+ +

I. Blocks, Scripts, and Sprites 5

+ +

Hat Blocks and Command Blocks 6

+ +

A. Sprites and Parallelism 8

+ +

Costumes and Sounds 8

+ +

Inter-Sprite Communication with Broadcast 9

+ +

B. Nesting Sprites: Anchors and Parts 10

+ +

C. Reporter Blocks and Expressions 10

+ +

D. Predicates and Conditional Evaluation 12

+ +

E. Variables 13

+ +

Global Variables 14

+ +

Script Variables 15

+ +

Renaming variables 15

+ +

Transient variables 16

+ +

F. Debugging 17

+ +

The pause button 17

+ +

Breakpoints: the pause all block 17

+ +

Visible stepping 18

+ +

G. Etcetera 18

+ +

H. Libraries 25

+ +

II. Saving and Loading Projects and Media 37

+ +

A. Local Storage 37

+ +

B. Creating a Cloud Account 37

+ +

C. Saving to the Cloud 38

+ +

D. Loading Saved Projects 38

+ +

E. If you lose your project, do this first! 39

+ +

F. Private and Public Projects 39

+ +

III. Building a Block 40

+ +

A. Simple Blocks 40

+ +

Custom Blocks with Inputs 42

+ +

Editing Block Properties 43

+ +

B. Recursion 43

+ +

C. Block Libraries 44

+ +

D. Custom blocks and Visible Stepping 45

+ +

IV. First class lists 46

+ +

A. The list Block 46

+ +

B. Lists of Lists 47

+ +

C. Functional and Imperative List Programming 48

+ +

D. Higher Order List Operations and Rings 49

+ +

E. Table View vs. List View 51

+ +

Comma-Separated Values 54

+ +

Multi-dimensional lists and JSON 54

+ +

F. Hyperblocks 55

+ +

V. Typed Inputs 59

+ +

A. Scratchā€™s Type Notation 59

+ +

B. The Snap! Input Type Dialog 59

+ +

Procedure Types 60

+ +

Pulldown inputs 61

+ +

Input variants 63

+ +

Prototype Hints 64

+ +

Title Text and Symbols 64

+ +

VI. Procedures as Data 65

+ +

A. Call and Run 65

+ +

Call/Run with inputs 65

+ +

Variables in Ring Slots 66

+ +

B. Writing Higher Order Procedures 66

+ +

Recursive Calls to Multiple-Input Blocks 68

+ +

C. Formal Parameters 69

+ +

D. Procedures as Data 70

+ +

E. Special Forms 71

+ +

Special Forms in Scratch 72

+ +

VII. Object Oriented Programming with Sprites 73

+ +

A. First Class Sprites 73

+ +

B. Permanent and Temporary Clones 74

+ +

C. Sending Messages to Sprites 74

+ +

Polymorphism 75

+ +

D. Local State in Sprites: Variables and Attributes 76

+ +

E. Prototyping: Parents and Children 76

+ +

F. Inheritance by Delegation 77

+ +

G. List of attributes 78

+ +

H. First Class Costumes and Sounds 79

+ +

Media Computation with Costumes 79

+ +

Media Computation with Sounds 82

+ +

VIII. OOP with Procedures 85

+ +

A. Local State with Script Variables 85

+ +

B. Messages and Dispatch Procedures 86

+ +

C. Inheritance via Delegation 87

+ +

D. An Implementation of Prototyping OOP 88

+ +

IX. The Outside World 91

+ +

A. The World Wide Web 91

+ +

B. Hardware Devices 92

+ +

C. Date and Time 92

+ +

X. Continuations 93

+ +

A. Continuation Passing Style 94

+ +

B. Call/Run w/Continuation 97

+ +

Nonlocal exit 99

+ +

XI. Metaprogramming 101

+ +

A. Reading a block 101

+ +

B. Writing a block 102

+ +

C. Macros 105

+ +

XII. User Interface Elements 107

+ +

A. Tool Bar Features 107

+ +

The Snap! Logo Menu 107

+ +

The File Menu 108

+ +

The Cloud Menu 113

+ +

The Settings Menu 114

+ +

Visible Stepping Controls 117

+ +

Stage Resizing Buttons 118

+ +

Project Control Buttons 118

+ +

B. The Palette Area 119

+ +

Buttons in the Palette 119

+ +

Context Menus for Palette Blocks 119

+ +

Context Menu for the Palette Background 120

+ +

C. The Scripting Area 122

+ +

Sprite Appearance and Behavior Controls 122

+ +

Scripting Area Tabs 122

+ +

Scripts and Blocks Within Scripts 122

+ +

Controls in the Costumes Tab 126

+ +

The Paint Editor 128

+ +

Controls in the Sounds Tab 130

+ +

D. Keyboard Editing 130

+ +

Starting and stopping the keyboard editor 130

+ +

Navigating in the keyboard editor 130

+ +

Editing a script 131

+ +

Running the selected script 132

+ +

E. Controls on the Stage 132

+ +

Sprites 132

+ +

Variable watchers 134

+ +

The stage itself 135

+ +

F. The Sprite Corral and Sprite Creation Buttons 135

+ +

G. Preloading a Project when Starting Snap! 136

+ +

H. Mirror Sites 137

+ +

Appendix A. Snap! color library 138

+ +

Introduction to Color 138

+ +

Crayons and Color Numbers 139

+ +

Perceptual Spaces: HSV and HSL 142

+ +

Mixing Colors 144

+ +

tl;dr 145

+ +

Subappendix: Geeky details on fair hue 145

+ +

Subappendix: Geeky details on color numbers 146

+ +

Appendix B. APL features 148

+ +

Boolean values 150

+ +

Scalar functions 150

+ +

Mixed functions 151

+ +

Higher order functions 157

+ +

Index ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦. 159

+ +

Copyright Ā© 2020 Jens Mƶnig and Brian Harvey.

+ +

Macintosh
+HD:Users:bh:Desktop:cc.png{width=ā€59pxā€ +height=ā€21pxā€} This work is licensed under a Creative +Commons Attribution-NonCommercial-ShareAlike 4.0 International +License.

+ +

Acknowledgements {#acknowledgements .TOCHeading}

+ +

[W]{.smallcaps}e have been extremely lucky in our mentors. Jens cut +his teeth in the company of the Smalltalk pioneers: Alan Kay, Dan +Ingalls, and the rest of the gang who invented personal computing and +object oriented programming in the great days of Xerox PARC. He worked +with John Maloney, of the MIT Scratch Team, who developed the Morphic +graphics framework thatā€™s still at the heart of Snap!.

+ +

The brilliant design of Scratch, from the Lifelong Kindergarten Group +at the MIT Media Lab, is crucial to Snap!. Our earlier version, BYOB, +was a direct modification of the Scratch source code. Snap! is a +complete rewrite, but its code structure and its user interface remain +deeply indebted to Scratch. And the Scratch Team, who could have seen us +as rivals, have been entirely supportive and welcoming to us.

+ +

Brian grew up at the MIT and Stanford Artificial Intelligence Labs, +learning from Lisp inventor John McCarthy, Scheme inventors Gerald J. +Sussman and Guy Steele, and the authors of the worldā€™s best computer +science book, Structure and Interpretation of Computer Programs, Hal +Abelson and Gerald J. Sussman with Julie Sussman, among many other +heroes of computer science. (Brian was also lucky enough, while in high +school, to meet Kenneth Iverson, the inventor of APL.)

+ +

In the glory days of the MIT Logo Lab, we used to say, ā€œLogo is Lisp +disguised as BASIC.ā€ Now, with its first class procedures, lexical +scope, and first class continuations, Snap! is Scheme disguised as +Scratch.

+ +

Four people have made such massive contributions to the implementation +of Snap! that we have officially declared them members of the team: +Michael Ball and Bernat Romagosa, in addition to contributions +throughout the project, have primary responsibility for the web site and +cloud storage. Joan GuillĆ©n i Pelegay has contributed very careful and +wise analysis of outstanding issues, including help in taming the +management of translations to non-English languages. Jadga HĆ¼gle, has +energetically contributed to online mini-courses about Snap! and +leading workshops for kids and for adults. Jens, Jadga, and Bernat are +paid to work on Snap! by SAP, which also supports our computing needs.

+ +

We have been fortunate to get to know an amazing group of brilliant +middle school(!) and high school students through the Scratch Advanced +Topics forum, several of whom (since grown up) have contributed code to +Snap!: Kartik Chandra, Nathan Dinsmore, Connor Hudson, Ian Reynolds, +and Deborah Servilla. Many more have contributed ideas and alpha-testing +bug reports. UC Berkeley students whoā€™ve contributed code include Achal +Dave. Kyle Hotchkiss, Ivan Motyashov, and Yuan Yuan. Contributors of +translations are too numerous to list here, but theyā€™re in the +ā€œAboutā€¦ā€ box in Snap! itself.

+ +

This material is based upon work supported in part by the National +Science Foundation under Grants No[.]{.smallcaps} 1138596, 1143566, and +1441075; and in part by MioSoft, Arduino.org, SAP, and YC Research. Any +opinions, findings, and conclusions or recommendations expressed in this +material are those of the author(s) and do not necessarily reflect the +views of the National Science Foundation or other funders.

+ +

[
+]{.smallcaps}[Snap! Reference Manual]{.underline}

+ +

Version 8.0

+ +

Snap! (formerly BYOB) is an extended reimplementation of Scratch +([http://scratch.mit.edu]{.underline}) that allows you to Build Your Own +Blocks. It also features ļ¬rst class lists, ļ¬rst class procedures, first +class sprites, first class costumes, first class sounds, and first class +continuations. These added capabilities make it suitable for a serious +introduction to computer science for high school or college students.

+ +

In this manual we sometimes make reference to Scratch, e.g., to explain +how some Snap! feature extends something familiar in Scratch. Itā€™s +very helpful to have some experience with Scratch before reading this +manual, but not essential.

+ +

To run Snap![,]{.smallcaps} open a browser window and connect to +http://snap.berkeley.edu/run. The Snap! community web site at +http://snap.berkeley.edu is not part of this manualā€™s scope.

+ +

Blocks, Scripts, and Sprites

+ +

This chapter describes the Snap! features inherited from Scratch; +experienced Scratch users can skip to SectionĀ B.

+ +

Snap! is a programming languageā€”a notation in which you can tell a +computer what you want it to do. Unlike most programming languages, +though, Snap! is a visual language; instead of writing a program +using the keyboard, the Snap! programmer uses the same drag-and-drop +interface familiar to computer users.

+ +

{width=ā€415pxā€ +height=ā€258pxā€}Start Snap![.]{.smallcaps} You should see +the following arrangement of regions in the window:

+ +

(The proportions of these areas may be different, depending on the size +and shape of your browser window.)

+ +

{width=ā€142pxā€ +height=ā€130pxā€}A Snap! program consists of one or more +scripts, each of which is made of blocks. Hereā€™s a typical script:

+ +

{width=ā€216pxā€ +height=ā€141pxā€}{width=ā€212pxā€ +height=ā€109pxā€}The five blocks that make up this script +have three different colors, corresponding to three of the eight +palettes in which blocks can be found. The palette area at the left +edge of the window shows one palette at a time, chosen with the eight +buttons just above the palette area. In this script, the gold blocks are +from the Control palette; the green block is from the Pen palette; and +the blue blocks are from the Motion palette. A script is assembled by +dragging blocks from a palette into the scripting area in the middle +part of the window. Blocks snap together (hence the name Snap! for the +language) when you drag a block so that its indentation is near the tab +of the one above it:

+ +

The white horizontal line is a signal that if you let go of the green +block it will snap into the tab of the gold one.

+ +

Hat Blocks and Command Blocks {#hat-blocks-and-command-blocks .ListParagraph}

+ +

At the top of the script is a hat block, which indicates when the +script should be carried out. Hat block names typically start with the +word ā€œwhenā€; in the square-drawing example on page 5, the script should +be run when the green flag near the right end of the Snap! tool bar is +clicked. (The Snap! tool bar is part of the Snap! window, not the +same as the browserā€™s or operating systemā€™s menu bar.) A script isnā€™t +required to have a hat block, but if not, then the script will be run +only if the user clicks on the script itself. A script canā€™t have more +than one hat block, and the hat block can be used only at the top of the +script; its distinctive shape is meant to remind you of that.1

+ +

{width=ā€112pxā€ +height=ā€24pxā€}The other blocks in our example script are command +blocks. Each command block corresponds to an action that Snap! already +knows how to carry out. For example, the block tells the sprite (the +arrowhead shape on the stage at the right end of the window) to move +ten steps (a step is a very small unit of distance) in the direction in +which the arrowhead is pointing. Weā€™ll see shortly that there can be +more than one sprite, and that each sprite has its own scripts. Also, a +sprite doesnā€™t have to look like an arrowhead, but can have any picture +as a costume. The shape of the move block is meant to remind you of a +Legoā„¢ brick; a script is a stack of blocks. (The word ā€œblockā€ denotes +both the graphical shape on the screen and the procedure, the action, +that the block carries out.)

+ +

{width=ā€105pxā€ +height=ā€34pxā€}The number 10 in the move block above is +called an input to the block. By clicking on the white oval, you can +type any number in place of the 10. The sample script on the previous +page uses 100 as the input value. Weā€™ll see later that inputs can have +non-oval shapes that accept values other than numbers. Weā€™ll also see +that you can compute input values, instead of typing a particular value +into the oval. A block can have more than one input slot. For example, +the glide block located about halfway down the Motion palette has three +inputs.

+ +

Most command blocks have that brick shape, but some, like the repeat +block in the sample script, are Cā€‘shaped. Most C-shaped blocks are +found in the Control palette. The slot inside the C shape is a special +kind of input slot that accepts a script as the input.

+ +

{width=ā€142pxā€ +height=ā€130pxā€}

+ +

{width=ā€135pxā€ +height=ā€47pxā€}In the sample script

+ +

{width=ā€547pxā€ +height=ā€139pxā€}C-shaped blocks can be put in a script in +two ways. If you see a white line and let go, the block will be inserted +into the script like any command block:

+ +

{width=ā€528pxā€ +height=ā€123pxā€}But if you see an orange halo and let go, +the block will wrap around the haloed blocks:

+ +

{width=ā€557pxā€ +height=ā€124pxā€}The halo will always extend from the +cursor position to the bottom of the script:

+ +

If you want only some of those blocks, after wrapping you can grab the +first block you donā€™t want wrapped, pull it down, and snap it under the +C-shaped block.

+ +

{width=ā€222pxā€ +height=ā€131pxā€}For ā€œE-shapedā€ blocks with more than one +C-shaped slot, only the first slot will wrap around existing blocks in a +script, and only if that C-shaped slot is empty before wrapping. (You +can fill the other slots by dragging blocks into the desired slot.)

+ +

{width=ā€33pxā€ height=ā€23pxā€}Sprites and Parallelism

+ +

Just below the stage is the ā€œnew spriteā€ button . Click the button to +add a new sprite to the stage. The new sprite will appear in a random +position on the stage, with a random color, but always facing to the +right.

+ +

Each sprite has its own scripts. To see the scripts for a particular +sprite in the scripting area, click on the picture of that sprite in the +sprite corral in the bottom right corner of the window. Try putting +one of the following scripts in each spriteā€™s scripting area:

+ +
+

{width=ā€149pxā€ +height=ā€95pxā€} +{width=ā€148pxā€ +height=ā€112pxā€}

+
+ +

When you click the green flag, you should see one sprite rotate while +the other moves back and forth. This experiment illustrates the way +different scripts can run in parallel. The turning and the moving happen +together. Parallelism can be seen with multiple scripts of a single +sprite also. Try this example:

+ +
+

{width=ā€166pxā€ +height=ā€84pxā€} +{width=ā€166pxā€ +height=ā€86pxā€}

+
+ +

When you press the space key, the sprite should move forever in a +circle, because the move and turn blocks are run in parallel. (To stop +the program, click the red stop sign at the right end of the tool bar.)

+ +

Costumes and Sounds

+ +

{width=ā€31pxā€ +height=ā€21pxā€}{width=ā€170pxā€ +height=ā€180pxā€}{width=ā€28pxā€ +height=ā€16pxā€}To change the appearance of a sprite, +paint or import a new costume for it. To paint a costume, click on the +Costumes tab above the scripting area, and click the paint button . The +Paint Editor that appears is explained on page 128. There are three +ways to import a costume. First select the desired sprite in the sprite +corral. Then, one way is to click on the file icon in the tool bar , +then choose the ā€œCostumesā€¦ā€œmenu item. You will see a list of costumes +from the public media library, and can choose one. The second way, for a +costume stored on your own computer, is to click on the file icon and +choose the ā€œImportā€¦ā€ menu item. You can then select a file in any +picture format (PNG, JPEG, etc.) supported by your browser. The third +way is quicker if the file you want is visible on the desktop: Just drag +the file onto the Snap! window. In any of these cases, the scripting +area will be replaced by something like this:

+ +

Just above this part of the window is a set of three tabs: Scripts, +Costumes, and Sounds. Youā€™ll see that the Costumes tab is now selected. +In this view, the spriteā€™s wardrobe, you can choose whether the sprite +should wear its Turtle costume or its Alonzo costume. (Alonzo, the +Snap! mascot, is named after Alonzo Church, a mathematician who +invented the idea of procedures as data, the most important way in which +Snap! is different from Scratch.) You can give a sprite as many +costumes as you like, and then choose which it will wear either by +clicking in its wardrobe or by using the or block in a script. (Every +costume has a number as well as a name. The next costume block selects +the next costume by number; after the highest-numbered costume it +switches to costume 1. The Turtle, costume 0, is never chosen by next +costume.) The Turtle costume is the only one that changes color to match +a change in the spriteā€™s pen color. Protip: switches to the previous +costume, wrapping like next costume.

+ +

{width=ā€173pxā€ +height=ā€27pxā€}{width=ā€283pxā€ +height=ā€25pxā€}{width=ā€182pxā€ +height=ā€25pxā€}{width=ā€119pxā€ +height=ā€25pxā€}In addition to its costumes, a sprite can +have sounds; the equivalent for sounds of the spriteā€™s wardrobe is +called its jukebox. Sound files can be imported in any format (WAV, +OGG, MP3, etc.) supported by your browser. Two blocks accomplish the +task of playing sounds. If you would like a script to continue running +while the sound is playing, use the block . In contrast, you can use the +block to wait for the sound's completion before continuing the rest of +the script.

+ +

Inter-Sprite Communication with Broadcast

+ +

Earlier we saw an example of two sprites moving at the same time. In a +more interesting program, though, the sprites on stage will interact +to tell a story, play a game, etc. Often one sprite will have to tell +another sprite to run a script. Hereā€™s a simple example:

+ +

{width=ā€165pxā€ +height=ā€24pxā€}{width=ā€55pxā€ +height=ā€107pxā€} +{width=ā€267pxā€ +height=ā€145pxā€} +{width=ā€119pxā€ +height=ā€83pxā€} +{width=ā€146pxā€ +height=ā€58pxā€}

+ +

{width=ā€172pxā€ +height=ā€19pxā€}{width=ā€173pxā€ +height=ā€18pxā€}In the block, the word ā€œbarkā€ is just an +arbitrary name I made up. When you click on the downward arrowhead in +that input slot, one of the choices (the only choice, the first time) is +ā€œnew,ā€ which then prompts you to enter a name for the new broadcast. +When this block is run, the chosen message is sent to every sprite, +which is why the block is called ā€œbroadcast.ā€ (But if you click the +right arrow after the message name, the block becomes , and you can +change it to Ā to send the message just to one sprite.) In this program, +though, only one sprite has a script to run when that broadcast is sent, +namely the dog. Because the boyā€™s script uses broadcast and wait rather +than just broadcast, the boy doesnā€™t go on to his next say block until +the dogā€™s script finishes. Thatā€™s why the two sprites take turns +talking, instead of both talking at once. In Chapter VII, +ā€œObject-Oriented Programming with Sprites,ā€ youā€™ll see a more flexible +way to send a message to a specific sprite using the tell and ask +blocks.

+ +

Notice, by the way, that the say blockā€™s first input slot is rectangular +rather than oval. This means the input can be any text string, not only +a number. In text input slots, a space character is shown as a brown +dot, so that you can count the number of spaces between words, and in +particular you can tell the difference between an empty slot and one +containing spaces. The brown dots are not shown on the stage if the +text is displayed.

+ +

The stage has its own scripting area. It can be selected by clicking on +the Stage icon at the left of the sprite corral. Unlike a sprite, +though, the stage canā€™t move. Instead of costumes, it has backgrounds: +pictures that fill the entire stage area. The sprites appear in front of +the current background. In a complicated project, itā€™s often convenient +to use a script in the stageā€™s scripting area as the overall director of +the action.

+ +

Nesting Sprites: Anchors and Parts

+ +

Sometimes itā€™s desirable to make a sort of ā€œsuper-spriteā€ composed of +pieces that can move together but can also be separately articulated. +The classic example is a personā€™s body made up of a torso, limbs, and a +head. Snap! allows one sprite to be designated as the anchor of the +combined shape, with other sprites as its parts. To set up sprite +nesting, drag the sprite corral icon of a part sprite onto the stage +display (not the sprite corral icon!) of the desired anchor sprite. +The precise place where you let go of the mouse button will be the +attachment point of the part on the anchor.

+ +

{width=ā€157pxā€ +height=ā€93pxā€}Sprite nesting is shown in the sprite +corral icons of both anchors and parts:

+ +

{width=ā€468pxā€ +height=ā€91pxā€}{width=ā€139pxā€ +height=ā€150pxā€}{width=ā€519pxā€ +height=ā€80pxā€}In this illustration, it is desired to +animate Alonzoā€™s arm. (The arm has been colored green in this picture to +make the relationship of the two sprites clearer, but in a real project +theyā€™d be the same color, probably.) Sprite, representing Alonzoā€™s body, +is the anchor; Sprite(2) is the arm. The icon for the anchor shows small +images of up to three attached parts at the bottom. The icon for each +part shows a small image of the anchor in its top left corner, and a +synchronous/dangling rotation flag in the top right corner. In its +initial, synchronous setting, as shown above, it means that the when the +anchor sprite rotates, the part sprite also rotates as well as revolving +around the anchor. When clicked, it changes from a circular arrow to a +straight arrow, and indicates that when the anchor sprite rotates, the +part sprite revolves around it, but does not rotate, keeping its +original orientation. (The part can also be rotated separately, using +its turn blocks.) Any change in the position or size of the anchor is +always extended to its parts. Also, cloning the anchor (see Section VII. +B) will also clone all its parts.

+ +

Top: turning the part: the green arm. Bottom: turning the anchor, with +the arm synchronous (left) and dangling (right).

+ +

Reporter Blocks and Expressions

+ +

{width=ā€141pxā€ +height=ā€50pxā€}{width=ā€70pxā€ +height=ā€15pxā€}So far, weā€™ve used two kinds of blocks: hat blocks +and command blocks. Another kind is the reporter block, which has an +oval shape: . Itā€™s called a ā€œreporterā€ because when itā€™s run, instead of +carrying out an action, it reports a value that can be used as an input +to another block. If you drag a reporter into the scripting area by +itself and click on it, the value it reports will appear in a speech +balloon next to the block:

+ +

{width=ā€510pxā€ +height=ā€92pxā€}When you drag a reporter block over +another blockā€™s input slot, a white ā€œhaloā€ appears around that input +slot, analogous to the white line that appears when snapping command +blocks together:

+ +

{width=ā€203pxā€ +height=ā€59pxā€}Donā€™t drop the input over a red halo:

+ +

Thatā€™s used for a purpose explained on page 68.

+ +

Hereā€™s a simple script that uses a reporter block:

+ +

{width=ā€511pxā€ +height=ā€131pxā€}Here the x position reporter provides the +first input to the say block. (The spriteā€™s X position is its horizontal +position, how far left (negative values) or right (positive values) it +is compared to the center of the stage. Similarly, the Y position is +measured vertically, in steps above (positive) or below (negative) the +center.)

+ +

You can do arithmetic using reporters in the Operators palette:

+ +

{width=ā€601pxā€ +height=ā€139pxā€}The round block rounds 35.3905ā€¦ to 35, +and the + block adds 100 to that. (By the way, the round block is in the +Operators palette, just like +, but in this script itā€™s a lighter color +with black lettering because Snap! alternates light and dark versions +of the palette colors when a block is nested inside another block from +the same palette:

+ +

{width=ā€466pxā€ +height=ā€183pxā€}

+ +

{width=ā€184pxā€ +height=ā€23pxā€}This aid to readability is called zebra +coloring.) A reporter block with its inputs, maybe including other +reporter blocks, such as , is called an expression.

+ +

Predicates and Conditional Evaluation

+ +

{width=ā€64pxā€ +height=ā€18pxā€}{width=ā€116pxā€ +height=ā€18pxā€}Most reporters report either a number, like , or a +text string, like . A predicate is a special kind of reporter that +always reports true or false. Predicates have a hexagonal shape:

+ +

{width=ā€187pxā€ +height=ā€25pxā€}{width=ā€103pxā€ +height=ā€15pxā€}The special shape is a reminder that predicates donā€™t +generally make sense in an input slot of blocks that are expecting a +number or text. You wouldnā€™t say , although (as you can see from the +picture) Snap! lets you do it if you really want. Instead, you +normally use predicates in special hexagonal input slots like this one:

+ +

{width=ā€64pxā€ +height=ā€55pxā€}The C-shaped if block runs its input +script if (and only if) the expression in its hexagonal input reports +true.

+ +

{width=ā€153pxā€ +height=ā€59pxā€}A really useful block in animations runs +its input script repeatedly until a predicate is satisfied:

+ +

{width=ā€219pxā€ +height=ā€141pxā€}{width=ā€220pxā€ +height=ā€81pxā€}If, while working on a project, you want to omit +temporarily some commands in a script, but you donā€™t want to forget +where they belong, you can say

+ +

Sometimes you want to take the same action whether some condition is +true or false, but with a different input value. For this purpose you +can use the reporter if block:

+ +

{width=ā€404pxā€ +height=ā€37pxā€}The technical term for a true or false +value is a ā€œBooleanā€ value; it has a capital B because itā€™s named after +a person, George Boole, who developed the mathematical theory of Boolean +values. Donā€™t get confused; a hexagonal block is a predicate, but the +value it reports is a Boolean.

+ +

Another quibble about vocabulary: Many programming languages reserve the +name ā€œprocedureā€ for Commands (that carry out an action) and use the +name ā€œfunctionā€ for Reporters and Predicates. In this manual, a +procedure is any computational capability, including those that report +values and those that donā€™t. Commands, Reporters, and Predicates are all +procedures. The words ā€œa Procedure typeā€ are shorthand for ā€œCommand +type, Reporter type, or Predicate type.ā€

+ +

{width=ā€132pxā€ +height=ā€23pxā€}{width=ā€132pxā€ +height=ā€23pxā€}If you want to put a constant Boolean +value in a hexagonal slot instead of a predicate-based expression, hover +the mouse over the block and click on the control that appears:

+ +

Variables

+ +

{width=ā€152pxā€ +height=ā€136pxā€}Try this script:

+ +

{width=ā€181pxā€ +height=ā€138pxā€}The input to the move block is an orange oval. To get +it there, drag the orange oval thatā€™s part of the for block:

+ +

The orange oval is a variable: a symbol that represents a value. (I +took this screenshot before changing the second number input to the for +block from the default 10 to 200, and before dragging in a turn block.) +For runs its script input repeatedly, just like repeat, but before each +repetition it sets the variable i to a number starting with its first +numeric input, adding 1 for each repetition, until it reaches the second +numeric input. In this case, there will be 200 repetitions, first with +i=1, then with i=2, then 3, and so on until i=200 for the final +repetition. The result is that each move draws a longer and longer line +segment, and thatā€™s why the picture you see is a kind of spiral. (If you +try again with a turn of 90 degrees instead of 92, youā€™ll see why this +picture is called a ā€œsquiral.ā€)

+ +

{width=ā€306pxā€ +height=ā€144pxā€}The variable i is created by the for block, and it can +only be used in the script inside the blockā€™s C-slot. (By the way, if +you donā€™t like the name i, you can change it by clicking on the orange +oval without dragging it, which will pop up a dialog window in which you +can enter a different name:

+ +

ā€œIā€ isnā€™t a very descriptive name; you might prefer ā€œlengthā€ to indicate +its purpose in the script. ā€œIā€ is traditional because mathematicians +tend to use letters between i and n to represent integer values, but in +programming languages we donā€™t have to restrict ourselves to +single-letter variable names.)

+ +

Global Variables

+ +

You can create variables ā€œby handā€ that arenā€™t limited to being used +within a single block. At the top of the Variables palette, click the +ā€œMake a variableā€ button:

+ +

{width=ā€306pxā€ +height=ā€177pxā€}{width=ā€197pxā€ +height=ā€218pxā€}This will bring up a dialog window in +which you can give your variable a name:

+ +

The dialog also gives you a choice to make the variable available to all +sprites (which is almost always what you want) or to make it visible +only in the current sprite. Youā€™d do that if youā€™re going to give +several sprites individual variables with the same name, so that you +can share a script between sprites (by dragging it from the current +spriteā€™s scripting area to the picture of another sprite in the sprite +corral), and the different sprites will do slightly different things +when running that script because each has a different value for that +variable name.

+ +

{width=ā€159pxā€ +height=ā€220pxā€}If you give your variable the name ā€œnameā€ +then the Variables palette will look like this:

+ +

{width=ā€100pxā€ +height=ā€39pxā€}Thereā€™s now a ā€œDelete a variableā€ button, and thereā€™s +an orange oval with the variable name in it, just like the orange oval +in the for block. You can drag the variable into any script in the +scripting area. Next to the oval is a checkbox, initially checked. When +itā€™s checked, youā€™ll also see a variable watcher on the stage:

+ +

When you give the variable a value, the orange box in its watcher will +display the value.

+ +

{width=ā€185pxā€ +height=ā€46pxā€}How do you give it a value? You use the +set block:

+ +

Note that you donā€™t drag the variableā€™s oval into the set block! You +click on the downarrow in the first input slot, and you get a menu of +all the available variable names.

+ +

If you do choose ā€œFor this sprite onlyā€ when creating a variable, its +block in the palette looks like this:

+ +

Macintosh
+HD:Users:bh:Desktop:local-var.png{width=ā€63pxā€ +height=ā€14pxā€} The location-pin icon is a bit of a +pun on a sprite-local variable. Itā€™s shown only in the palette.

+ +

Script Variables

+ +

{width=ā€528pxā€ +height=ā€222pxā€}In the name example above, our project is going to +carry on an interaction with the user, and we want to remember their +name throughout the project. Thatā€™s a good example of a situation in +which a global variable (the kind you make with the ā€œMake a variableā€ +button) is appropriate. Another common example is a variable called +ā€œscoreā€ in a game project. But sometimes you only need a variable +temporarily, during the running of a particular script. In that case you +can use the script variables block to make the variable:

+ +

As in the for block, you can click on an orange oval in the script +variables block without dragging to change its name. You can also make +more than one temporary variable by clicking on the right arrow at the +end of the block to add another variable oval:

+ +

{width=ā€200pxā€ height=ā€29pxā€}Renaming variables

+ +

There are several reasons why you might want to change the name of a +variable:

+ +
    +
  1. +

    It has a default name, such as the ā€œaā€ in script variables or the +ā€œiā€ in for.

    +
  2. +
  3. +

    It conflicts with another name, such as a global variable, that you +want to use in the same script.

    +
  4. +
  5. +

    You just decide a different name would be more self-documenting.

    +
  6. +
+ +

In the first and third case, you probably want to change the name +everywhere it appears in that script, or even in all scripts. In the +second case, if youā€™ve already used both variables in the script before +realizing that they have the same name, youā€™ll want to look at each +instance separately to decide which ones to rename. Both of these +operations are possible by right-clicking or control-clicking on a +variable oval.

+ +

{width=ā€155pxā€ +height=ā€145pxā€}{width=ā€271pxā€ +height=ā€121pxā€}{width=ā€133pxā€ +height=ā€71pxā€}If you right-click on an orange oval in a +context in which the variable is used, then you are able to rename +just that one orange oval:

+ +

{width=ā€164pxā€ +height=ā€80pxā€}{width=ā€143pxā€ +height=ā€71pxā€}If you right-click on the place where the +variable is defined (a script variables block, the orange oval for a +global variable in the Variables palette, or an orange oval thatā€™s built +into a block such as the ā€œiā€ in for), then you are given two renaming +options, ā€œrenameā€ and ā€œrename all.ā€ If you choose ā€œrename,ā€ then the +name is changed only in that one orange oval, as in the previous case:

+ +

{width=ā€143pxā€ +height=ā€71pxā€}{width=ā€164pxā€ +height=ā€80pxā€}But if you choose ā€œrename all,ā€ then the +name will be changed throughout the scope of the variable (the script +for a script variable, or everywhere for a global variable):

+ +

Transient variables

+ +

{width=ā€124pxā€ +height=ā€101pxā€}So far weā€™ve talked about variables with +numeric values, or with short text strings such as someoneā€™s name. But +thereā€™s no limit to the amount of information you can put in a variable; +in Chapter IV youā€™ll see how to use lists to collect many values in +one data structure, and in Chapter VIII youā€™ll see how to read +information from web sites. When you use these capabilities, your +project may take up a lot of memory in the computer. If you get close to +the amount of memory available to Snap!, then it may become impossible +to save your project. (Extra space is needed temporarily to convert from +Snap! ā€˜s internal representation to the form in which projects are +exported or saved.) If your program reads a lot of data from the outside +world that will still be available when you use it next, you might want +to have values containing a lot of data removed from memory before +saving the project. To do this, right-click or control-click on the +orange oval in the Variables palette, to see this menu:

+ +

You already know about the rename options, and helpā€¦ displays a help +screen about variables in general. Here weā€™re interested in the check +box next to transient. If you check it, this variableā€™s value will not +be saved when you save your project. Of course, youā€™ll have to ensure +that when your project is loaded, it recreates the needed value and sets +the variable to it.

+ +

Debugging

+ +

Snap! provides several tools to help you debug a program. They center +around the idea of pausing the running of a script partway through, so +that you can examine the values of variables.

+ +

The pause button

+ +

{width=ā€28pxā€ +height=ā€16pxā€}{width=ā€28pxā€ +height=ā€16pxā€}The simplest way to pause a program is +manually, by clicking the pause button in the top right corner of the +window. While the program is paused, you can run other scripts by +clicking on them, show variables on stage with the checkbox next to the +variable in the Variables palette or with the show variable block, and +do all the other things you can generally do, including modifying the +paused scripts by adding or removing blocks. The button changes shape to +and clicking it again resumes the paused scripts.

+ +

Breakpoints: the pause all block

+ +

{width=ā€79pxā€ +height=ā€21pxā€}The pause button is great if your program +seems to be in an infinite loop, but more often youā€™ll want to set a +breakpoint, a particular point in a script at which you want to pause. +The block, near the bottom of the Control palette, can be inserted in a +script to pause when it is run. So, for example, if your program is +getting an error message in a particular block, you could use pause all +just before that block to look at the values of variables just before +the error happens.

+ +

{width=ā€181pxā€ +height=ā€87pxā€}The pause all block turns bright cyan +while paused. Also, during the pause, you can right-click on a running +script and the menu that appears will give you the option to show +watchers for temporary variables of the script:

+ +

But what if the block with the error is run many times in a loop, and it +only errors when a particular condition is trueā€”say, the value of some +variable is negative, which shouldnā€™t ever happen. In the iteration +library (see page 25 for more about how to use libraries) is a +breakpoint block that lets you set a conditional breakpoint, and +automatically display the relevant variables before pausing. Hereā€™s a +sample use of it:

+ +

{width=ā€115pxā€ +height=ā€128pxā€}(In this contrived example, variable zot +comes from outside the script but is relevant to its behavior.) When you +continue (with the pause button), the temporary variable watchers are +removed by this breakpoint block before resuming the script. The +breakpoint block isnā€™t magic; you could alternatively just put a pause +all inside an if.2

+ +

Visible stepping

+ +

{width=ā€28pxā€ +height=ā€16pxā€}{width=ā€52pxā€ +height=ā€15pxā€}{width=ā€28pxā€ +height=ā€16pxā€}Sometimes youā€™re not exactly sure where +the error is, or you donā€™t understand how the program got there. To +understand better, youā€™d like to watch the program as it runs, at human +speed rather than at computer speed. You can do this by clicking the +visible stepping button ( ), before running a script or while the +script is paused. The button will light up ( ) and a speed control +slider will appear in the toolbar. When you start or continue the +script, its blocks and input slots will light up cyan one at a time:

+ +

{width=ā€720pxā€ +height=ā€110pxā€}In this simple example, the inputs to the blocks are +constant values, but if an input were a more complicated expression +involving several reporter blocks, each of those would light up as they +are called. Note that the input to a block is evaluated before the block +itself is called, so, for example, the 100 lights up before the move.

+ +

{width=ā€28pxā€ +height=ā€16pxā€}The speed of stepping is controlled by +the slider. If you move the slider all the way to the left, the speed is +zero, the pause button turns into a step button , and the script takes a +single step each time you push it. The name for this is single +stepping.

+ +

If several scripts that are visible in the scripting area are running at +the same time, all of them are stepped in parallel. However, consider +the case of two repeat loops with different numbers of blocks. While not +stepping, each script goes through a complete cycle of its loop in each +display cycle, despite the difference in the length of a cycle. In order +to ensure that the visible result of a program on the stage is the same +when stepped as when not stepped, the shorter script will wait at the +bottom of its loop for the longer script to catch up.

+ +

When we talk about custom blocks in Chapter III, weā€™ll have more to say +about visible stepping as it affects those blocks.

+ +

Etcetera

+ +

This manual doesnā€™t explain every block in detail. There are many more +motion blocks, sound blocks, costume and graphics effects blocks, and so +on. You can learn what they all do by experimentation, and also by +reading the ā€œhelp screensā€ that you can get by right-clicking or +control-clicking a block and selecting ā€œhelpā€¦ā€ from the menu that +appears. If you forget what palette (color) a block is, but you remember +at least part of its name, type control-F and enter the name in the text +block that appears in the palette area.

+ +

Here are the primitive blocks that donā€™t exist in Scratch:

+ +

{width=ā€120pxā€ +height=ā€22pxā€}{width=ā€101pxā€ +height=ā€22pxā€} reports a new costume consisting of +everything thatā€™s drawn on the stage by any sprite. Right-clicking the +block in the scripting area gives the option to change it to if vector +logging is enabled. See page 116.

+ +

{width=ā€200pxā€ +height=ā€36pxā€}Print characters in the given point size on the stage, +at the spriteā€™s position and in its direction. The sprite moves to the +end of the text. (Thatā€™s not always what you want, but you can save the +spriteā€™s position before using it, and sometimes you need to know how +big the text turned out to be, in turtle steps.) If the pen is down, the +text will be underlined.

+ +

{width=ā€115pxā€ +height=ā€49pxā€}Takes a sprite as input. Like stamp except +that the costume is stamped onto the selected sprite instead of onto the +stage. (Does nothing if the current sprite doesnā€™t overlap the chosen +sprite.)

+ +

{width=ā€114pxā€ +height=ā€33pxā€}Takes a sprite as input. Erases from that +spriteā€™s costume the area that overlaps with the current spriteā€™s +costume. (Does not affect the costume in the chosen spriteā€™s wardrobe, +only the copy currently visible.)

+ +

{width=ā€51pxā€ +height=ā€48pxā€}{width=ā€95pxā€ +height=ā€25pxā€}Icon Description automatically
+generated{width=ā€128pxā€ +height=ā€41pxā€} See page 6. See page 17.

+ +

{width=ā€164pxā€ +height=ā€22pxā€}Reporter version of the if/else primitive command block. +Only one of the two branches is evaluated, depending on the value of the +first input.

+ +

{width=ā€176pxā€ +height=ā€59pxā€}Looping block like repeat but with an index variable.

+ +

{width=ā€132pxā€ +height=ā€28pxā€}Declare local variables in a script.

+ +

{width=ā€83pxā€ +height=ā€18pxā€}{width=ā€69pxā€ +height=ā€19pxā€}{width=ā€112pxā€ +height=ā€17pxā€} See page 91.

+ +

{width=ā€263pxā€ +height=ā€20pxā€}Constant true or false value. See page 12.

+ +

{width=ā€204pxā€ height=ā€17pxā€} +Create a primitive using JavaScript. (This block is disabled by default; +the user must check ā€œJavascript extensionsā€ in the setting menu each +time a project is loaded.)

+ +

{width=ā€157pxā€ +height=ā€151pxā€}The at block lets you examine the screen +pixel directly behind the rotation center of a sprite, the mouse, or an +arbitrary (x,y) coordinate pair dropped onto the second menu slot. The +first five items of the left menu let you examine the color visible at +the position. (The ā€œRGBAā€ option reports a list.) The ā€œspritesā€ option +reports a list of all sprites, including this one, any point of which +overlaps this spriteā€™s rotation center (behind or in front). This is a +hyperblock with respect to its second input.

+ +

{width=ā€162pxā€ +height=ā€178pxā€}{width=ā€235pxā€ +height=ā€127pxā€}{width=ā€226pxā€ +height=ā€37pxā€} Checks the data type of a value.

+ +

{width=ā€326pxā€ +height=ā€102pxā€}

+ +

{width=ā€240pxā€ +height=ā€214pxā€}Turn the text into a list, using the second input as +the delimiter between items. The default delimiter, indicated by the +brown dot in the input slot, is a single space character. ā€œLetterā€ puts +each character of the text in its own list item. ā€œWordā€ puts each word +in an item. (Words are separated by any number of consecutive space, +tab, carriage return, or newline characters.) ā€œLineā€ is a newline +character (0xa); ā€œtabā€ is a tab character (0x9); ā€œcrā€ is a carriage +return (0xd). ā€œCsvā€ and ā€œjsonā€ split formatted text into lists of lists; +see page 54. ā€œBlocksā€ takes a script as the first input, reporting a +list structure representing the structure of the script. See Chapter XI.

+ +

{width=ā€142pxā€ +height=ā€18pxā€}For lists, reports true only if its two +input values are the very same list, so changing an item in one of them +is visible in the other. (For =, lists that look the same are the same.) +For text strings, uses case-sensitive comparison, unlike =, which is +case-independent.

+ +

{width=ā€275pxā€ +height=ā€18pxā€}These hidden blocks can be found with +the relabel option of any dyadic arithmetic block. Theyā€™re hidden partly +because writing them in Snap! is a good, pretty easy programming +exercise. Note: the two inputs to atan2 are Ī”x and Ī”y in that order, +because we measure angles clockwise from north. Max and min are +variadic; by clicking the arrowhead, you can provide additional +inputs.

+ +

Logo Description automatically generated with medium
+confidence{width=ā€60pxā€ +height=ā€18pxā€} A picture containing text, monitor, screenshot
+Description automatically
+generated{width=ā€60pxā€ +height=ā€18pxā€} Logo Description automatically
+generated{width=ā€60pxā€ +height=ā€18pxā€} Similarly, these hidden predicates can be found by +relabeling the relational predicates.

+ +

{width=ā€523pxā€ +height=ā€59pxā€}Metaprogramming (see Chapter XI. , +page 101)

+ +

These blocks support metaprogramming, which means manipulating blocks +and scripts as data. This is not the same as manipulating procedures +(see Chapter VI. ), which are what the blocks mean; in metaprogramming +the actual blocks, what you see on the screen, are the data. This +capability is new in version 8.0.

+ +

First class list blocks (see Chapter IV, page 46):

+ +

{width=ā€731pxā€ +height=ā€210pxā€}

+ +


+**{width=ā€80pxā€ +height=ā€20pxā€} {width=ā€137pxā€ +height=ā€20pxā€} **report the sprite or mouse position as a two-item +vector (x,y).

+ +

{width=ā€575pxā€ +height=ā€31pxā€}First class procedure blocks (see Chapter VI, page +65):

+ +

{width=ā€512pxā€ +height=ā€33pxā€}{width=ā€419pxā€ +height=ā€31pxā€}First class continuation blocks (see Chapter X, +page 93):

+ +

First class sprite, costume, and sound blocks (see Chapter VII, page +73):

+ +

{width=ā€565pxā€ +height=ā€206pxā€}

+ +

Scenes:

+ +

{width=ā€228pxā€ +height=ā€127pxā€}The major new feature of version 7.0 is scenes: A +project can include within it sub-projects, called scenes, each with its +own stage, sprites, scripts, and so on. This block makes another scene +active, replacing the current one.

+ +

Nothing is automatically shared between scenes: no sprites, no blocks, +no variables. But the old scene can send a message to the new one, to +start it running, with optional payload as in broadcast (page 23).

+ +

{width=ā€244pxā€ +height=ā€30pxā€}{width=ā€300pxā€ +height=ā€50pxā€}In particular, you can say

+ +
+

if the new scene expects to be started with a green flag signal.

+
+ +


+These arenā€™t new blocks but they have a new feature:

+ +

These accept two-item (x,y) lists as input, and have extended menus +(also including other sprites):

+ +

{width=ā€718pxā€ +height=ā€108pxā€}ā€Centerā€ means the center of the stage, +the point at (0,0). ā€œDirectionā€ is in the point in direction sense, the +direction that would leave this sprite pointing toward another sprite, +the mouse, or the center. ā€œRay lengthā€ is the distance from the center +of this sprite to the nearest point on the other sprite, in the current +direction.

+ +

{width=ā€247pxā€ +height=ā€136pxā€}The stop block has two extra menu choices. Stop this +block is used inside the definition of a custom block to stop just this +invocation of this custom block and continue the script that called it. +Stop all but this script is good at the end of a game to stop all the +game pieces from moving around, but keep running this script to provide +the userā€™s final score. The last two menu choices add a tab at the +bottom of the block because the current script can continue after it.

+ +

{width=ā€232pxā€ +height=ā€102pxā€}The new ā€œpen trailsā€ option is true if the +sprite is touching any drawn or stamped ink on the stage. Also, touching +will not detect hidden sprites, but a hidden sprite can use it to detect +visible sprites.

+ +

{width=ā€102pxā€ +height=ā€27pxā€}{width=ā€234pxā€ +height=ā€29pxā€}The video block has a snap option that takes a snapshot +and reports it as a costume. It is hyperized with +{width=ā€101pxā€ +height=ā€27pxā€}respect to its second input.

+ +

{width=ā€136pxā€ +height=ā€320pxā€}The ā€œnegā€ option is a monadic negation +operator, equivalent to . ā€œlgā€ is log~2~. ā€œidā€ is the identity function, +which reports its input. ā€œsignā€ reports 1 for positive input, 0 for zero +input, or -1 for negative input.

+ +

{width=ā€315pxā€ +height=ā€53pxā€}

+ +

{width=ā€361pxā€ +height=ā€117pxā€}

+ +

{width=ā€213pxā€ +height=ā€159pxā€}Extended mouse interaction events, sensing +clicking, dragging, hovering, etc. The ā€œstoppedā€ option triggers when +all scripts are stopped, as with the stop button; it is useful for +robots whose hardware interface must be told to turn off motors. A when +I am stopped script can run only for a limited time.

+ +

{width=ā€276pxā€ +height=ā€165pxā€}

+ +

Extended broadcast: Click the right arrowhead to direct the message to a +single sprite or the stage. Click again to add any value as a payload to +the message.

+ +

{width=ā€363pxā€ +height=ā€174pxā€}{width=ā€175pxā€ +height=ā€92pxā€}Extended when I receive: Click the right +arrowhead to expose a script variable (click on it to change its name, +like any script variable) that will be set to the data of a matching +broadcast. If the first input is set to ā€œany message,ā€ then the data +variable will be set to the message, if no payload is included with the +broadcast, or to a two-item list containing the message and the payload.

+ +

A picture containing text, clipart Description automatically
+generated{width=ā€161pxā€ +height=ā€36pxā€} If the input is set to ā€œany key,ā€ then a right +arrowhead appears:

+ +
+

{width=ā€216pxā€ +height=ā€40pxā€}{width=ā€175pxā€ +height=ā€36pxā€}and if you click it, a script variable +key is created whose value is the key that was pressed. (If the key is +one thatā€™ represented in the input menu by a word or phrase, e.g., +ā€œenterā€ or ā€œup arrow,ā€ then the value of key will be that word or +phrase, except for the space character, which is represented as +itself in key.)
+{width=ā€297pxā€ +height=ā€66pxā€}

+
+ +

{width=ā€571pxā€ +height=ā€84pxā€}{width=ā€535pxā€ +height=ā€106pxā€}{width=ā€611pxā€ +height=ā€279pxā€}

+ +

{width=ā€140pxā€ +height=ā€223pxā€}{width=ā€564pxā€ +height=ā€97pxā€}These ask features and more in the Menus +library.

+ +

The of block has an extended menu of attributes of a sprite. Position +reports an (x,y) vector. Size reports the percentage of normal size, as +controlled by the set size block in the Looks category. Left, right, +etc. report the stage coordinates of the corresponding edge of the +spriteā€™s bounding box. Variables reports a list of the names of all +variables in scope (global, sprite-local, and script variables if the +right input is a script.

+ +

Libraries

+ +

{width=ā€31pxā€ +height=ā€17pxā€}{width=ā€711pxā€ +height=ā€311pxā€}There are several collections of useful +procedures that arenā€™t Snap! primitives, but are provided as +libraries. To include a library in your project, choose the Librariesā€¦ +option in the file ( ) menu.

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs.

+ +

The libraries and their contents may change, but as of this writing the +list library has these blocks:

+ +

{width=ā€177pxā€ +height=ā€239pxā€} (The lightning bolt before the name in +several of these blocks means that they use compiled HOFs or JavaScript +primitives to achieve optimal speed. They are officially considered +experimental.) Remove duplicates from reports a list in which no two +items are equal. The sort block takes a list and a two-input comparison +predicate, such as <, and reports a list with the items sorted +according to that comparison. The assoc block is for looking up a key in +an association list: a list of two-item lists. In each two-item list, +the first is a key and the second is a value. The inputs are a key +and an association list; the block reports the first key-value pair +whose key is equal to the input key.

+ +

For each item is a variant of the primitive version that provides a # +variable containing the position in the input list of the currently +considered item. Multimap is a version of map that allows multiple list +inputs, in which case the mapping function must take as many inputs as +there are lists; it will be called with all the first items, all the +second items, and so on. Zip takes any number of lists as inputs; it +reports a list of lists: all the first items, all the second items, and +so on. The no-name identity function reports its input.

+ +

Sentence and sentenceāž”list are borrowed from the word and sentence +library (page 27) to serve as a variant of append that accepts non-lists +as inputs. Printable takes a list structure of any depth as input and +reports a compact representation of the list as a text string.

+ +

The iteration, composition library has these blocks:

+ +

{width=ā€162pxā€ +height=ā€456pxā€}Catch and throw provide a nonlocal exit facility. You +can drag the tag from a catch block to a throw inside its C-slot, and +the throw will then jump directly out to the matching catch without +doing anything in between.

+ +

If do and pause all is for setting a breakpoint while debugging code. +The idea is to put show variable blocks for local variables in the +C-slot; the watchers will be deleted when the user continues from the +pause.

+ +

Ignore is used when you need to call a reporter but you donā€™t care about +the value it reports. (For example, you are writing a script to time how +long the reporter takes.)

+ +

The cascade blocks take an initial value and call a function repeatedly +on that value, f(f(f(fā€¦(x)))).

+ +

The compose block takes two functions and reports the function +f(g(x)).

+ +

{width=ā€100pxā€ +height=ā€15pxā€}{width=ā€303pxā€ +height=ā€29pxā€}The first three repeat blocks are variants +of the primitive repeat until block, giving all four combinations of +whether the first test happens before or after the first repetition, and +whether the condition must be true or false to continue repeating. The +last repeat block is like the repeat primitive, but makes the number of +repetitions so far available to the repeated script. The next two blocks +are variations on for: the first allows an explicit step instead of +using Ā±1, and the second allows any values, not just numbers; inside the +script you say

+ +

{width=ā€330pxā€ +height=ā€131pxā€}{width=ā€356pxā€ +height=ā€112pxā€}replacing the grey block in the picture +with an expression to give the next desired value for the loop index. +Pipe allows reordering a nested composition with a left-to-right one:

+ +

The stream library has these blocks:

+ +

{width=ā€303pxā€ +height=ā€207pxā€}Streams are a special kind of list whose +items are not computed until they are needed. This makes certain +computations more efficient, and also allows the creation of lists with +infinitely many items, such as a list of all the positive integers. The +first five blocks are stream versions of the list blocks in front of, +item 1 of, all but first of, map, and keep. Show stream takes a stream +and a number as inputs, and reports an ordinary list of the first n +items of the stream. Stream is like the primitive list; it makes a +finite stream from explicit items. Sieve is an example block that takes +as input the stream of integers starting with 2 and reports the stream +of all the prime numbers. Stream with numbers from is like the numbers +from block for lists, except that there is no endpoint; it reports an +infinite stream of numbers.

+ +

The word and sentence library has these blocks:

+ +

{width=ā€161pxā€ +height=ā€350pxā€}This library has the goal of recreating +the Logo approach to handling text: A text isnā€™t best viewed as a string +of characters, but rather as a sentence, made of words, each of +which is a string of letters. With a few specialized exceptions, this +is why people put text into computers: The text is sentences of natural +(i.e., human) language, and the emphasis is on words as constitutive of +sentences. You barely notice the letters of the words, and you donā€™t +notice the spaces between them at all, unless youā€™re proof-reading. +(Even then: Proofreading is diffciult, because you see what you expect +to see, what will make the snetence make sense, rather than the +misspelling in front of of your eyes.) Internally, Logo stores a +sentence as a list of words, and a word as a string of letters.

+ +

Inexplicably, the designers of Scratch chose to abandon that tradition, +and to focus on the representation of text as a string of characters. +The one vestige of the Logo tradition from which Scratch developed is +the block named letter (1) of (world), rather than character (1) of +(world). Snap! inherits its text handling from Scratch.

+ +

In Logo, the visual representation of a sentence (a list of words) looks +like a natural language sentence: a string of words with spaces between +them. In Snap!, the visual representation of a list looks nothing at +all like natural language. On the other hand, representing a sentence as +a string means that the program must continually re-parse the text on +every operation, looking for spaces, treating multiple consecutive +spaces as one, and so on. Also, itā€™s more convenient to treat a sentence +as a list of words rather than a string of words because in the former +case you can use the higher order functions map, keep, and combine on +them. This library attempts to be agnostic as to the internal +representation of sentences. The sentence selectors accept any +combination of lists and strings; there are two sentence constructors, +one to make a string (join words) and one to make a list (sentence).

+ +

The selector names come from Logo, and should be self-explanatory. +However, because in a block language you donā€™t have to type the block +name, instead of the terse butfirst or the cryptic bf we spell out ā€œall +but first ofā€ and include ā€œwordā€ or ā€œsentenceā€ to indicate the intended +domain. Thereā€™s no first letter of block because letter 1 of serves that +need. Join words (the sentence-as-string constructor) is like the +primitive join except that it puts a space in the reported value between +each of the inputs. Sentence (the List-colored sentence-as-list +constructor) accepts any number of inputs, which can be words, +sentences-as-lists, or sentences-as-strings. (If inputs are lists of +lists, only one level of flattening is done.) Sentence reports a list of +words; there will be no empty words or words containing spaces. The four +blocks with right-arrows in their names convert back and forth between +text strings (words or sentences) and lists. (Splitting a word into a +list of letters is unusual unless youā€™re a linguist investigating +orthography.) Printable takes a list (including a deep list) of words as +input and reports a text string in which parentheses are used to show +the structure, as in Lisp/Scheme.

+ +

The pixels library has one block:

+ +

{width=ā€75pxā€ +height=ā€60pxā€}Costumes are first class data in Snap!. +Most of the processing of costume data is done by primitive blocks in +the Looks category. (See page 79.) This library provides snap, which +takes a picture using your computerā€™s camera and reports it as a +costume.

+ +

The bar charts library has these blocks:

+ +

{width=ā€329pxā€ +height=ā€184pxā€}Bar chart takes a table (typically from a +CSV data set) as input and reports a summary of the table grouped by the +field in the specified column number. The remaining three inputs are +used only if the field values are numbers, in which case they can be +grouped into buckets (e.g., decades, centuries, etc.). Those inputs +specify the smallest and largest values of interest and, most +importantly, the width of a bucket (10 for decades, 100 for centuries). +If the field isn't numeric, leave these three inputs empty or set them +to zero. Each string value of the field is its own bucket, and they +appear sorted alphabetically.

+ +

Bar chart reports a new table with three columns. The first column +contains the bucket name or smallest number. The second column contains +a nonnegative integer that says how many records in the input table fall +into this bucket. The third column is a subtable containing the actual +records from the original table that fall into the bucket. Plot bar +chart takes the table reported by bar chart and graphs it on the stage, +with axes labelled appropriately. The remaining blocks are helpers for +those.

+ +

If your buckets aren't of constant width, or you want to group by some +function of more than one field, load the "Frequency Distribution +Analysis" library instead.

+ +

The multi-branched conditional library has these blocks:

+ +

{width=ā€178pxā€ +height=ā€238pxā€}The catch and throw blocks duplicate ones +in the iteration library, and are included because they are used to +implement the others. The cases block sets up a multi-branch +conditional, similar to cond in Lisp or switch in C-family languages. +The first branch is built into the cases block; it consists of a Boolean +test in the first hexagonal slot and an action script, in the C-slot, to +be run if the test reports true. The remaining branches go in the +variadic hexagonal input at the end; each branch consists of an else if +block, which includes the Boolean test and the corresponding action +script, except possibly for the last branch, which can use the +unconditional else block. As in other languages, once a branch succeeds, +no other branches are tested.

+ +

###

+ +

The variadic library has these blocks:

+ +

{width=ā€115pxā€ +height=ā€40pxā€}These are versions of the associative +operators and, and or that take any number of inputs instead of exactly +two inputs. As with any variadic input, you can also drop a list of +values onto the arrowheads instead of providing the inputs one at a time +As of version 8.0, the arithmetic operators sum, product, minimum, and +maximum are no longer included, because the primitive operators +. Ɨ, +min, and max are themselves variadic.

+ +

{width=ā€699pxā€ +height=ā€106pxā€}The colors and crayons library has these +blocks:

+ +

It is intended as a more powerful replacement for the primitive set pen +block, including first class color support; HSL color specification as +a better alternative to the HSV that Snap! inherits from JavaScript; a +ā€œfair hueā€ scale that compensates for the eyeā€™s grouping a wide range of +light frequencies as green while labelling mere slivers as orange or +yellow; the X11/W3C standard color names; RGB in hexadecimal; a linear +color scale (as in the old days, but better) based on fair hues and +including shades (darker colors) and grayscale. Another linear scale is +a curated set of 100 ā€œcrayons,ā€ explained further on the next page.

+ +

{width=ā€294pxā€ +height=ā€219pxā€}{width=ā€109pxā€ +height=ā€22pxā€}{width=ā€91pxā€ +height=ā€22pxā€}Colors are created by the block (for direct user +selection), the color from block to specify a color numerically, or by , +which reports the color currently in use by the pen. The from color +block reports names or numbers associated with a color:

+ +

{width=ā€464pxā€ +height=ā€41pxā€}Colors can be created from other colors:

+ +

The three blocks with pen in their names are improved versions of +primitive Pen blocks. In principle set pen, for example, could be +implemented using a (hypothetical) set pen to color composed with the +color from block, but in fact set pen benefits from knowing how the pen +color was set in its previous invocation, so itā€™s implemented separately +from color from. Details in Appendix A.

+ +

{width=ā€720pxā€ +height=ā€24pxā€}The recommended way to choose a color is from one of two +linear scales: the continuous color numbers and the discrete +crayons:

+ +

{width=ā€720pxā€ height=ā€24pxā€}

+ +

{width=ā€384pxā€ +height=ā€20pxā€}Color numbers are based on fair hues, a +modification of the spectrum (rainbow) hue scale that devotes less space +to green and more to orange and yellow, as well as promoting brown to a +real color. Here is the normal hue scale, for reference:

+ +

{width=ā€384pxā€ +height=ā€20pxā€}Here is the fair hue scale:

+ +

{width=ā€480pxā€ +height=ā€20pxā€}Here is the color number scale:

+ +

(The picture is wider so that pure spectral colors line up with the fair +hue scale.)

+ +

{width=ā€480pxā€ +height=ā€20pxā€}And here are the 100 crayons:

+ +

The color from block, for example, provides different pulldown menus +depending on which scale you choose:

+ +

{width=ā€232pxā€ +height=ā€33pxā€}{width=ā€679pxā€ +height=ā€275pxā€}You can also type the crayon name: There +are many scales:

+ +

{width=ā€412pxā€ +height=ā€183pxā€}

+ +

{width=ā€590pxā€ +height=ā€51pxā€} The white slot at the end of some of the +blocks has two purposes. It can be used to add a transparency to a color +(0=opaque, 100=transparent):

+ +

{width=ā€675pxā€ +height=ā€41pxā€}or it can be expanded to enter three or +four numbers for a vector directly into the block, so these are +equivalent:

+ +

{width=ā€719pxā€ +height=ā€41pxā€}But note that a transparency number in a +four-number RGBA vector is on the scale 255=opaque, 0=transparent, so +the following are not equivalent:

+ +

Set pen crayon to provides the equivalent of a box of 100 crayons. They +are divided into color groups, so the menu in the set pen crayon to +input slot has submenus. The colors are chosen so that starting +{width=ā€419pxā€ +height=ā€49pxā€}from crayon 0, change pen crayon by 10 +rotates through an interesting, basic set of ten colors:

+ +

{width=ā€418pxā€ +height=ā€27pxā€}Using change pen crayon by 5 instead +gives ten more colors, for a total of 20:

+ +

(Why didnā€™t we use the colors of the 100-crayon Crayolaā„¢ box? A few +reasons, one of which is that some Crayola colors arenā€™t representable +on RGB screens. Some year when you have nothing else to do, look up +ā€œcolor spaceā€ on Wikipedia. Also ā€œcrayon.ā€ Oh, itā€™s deliberate that +change pen crayon by 5 doesnā€™t include white, since thatā€™s the usual +stage background color. White is crayon 14.) Note that crayon 43 is +ā€œVariablesā€; all the standard block colors are included.

+ +

See Appendix A (page 139) for more information.

+ +

{width=ā€145pxā€ +height=ā€86pxā€}The crayon library has only the crayon features, +without the rest of the colors package.

+ +

The catch errors library has these blocks:

+ +

{width=ā€41pxā€ +height=ā€15pxā€}{width=ā€292pxā€ +height=ā€134pxā€}The safely try block allows you to handle +errors that happen when your program is run within the program, instead +of stopping the script with a red halo and an obscure error message. The +block runs the script in its first C-slot. If it finishes without an +error, nothing else happens. But if an error happens, the code in the +second C-slot is run. While that second script is running, the variable +contains the text of the error message that would have been displayed if +you werenā€™t catching the error. The error block is sort of the opposite: +it lets your program generate an error message, which will be +displayed with a red halo unless it is caught by safely try. Safely try +reporting is the reporter version of safely try.

+ +

The text costumes library has only two blocks:

+ +

{width=ā€51pxā€ +height=ā€20pxā€}{width=ā€184pxā€ +height=ā€43pxā€}Costume from text reports a costume that +can be used with the switch to +{width=ā€313pxā€ +height=ā€18pxā€}costume block to make a button:

+ +

Costume with background reports a costume made from another costume by +coloring its background, taking a color input like the set pen color to +RGB(A) block and a number of turtle steps of padding around the original +costume. These two blocks work together to make even better buttons:

+ +

{width=ā€529pxā€ height=ā€65pxā€}

+ +

The text to speech library has these blocks:

+ +

{width=ā€218pxā€ +height=ā€77pxā€}This library interfaces with a capability in up-to-date +browsers, so it might not work for you. It works best if the accent +matches the text!

+ +

The parallelization library contains these blocks:

+ +

{width=ā€113pxā€ +height=ā€121pxā€}The two do in parallel blocks take any +number of scripts as inputs. Those scripts will be run in parallel, like +ordinary independent scripts in the scripting area. The and wait version +waits until all of those scripts have finished before continuing the +script below the block.

+ +

{width=ā€132pxā€ +height=ā€142pxā€}The create variables library has these +blocks:

+ +

These blocks allow a program to perform the same operation as the

+ +

button, making global, sprite local, or script variables, but allowing +the program to compute the variable name(s). It can also set and find +the values of these variables, show and hide their stage watchers, +delete them, and find out if they already exist.

+ +

The getters and setters library has these blocks:

+ +

{width=ā€180pxā€ +height=ā€101pxā€}{width=ā€28pxā€ +height=ā€16pxā€}The purpose of this library is to allow +program access to the settings controlled by user interface elements, +such as the settings menu. The setting block reports a setting; the set +flag block sets yes-or-no options that have checkboxes in the user +interface, while the set value block controls settings with numeric or +text values, such as project name.

+ +

Certain settings are ordinarily remembered on a per-user basis, such as +the ā€œzoom blocksā€ value. But when these settings are changed by this +library, the change is in effect only while the project using the +library is loaded. No permanent changes are made. Note: this library has +not been converted for version 7.0, so youā€™ll have to enable Javascript +extensions to use it.

+ +

The bignums, rationals, complex #s library has these blocks:

+ +

{width=ā€180pxā€ +height=ā€149pxā€}The USE BIGNUMS block takes a Boolean input, to turn the +infinite precision feature on or off. When on, all of the arithmetic +operators are redefined to accept and report integers of any number of +digits (limited only by the memory of your computer) and, in fact, the +entire Scheme numeric tower, with exact rationals and with complex +numbers. The Scheme number block has a list of functions applicable to +Scheme numbers, including subtype predicates such as rational? and +infinite?, and selectors such as numerator and real-part.

+ +

{width=ā€464pxā€ +height=ā€40pxā€}The ! block computes the factorial +function, useful to test whether bignums are turned on. Without bignums:

+ +

With bignums:

+ +

{width=ā€723pxā€ +height=ā€35pxā€}The 375-digit value of 200! isnā€™t +readable on this page, but if you right-click on the block and choose +ā€œresult pic,ā€ you can open the resulting picture in a browser window and +scroll through it. (These values end with a bunch of zero digits. Thatā€™s +not roundoff error; the prime factors of 100! and 200! include many +copies of 2 and 5.) The block with no name is a way to enter things like +3/4 and 4+7i into numeric input slots by converting the slot to Any +type.

+ +

The strings, multi-line input library provides these blocks:

+ +

{width=ā€378pxā€ +height=ā€196pxā€}All of these could be written in Snap! +itself, but these are implemented using the corresponding JavaScript +library functions directly, so they run fast. They can be used, for +example, in scraping data from a web site. The command use +case-independent comparisons applies only to this library. The multiline +block accepts and reports a text input that can include newline +characters.

+ +

The animation library has these blocks:

+ +

{width=ā€385pxā€ +height=ā€224pxā€}Despite the name, this isnā€™t only about graphics; you +can animate the values of a variable, or anything else thatā€™s expressed +numerically.

+ +

{width=ā€93pxā€ +height=ā€19pxā€}The central idea of this library is an +easing function, a reporter whose domain and range are real numbers +between 0 and 1 inclusive. The function represents what fraction of the +ā€œdistanceā€ (in quotes because it might be any numeric value, such as +temperature in a simulation of weather) from here to there should be +covered in what fraction of the time. A linear easing function means +steady progression. A quadratic easing function means starting slowly +and accelerating. (Note that, since itā€™s a requirement that f(0)=0 and +f(1)=1, there is only one linear easing function, f(x)=x, and +similarly for other categories.) The block reports some of the common +easing functions.

+ +

{width=ā€445pxā€ +height=ā€61pxā€}The two Motion blocks in this library +animate a sprite. Glide always animates the spriteā€™s motion. Animateā€™s +first pulldown menu input allows you to animate horizontal or vertical +motion, but will also animate the spriteā€™s direction or size. The +animate block in Control lets you animate any numeric quantity with any +easing function. The getter and setter inputs are best explained by +example:

+ +

{width=ā€327pxā€ +height=ā€25pxā€}is equivalent to

+ +

The other blocks in the library are helpers for these four.

+ +

The serial ports library contains these blocks:

+ +

{width=ā€166pxā€ +height=ā€99pxā€}It is used to allow hardware developers to +control devices such as robots that are

+ +

connected to your computer via a serial port.

+ +

The frequency distribution analysis library has these blocks:

+ +

{width=ā€387pxā€ +height=ā€230pxā€}

+ +

This is a collection of tools for analyzing large data sets and plotting +histograms of how often some value is found in some column of the table +holding the data.

+ +

For more information go here:

+ +

http://tinyurl.com/jens-data

+ +

The audio comp library includes these blocks:

+ +

{width=ā€340pxā€ +height=ā€286pxā€}This library takes a sound, one that you record or +one from our collection of sounds, and manipulates it by systematically +changing the intensity of the samples in the sound and by changing the +sampling rate at which the sound is reproduced. Many of the blocks are +helpers for the plot sound block, used to plot the waveform of a sound. +The play sound (primitive) block plays a sound. __ Hz for reports a +sine wave as a list of samples.

+ +

The web services library has these blocks:

+ +

{width=ā€327pxā€ +height=ā€106pxā€}The first block is a generalization of the +primitive url block, allowing more control over the various options in +web requests: GET, POST, PUT, and DELETE, and fine control over the +content of the message sent to the server. Current location reports your +latitude and longitude. Listify takes some text in JSON format (see page +54) and converts it to a structured list. Value at key looks up a +key-value pair in a (listified) JSON dictionary. The key:value: block is +just a constructor for an abstract data type used with the other blocks

+ +

The database library contains these blocks:

+ +

{width=ā€217pxā€ +height=ā€117pxā€}It is used to keep data that persist from +one Snap! session to the next, if you use the same browser and the +same login.

+ +

The world map library has these blocks:

+ +

{width=ā€234pxā€ +height=ā€327pxā€}Using any of the command blocks puts a map +on the screen, in a layer in front of the stageā€™s background but behind +the pen trails layer (which is in turn behind all the sprites). The +first block asks your browser for your current physical location, for +which you may be asked to give permission. The next two blocks get and +set the mapā€™s zoom amount; the default zoom of 10 ļ¬ts from San Francisco +not quite down to Palo Alto on the screen. A zoom of 1 ļ¬ts almost the +entire world. A zoom of 3 fits the United States; a zoom of 5 ļ¬ts +Germany. The zoom can be changed in half steps, i.e., 5.5 is different +from 5, but 5.25 isnā€™t.

+ +

The next five blocks convert between stage coordinates (pixels) and +Earth coordinates (latitude and longitude). The change by x: y: block +shifts the map relative to the stage. The distance to block measures the +map distance (in meters) between two sprites. The three reporters with +current in their names find your actual location, again supposing that +geolocation is enabled on your device. Update redraws the map; as +costume reports the visible section of the map as a costume. Set style +allows things like satellite pictures.

+ +

The APL primitives library contains these blocks:

+ +

{width=ā€550pxā€ +height=ā€107pxā€}

+ +

{width=ā€620pxā€ +height=ā€196pxā€}

+ +

For more information about APL, see Appendix B (page 148).

+ +

The {width=ā€115pxā€ +height=ā€47pxā€}list comprehension library has one +block, zip. Its first input is a function of two inputs. The two +Any-type inputs are deep lists (lists of lists ofā€¦) interpreted as +trees, and the function is called with every possible combination of a +leaf node of the first tree and a leaf node of the second tree. But +instead of taking atoms (non-lists) as the leaves, zip allows the leaves +of each tree to be vectors (one-dimensional lists), matrices +(two-dimensional lists), etc. The Number-type inputs specify the leaf +dimension for each tree, so the function input might be called with a +vector from the first tree and an atom from the second tree.

+ +

{width=ā€85pxā€ +height=ā€145pxā€}The bitwise library provides bitwise logic +functions; each bit of the reported value is the result of applying the +corresponding Boolean function to the corresponding bits of the +input(s). The Boolean functions are not for Ā¬, and for āˆ§, or for āˆØ, and +xor (exclusive or) for āŠ». The remaining functions shift their first +input left or right by the number of bits given by the second input. +<< is left shift, >> is arithmetic right shift (shifting in one bits +from the left), and >>> is logical right shift (shifting in zero bits +from the left). If you donā€™t already know what these mean, find a +tutorial online.

+ +

{width=ā€627pxā€ +height=ā€155pxā€}

+ +

The MQTT library supports the Message Queuing Telemetry Transport +protocol, for connecting with IOT devices. See https://mqtt.org/ for +more information.

+ +

{width=ā€479pxā€ +height=ā€277pxā€}The Signada library allows you to +control a microBit or similar device that works with the Signada +MicroBlocks project.

+ +

{width=ā€325pxā€ height=ā€182pxā€}

+ +

The menus library provides the ability to display hierarchical menus +on the stage, using the ask blockā€™s ability to take lists as inputs. See +page 24.

+ +

The SciSnap! library and the TuneScope library are too big to +discuss here and are documented separately at +http://emu-online.de/ProgrammingWithSciSnap.pdf and +https://maketolearn.org/creating-art-animations-and-music/ +respectively.

+ +

Saving and Loading Projects and Media

+ +

After youā€™ve created a project, youā€™ll want to save it, so that you can +have access to it the next time you use Snap!. There are two ways to +do that. You can save a project on your own computer, or you can save it +at the Snap! web site. The advantage of saving on the net is that you +have access to your project even if you are using a different computer, +or a mobile device such as a tablet or smartphone. The advantage of +saving on your computer is that you have access to the saved project +while on an airplane or otherwise not on the net. Also, cloud projects +are limited in size, but you can have all the costumes and sounds you +like if you save locally. This is why we have multiple ways to save.

+ +

{width=ā€341pxā€ +height=ā€247pxā€}In either case, if you choose ā€œSave asā€¦ā€ +from the File menu. Youā€™ll see something like this:

+ +

(If you are not logged in to your Snap! cloud account, Computer will +be the only usable option.) The text box at the bottom right of the Save +dialog allows you to enter project notes that are saved with the +project.

+ +

Local Storage

+ +

Click on Computer and Snap!ā€™s Save Project dialog window will be +replaced by your operating systemā€™s standard save window. If your +project has a name, that name will be the default filename if you donā€™t +give a different name. Another, equivalent way to save to disk is to +choose ā€œExport projectā€ from the File menu.

+ +

{width=ā€118pxā€ height=ā€224pxā€}Creating a Cloud Account

+ +

{width=ā€28pxā€ +height=ā€16pxā€}The other possibility is to save your +project ā€œin the cloud,ā€ at the Snap! web site. In order to do this, +you need an account with us. Click on the Cloud button ( ) in the Tool +Bar. Choose the ā€œSignupā€¦ā€ option. This will show you a window that +looks like the picture at the right.

+ +

You must choose a user name that will identify you on the web site, such +as Jens or bh. If youā€™re a Scratch user, you can use your Scratch name +for Snap! too. If youā€™re a kid, donā€™t pick a user name that includes +your family name, but first names or initials are okay. Donā€™t pick +something youā€™d be embarrassed to have other users (or your parents) +see! If the name you want is already taken, youā€™ll have to choose +another one. You must also supply a password.

+ +

We ask for your month and year of birth; we use this information only to +decide whether to ask for your own email address or your parentā€™s email +address. (If youā€™re a kid, you shouldnā€™t sign up for anything on the +net, not even Snap!, without your parentā€™s knowledge.) We do not store +your birthdate information on our server; it is used on your own +computer only during this initial signup. We do not ask for your exact +birthdate, even for this one-time purpose, because thatā€™s an important +piece of personally identifiable information.

+ +

When you click OK, an email will be sent to the email address you gave, +asking you to verify (by clicking a link) that itā€™s really your email +address. We keep your email address on file so that, if you forget your +password, we can send you a password-reset link. We will also email you +if your account is suspended for violation of the Terms of Service. We +do not use your address for any other purpose. You will never receive +marketing emails of any kind through this site, neither from us nor from +third parties. If, nevertheless, you are worried about providing this +information, do a web search for ā€œtemporary email.ā€

+ +

Finally, you must read and agree to the Terms of Service. A quick +summary: Donā€™t interfere with anyone elseā€™s use of the web site, and +donā€™t put copyrighted media or personally identifiable information in +projects that you share with other users. And weā€™re not responsible if +something goes wrong. (Not that we expect anything to go wrong; since +Snap! runs in JavaScript in your browser, it is strongly isolated from +the rest of your computer. But the lawyers make us say this.)

+ +

Saving to the Cloud

+ +

Once youā€™ve created your account, you can log into it using the +ā€œLoginā€¦ā€ option from the Cloud menu:

+ +

{width=ā€162pxā€ +height=ā€195pxā€}Use the user name and password that you +set up earlier. If you check the ā€œStay signed inā€ box, then you will be +logged in automatically the next time you run Snap! from the same +browser on the same computer. Check the box if youā€™re using your own +computer and you donā€™t share it with siblings. Donā€™t check the box if +youā€™re using a public computer at the library, at school, etc.

+ +

Once logged in, you can choose the ā€œCloudā€ option in the ā€œSave Projectā€ +dialog shown on page 37. You enter a project name, and optionally +project notes; your project will be saved online and can be loaded from +anywhere with net access. The project notes will be visible to other +users if you publish your project.

+ +

Loading Saved Projects

+ +

Once youā€™ve saved a project, you want to be able to load it back into +Snap!. There are two ways to do this:

+ +

1. If you saved the project in your online Snap! account, choose the +ā€œOpenā€¦ā€ option from the File menu. Choose the ā€œCloudā€ button, then +select your project from the list in the big text box and click OK, or +choose the ā€œComputerā€ button to open an operating system open dialog. (A +third button, ā€œExamples,ā€ lets you choose from example projects that we +provide. You can see what each of these projects is about by clicking on +it and reading its project notes.)

+ +

2. If you saved the project as an XML file on your computer, choose +ā€œImportā€¦ā€ from the File menu. This will give you an ordinary browser +file-open window, in which you can navigate to the file as you would in +other software. Alternatively, find the XML file on your desktop, and +just drag it onto the Snap! window.

+ +

The second technique above also allows you to import media (costumes and +sounds) into a project. Just choose ā€œImportā€¦ā€ and then select a +picture or sound file instead of an XML file.

+ +

Snap! can also import projects created in BYOB 3.0 or 3.1, or (with +some effort; see our web site) in Scratch 1.4, 2.0 or 3.0. Almost all +such projects work correctly in Snap!, apart from a small number of +incompatible blocks.

+ +

If you saved projects in an earlier version of Snap! using the +ā€œBrowserā€ option, then a Browser button will be shown in the Open dialog +to allow you to retrieve those projects. But you can save them only with +the Computer and Cloud options.

+ +

If you lose your project, do this first!

+ +

{width=ā€31pxā€ +height=ā€17pxā€}If you are still in Snap! and +realize that youā€™ve loaded another project without saving the one you +were working on: Donā€™t edit the new project. From the File menu +choose the Restore unsaved project option.

+ +

Restore unsaved project will also work if you log out of Snap! and +later log back in, as long as you donā€™t edit another project meanwhile. +Snap! remembers only the most recent project that youā€™ve edited (not +just opened, but actually changed in the project editor).

+ +

If your project on the cloud is missing, empty, or otherwise broken and +isnā€™t the one you edited most recently, or if Restore unsaved project +fails: Donā€™t edit the broken project. In the Openā€¦ box, enter +your project name, then push the Recover button. Do this right away, +because we save only the version before the most recent, and the latest +before today. So donā€™t keep saving bad versions; Recover right away. The +Recover feature works only on a project version that you actually saved, +so Restore unsaved project is your first choice if you switch away from +a project without saving it.

+ +

To help you remember to save your projects, when youā€™ve edited the +project and havenā€™t yet saved it, Snap! displays a pencil icon to the +left of the project name on the toolbar at the top of the window:

+ +

{width=ā€604pxā€ +height=ā€49pxā€}

+ +

Private and Public Projects

+ +

By default, a project you save in the cloud is private; only you can see +it. There are two ways to make a project available to others. If you +share a project, you can give your friends a project URL (in your +browserā€™s URL bar after you open the project) they can use to read it. +If you publish a project, it will appear on the Snap! web site, and +the whole world can see it. In any case, nobody other than you can ever +overwrite your project; if others ask to save it, they get their own +copy in their own account.

+ +

Building a Block

+ +

The first version of Snap! was called BYOB, for ā€œBuild Your Own +Blocks.ā€ This was the first and is still the most important capability +we added to Scratch. (The name was changed because a few teachers have +no sense of humor. ā˜¹ You pick your battles.) Scratch 2.0 and later also +has a partial custom block capability.

+ +

Simple Blocks

+ +

{width=ā€720pxā€ +height=ā€261pxā€}In every palette, at or near the bottom, +is a button labeled ā€œMake a block.ā€ Also, floating near the top of the +palette is a plus sign. Also, the menu you get by right-clicking on the +background of the scripting area has a ā€œmake a blockā€ option.

+ +

{width=ā€218pxā€ +height=ā€225pxā€}Clicking any of these will display a +dialog window in which you choose the blockā€™s name, shape, and +palette/color. You also decide whether the block will be available to +all sprites, or only to the current sprite and its children.

+ +

In this dialog box, you can choose the block's palette, shape, and +name. With one exception, there is one color per palette, e.g., all +Motion blocks are blue. But the Variables palette includes the orange +variable-related blocks and the red list-related blocks. Both colors are +available, along with an ā€œOtherā€ option that makes grey blocks in the +Variables palette for blocks that donā€™t fit any category.

+ +

There are three block shapes, following a convention that should be +familiar to Scratch users: The jigsaw-puzzle-piece shaped blocks are +Commands, and donā€™t report a value. The oval blocks are Reporters, and +the hexagonal blocks are Predicates, which is the technical term for +reporters that report Boolean (true or false) values.

+ +

Suppose you want to make a block named ā€œsquareā€ that draws a square. You +would choose Motion, Command, and type ā€œsquareā€ into the name field. +When you click OK, you enter the Block Editor. This works just like +making a script in the spriteā€™s scripting area, except that the ā€œhatā€ +block at the top, instead of saying something like ā€œwhen I am clicked,ā€ +has a picture of the block youā€™re building. This hat block is called the +prototype of your custom block.3 You drag blocks under the hat to +program your custom block, then click OK:

+ +

{width=ā€404pxā€ +height=ā€128pxā€}

+ +

{width=ā€443pxā€ +height=ā€350pxā€}

+ +

Your block appears at the bottom of the Motion palette. Hereā€™s the block +and the result of using it:

+ +

{width=ā€407pxā€ +height=ā€136pxā€}

+ +

Custom Blocks with Inputs

+ +

But suppose you want to be able to draw squares of different sizes. +Control-click or right-click on the block, choose ā€œedit,ā€ and the Block +Editor will open. Notice the plus signs before and after the word square +in the prototype block. If you hover the mouse over one, it lights up:

+ +

{width=ā€331pxā€ +height=ā€261pxā€}

+ +

{width=ā€248pxā€ +height=ā€154pxā€}Click on the plus on the right. You will +then see the ā€œinput nameā€ dialog:

+ +

Type in the name ā€œsizeā€ and click OK. There are other options in this +dialog; you can choose ā€œtitle textā€ if you want to add words to the +block name, so it can have text after an input slot, like the ā€œmove ( ) +stepsā€ block. Or you can select a more extensive dialog with a lot of +options about your input name. But weā€™ll leave that for later. When you +click OK, the new input appears in the block prototype:

+ +

{width=ā€142pxā€ +height=ā€143pxā€}You can now drag the orange variable down +into the script, then click okay:

+ +

{width=ā€142pxā€ +height=ā€144pxā€}

+ +

{width=ā€67pxā€ +height=ā€24pxā€}Your block now appears in the Motion palette with an +input box: You can draw any size square by entering the length of its +side in the box and running the block as usual, by clicking it or by +putting it in a script.

+ +

Editing Block Properties

+ +

{width=ā€96pxā€ +height=ā€73pxā€}What if you change your mind about a +blockā€™s color (palette) or shape (command, reporter, predicate)? If you +click in the hat block at the top that holds the prototype, but not in +the prototype itself, youā€™ll see a window in which you can change the +color, and sometimes the shape, namely, if the block is not used in +any script, whether in a scripting area or in another custom block. +(This includes a one-block script consisting of a copy of the new block +pulled out of the palette into the scripting area, seeing which made you +realize itā€™s the wrong category. Just delete that copy (drag it back to +the palette) and then change the category.)

+ +

If you right-click/control-click the hat block, you get this menu:

+ +

Script pic exports a picture of the script. (Many of the illustrations +in this manual were made that way.) Translations opens a window in which +you can specify how your block should be translated if the user chooses +a language other than the one in which you are programming. Block +variables lets you create a variant of script variables for this block: +A script variable is created when a block is called, and it disappears +when that call finishes. What if you want a variable thatā€™s local to +this block, as a script variable is, but doesnā€™t disappear between +invocations? Thatā€™s a block variable. If the definition of a block +includes a block variable, then every time that (custom) block is +dragged from the palette into a script, the block variable is created. +Every time that copy of the block is called, it uses the same block +variable, which preserves its value between calls. Other copies of the +block have their own block variables. The in palette checkbox determines +whether or not this block will be visible in the palette. Itā€™s normally +checked, but you may want to hide custom blocks if youā€™re a curriculum +writer creating a Parsons problem. To unhide blocks, choose ā€œHide +blocksā€ from the File menu and uncheck the checkboxes. Edit does the +same thing as regular clicking, as described earlier.

+ +

Recursion

+ +

{width=ā€285pxā€ +height=ā€227pxā€}{width=ā€188pxā€ +height=ā€226pxā€}{width=ā€137pxā€ +height=ā€88pxā€}Since the new custom block appears in its +palette as soon as you start editing it, you can write recursive +blocks (blocks that call themselves) by dragging the block into its own +definition:

+ +

(If you added inputs to the block since opening the editor, click Apply +before finding the block in the palette, or drag the block from the top +of the block editor rather than from the palette.)

+ +

If recursion is new to you, here are a few brief hints: Itā€™s crucial +that the recursion have a base case, that is, some small(est) case +that the block can handle without using recursion. In this example, itā€™s +the case depth=0, for which the block does nothing at all, because of +the enclosing if. Without a base case, the recursion would run forever, +calling itself over and over.

+ +

Donā€™t try to trace the exact sequence of steps that the computer follows +in a recursive program. Instead, imagine that inside the computer there +are many small people, and if Theresa is drawing a tree of size 100, +depth 6, she hires Tom to make a tree of size 70, depth 5, and later +hires Theo to make another tree of size 70, depthĀ 5. Tom in turn hires +Tammy and Tallulah, and so on. Each little person has his or her own +local variables size and depth, each with different values.

+ +

{width=ā€464pxā€ +height=ā€152pxā€}You can also write recursive reporters, +like this block to compute the factorial function:

+ +

Note the use of the report block. When a reporter block uses this block, +the reporter finishes its work and reports the value given; any further +blocks in the script are not evaluated. Thus, the if else block in the +script above could have been just an if, with the second report block +below it instead of inside it, and the result would be the same, because +when the ļ¬rst report is seen in the base case, that finishes the block +invocation, and the second report is ignored. There is also a stop this +block block that has a similar purpose, ending the block invocation +early, for command blocks. (By contrast, the stop this script block +stops not only the current block invocation, but also the entire +toplevel script that called it.)

+ +

{width=ā€412pxā€ +height=ā€83pxā€}Hereā€™s a slightly more compact way to +write the factorial function:

+ +

For more on recursion, see Thinking Recursively by Eric Roberts. (The +original edition is ISBN 978ā€‘0471816522; a more recent Thinking +Recursively in Java is ISBN 978-0471701460.)

+ +

Block Libraries

+ +

When you save a project (see Chapter II above), any custom blocks youā€™ve +made are saved with it. But sometimes youā€™d like to save a collection of +blocks that you expect to be useful in more than one project. Perhaps +your blocks implement a particular data structure (a stack, or a +dictionary, etc.), or theyā€™re the framework for building a multilevel +game. Such a collection of blocks is called a block library.

+ +

*
+*To create a block library, choose ā€œExport blocksā€¦ā€ from the File +menu. You then see a window like this:

+ +

{width=ā€194pxā€ +height=ā€261pxā€}The window shows all of your global custom +blocks. You can uncheck some of the checkboxes to select exactly which +blocks you want to include in your library. (You can right-click or +control-click on the export window for a menu that lets you check or +uncheck all the boxes at once.) Then press OK. An XML file containing +the blocks will appear in your Downloads location.

+ +

To import a block library, use the ā€œImportā€¦ā€ command in the File menu, +or just drag the XML file into the Snap! window.

+ +

Several block libraries are included with Snap!; for details about +them, see page 25.

+ +

Custom blocks and Visible Stepping

+ +

Visible stepping normally treats a call to a custom block as a single +step. If you want to see stepping inside a custom block you must take +these steps in order:

+ +
    +
  1. +

    {width=ā€28pxā€ +height=ā€16pxā€}Turn on Visible Stepping.

    +
  2. +
  3. +

    Select ā€œEditā€ in the context menu(s) of the block(s) you want to +examine.

    +
  4. +
  5. +

    Then start the program.

    +
  6. +
+ +

The Block Editor windows you open in step 2 do not have full editing +capability. You can tell because there is only one ā€œOKā€ button at the +bottom, not the usual three buttons. Use the button to close these +windows when done stepping.

+ +

First class lists

+ +

A data type is ļ¬rst class in a programming language if data of that +type can be

+ + + +

In Scratch, numbers and text strings are ļ¬rst class. You can put a +number in a variable, use one as the input to a block, call a reporter +that reports a number, or put a number into a list.

+ +

But Scratchā€™s lists are not ļ¬rst class. You create one using the ā€œMake a +listā€ button, which requires that you give the list a name. You canā€™t +put the list into a variable, into an input slot of a block, or into a +list itemā€”you canā€™t have lists of lists. None of the Scratch reporters +reports a list value. (You can use a reduction of the list into a text +string as input to other blocks, but this loses the list structure; the +input is just a text string, not a data aggregate.)

+ +

A fundamental design principle in Snap! is that [all data should be +ļ¬rst class]{.underline}. If itā€™s in the language, then we should be +able to use it fully and freely. We believe that this principle avoids +the need for many special-case tools, which can instead be written by +Snap! users themselves.

+ +

{width=ā€273pxā€ +height=ā€40pxā€}Note that itā€™s a data type thatā€™s ļ¬rst +class, not an individual value. Donā€™t think, for example, that some +lists are ļ¬rst class, while others arenā€™t. In Snap!, lists are ļ¬rst +class, period.

+ +

The list Block

+ +

At the heart of providing first class lists is the ability to make an +ā€œanonymousā€ listā€”to make a list without simultaneously giving it a +name. The list reporter block does that.

+ +

{width=ā€403pxā€ +height=ā€151pxā€}At the right end of the block are two +left-and-right arrowheads. Clicking on these changes the number of +inputs to list, i.e., the number of elements in the list you are +building. Shift-clicking changes by three at a time.

+ +

{width=ā€144pxā€ +height=ā€174pxā€}{width=ā€215pxā€ +height=ā€31pxā€}You can use this block as input to many +other blocks:

+ +

{width=ā€297pxā€ +height=ā€74pxā€}{width=ā€175pxā€ +height=ā€28pxā€}Snap! does not have a ā€œMake a listā€ +button like the one in Scratch. If you want a global ā€œnamed list,ā€ make +a global variable and use the set block to put a list into the variable.

+ +

Lists of Lists

+ +

{width=ā€565pxā€ +height=ā€101pxā€}Lists can be inserted as elements in +larger lists. We can easily create ad hoc structures as needed:

+ +

Notice that this list is presented in a different format from the ā€œShe +Loves Youā€ list above. A two-dimensional list is called a table and is +by default shown in table view. Weā€™ll have more to say about this +later.

+ +

{width=ā€705pxā€ +height=ā€267pxā€}We can also build any classic computer science data +structure out of lists of lists, by defining constructors (blocks to +make an instance of the structure), selectors (blocks to pull out a +piece of the structure), and mutators (blocks to change the contents +of the structure) as needed. Here we create binary trees with selectors +that check for input of the correct data type; only one selector is +shown but the ones for left and right children are analogous.

+ +

Functional and Imperative List Programming

+ +

{width=ā€202pxā€ +height=ā€105pxā€} There are two ways to create a list inside a +program. Scratch users will be familiar with the imperative +programming style, which is based on a set of command blocks that modify +a list:

+ +

As an example, here are two blocks that take a list of numbers as input, +and report a new list containing only the even numbers from the original +list:4

+ +

{width=ā€566pxā€ +height=ā€219pxā€}

+ +

or

+ +

In this script, we first create a temporary variable, then put an empty +list in it, then go through the items of the input list using the add +ā€¦ to (result) block to modify the result list, adding one item at +a time, and finally report the result.

+ +

{width=ā€150pxā€ +height=ā€78pxā€}Functional programming is a different +approach that is becoming important in ā€œreal worldā€ programming because +of parallelism, i.e., the fact that different processors can be +manipulating the same data at the same time. This makes the use of +mutation (changing the value associated with a variable, or the items of +a list) problematic because with parallelism itā€™s impossible to know the +exact sequence of events, so the result of mutation may not be what the +programmer expected. Even without parallelism, though, functional +programming is sometimes a simpler and more effective technique, +especially when dealing with recursively defined data structures. It +uses reporter blocks, not command blocks, to build up a list value:

+ +

In a functional program, we often use recursion to construct a list, one +item at a time. The in front of block makes a list that has one item +added to the front of an existing list, without changing the value of +the original list. A nonempty list is processed by dividing it into its +first item (item 1 of) and all the rest of the items (all but first of), +which are handled through a recursive call:

+ +

{width=ā€456pxā€ +height=ā€215pxā€}Snap! uses two different internal +representations of lists, one (dynamic array) for imperative programming +and the other (linked list) for functional programming. Each +representation makes the corresponding built-in list blocks (commands or +reporters, respectively) most efficient. Itā€™s possible to mix styles in +the same program, but if the same list is used both ways, the program +will run more slowly because it converts from one representation to the +other repeatedly. (The item ( ) of [ ] block doesnā€™t change the +representation.) You donā€™t have to know the details of the internal +representations, but itā€™s worthwhile to use each list in a consistent +way.

+ +

{width=ā€563pxā€ height=ā€103pxā€}Higher Order List Operations and Rings

+ +

Thereā€™s an even easier way to select the even numbers from a list:

+ +

{width=ā€228pxā€ +height=ā€27pxā€}The keep block takes a Predicate +expression as its first input, and a list as its second input. It +reports a list containing those elements of the input list for which the +predicate returns true. Notice two things about the predicate input: +First, it has a grey ring around it. Second, the mod block has an empty +input. Keep puts each item of its input list, one at a time, into that +empty input before evaluating the predicate. (The empty input is +supposed to remind you of the ā€œboxā€ notation for variables in elementary +school: ā˜+3=7.) The grey ring is part of the keep block as it appears in +the palette:

+ +

{width=ā€397pxā€ +height=ā€61pxā€}What the ring means is that this input is +a block (a predicate block, in this case, because the interior of the +ring is a hexagon), rather than the value reported by that block. Hereā€™s +the difference:

+ +

Evaluating the = block without a ring reports true or false; evaluating +the block with a ring reports the block itself. This allows keep to +evaluate the = predicate repeatedly, once for each list item. A block +that takes another block as input is called a higher order block (or +higher order procedure, or higher order function).

+ +

{width=ā€229pxā€ +height=ā€21pxā€}{width=ā€163pxā€ +height=ā€95pxā€} Snap! provides four higher order +function blocks for operating on lists:

+ +

{width=ā€720pxā€ +height=ā€165pxā€}Youā€™ve already seen keep. Find first is +similar, but it reports just the first item that satisfies the +predicate, not a list of all the matching items. Itā€™s equivalent to but +faster because it

+ +

stops looking as soon as it finds a match. If there are no matching +items, it returns an empty string.

+ +

{width=ā€729pxā€ +height=ā€104pxā€}

+ +

{width=ā€719pxā€ +height=ā€96pxā€}These examples use small lists, to fit the +page, but the higher order blocks work for any size list.

+ +

An empty gray ring represents the identity function, which just +reports its input. Leaving the ring in map empty is the most concise way +to make a shallow copy of a list (that is, in the case of a list of +lists, the result is a new toplevel list whose items are the same +(uncopied) lists that are items of the toplevel input list). To make a +deep copy of a list (that is, one in which all the sublists, sublists of +sublists, etc. are copied), use the list as input to the Macintosh
+HD:Users:bh:Desktop:id.png{width=ā€71pxā€ +height=ā€19pxā€} block (one of the variants of the sqrt +of block). This works because id of is a hyperblock (page 55).

+ +

{width=ā€536pxā€ +height=ā€44pxā€}The third higher order block, combine, +computes a single result from all the items of a list, using a +two-input reporter as its second input. In practice, there are only a +few blocks youā€™ll ever use with combine:

+ +

These blocks take the sum of the list items, take their product, string +them into one word, combine them into a sentence (with spaces between +items), see if all items of a list of Booleans are true, see if any of +the items is true, find the smallest, or find the largest.

+ +

{width=ā€603pxā€ +height=ā€36pxā€}{width=ā€371pxā€ +height=ā€33pxā€}Why + but not āˆ’? It only makes sense to +combine list items using an associative function: one that doesnā€™t +care in what order the items are combined (left to right or right to +left). (2+3)+4 = 2+(3+4), but (2āˆ’3)āˆ’4 ā‰  2āˆ’(3āˆ’4).

+ +

{width=ā€558pxā€ +height=ā€114pxā€}The functions map, keep, and find first +have an advanced mode with rarely-used features: If their function input +is given explicit input names (by clicking the arrowhead at the right +end of the gray ring; see page 69), then it will be called for each list +item with three inputs: the itemā€™s value (as usual), the itemā€™s +position in the input list (its index), and the entire input list. No +more than three input names can be used in this contex

+ +

{#section-2 .ListParagraph}

+ +

Table View vs. List View

+ +

{width=ā€298pxā€ +height=ā€241pxā€}We mentioned earlier that there are two +ways of representing lists visually. For one-dimensional lists (lists +whose items are not themselves lists) the visual differences are small:

+ +

For one-dimensional lists, itā€™s not really the appearance thatā€™s +important. What matters is that the list view allows very versatile +direct manipulation of the list through the picture: you can edit the +individual items, you can delete items by clicking the tiny buttons next +to each item, and you can add new items at the end by clicking the tiny +plus sign in the lower left corner. (You can just barely see that the +item deletion buttons have minus signs in them.) Even if you have +several watchers for the same list, all of them will be updated when you +change anything. On the other hand, this versatility comes at an +efficiency cost; a list view watcher for a long list would be way too +slow. As a partial workaround, the list view can only contain 100 items +at a time; the downward-pointing arrowhead opens a menu in which you can +choose which 100 to display.

+ +

{width=ā€121pxā€ +height=ā€88pxā€}

+ +

By contrast, because it doesnā€™t allow direct editing, the table view +watcher can hold hundreds of thousands of items and still scroll through +them efficiently. The table view has flatter graphics for the items to +remind you that theyā€™re not clickable to edit the values.

+ +

Right-clicking on a list watcher (in either form) gives you the option +to switch to the other form. The right-click menu also offers an open in +dialogā€¦ option that opens an offstage table view watcher, because +the watchers can take up a lot of stage space that may make it hard to +see what your program is actually doing. Once the offstage dialog box is +open, you can close the stage watcher. Thereā€™s an OK button on the +offstage dialog to close it if you want. Or you can right-click it to +make another offstage watcher, which is useful if you want to watch +two parts of the list at once by having each watcher scrolled to a +different place.

+ +

{width=ā€565pxā€ +height=ā€101pxā€}Table view is the default if the list has +more than 100 items, or if any of the first ten items of the list are +lists, in which case it makes a very different-looking two-dimensional +picture:

+ +

In this format, the column of red items has been replaced by a +spreadsheet-looking display. For short, wide lists, this display makes +the content of the list very clear. A vertical display, with much of the +space taken up by the ā€œmachineryā€ at the bottom of each sublist, would +make it hard to show all the text at once. (The pedagogic cost is that +the structure is no longer explicit; we canā€™t tell just by looking that +this is a list of row-lists, rather than a list of column-lists or a +primitive two-dimensional array type. But you can choose list view to +see the structure.)

+ +

Beyond such simple cases, in which every item of the main list is a list +of the same length, itā€™s important to keep in mind that the design of +table view has to satisfy two goals, not always in agreement: (1) a +visually compelling display of two-dimensional arrays, and (2) highly +efficient display generation, so that Snap! can handle very large +lists, since ā€œbig dataā€ is an important topic of study. To meet the +first goal perfectly in the case of ā€œragged rightā€ arrays in which +sublists can have different lengths, Snap! would scan the entire list +to find the maximum width before displaying anything, but that would +violate the second goal.

+ +

Snap! uses the simplest possible compromise between the two goals: It +examines only the first ten items of the list to decide on the format. +If none of those are lists, or theyā€™re all lists of one item, and the +overall length is no more than 100, list view is used. If the any of +first ten items is a list, then table view is used, and the number of +columns in the table is equal to the largest number of items among the +first ten items (sublists) of the main list.

+ +

Table views open with standard values for the width and height of a +cell, regardless of the actual data. You can change these values by +dragging the column letters or row numbers. Each column has its own +width, but changing the height of a row changes the height for all rows. +(This distinction is based not on the semantics of rows vs. columns, but +on the fact that a constant row height makes scrolling through a large +list more efficient.) Shift-dragging a column label will change the +width of that column.

+ +

If you tried out the adjustments in the previous paragraph, you may have +noticed that a column letter turns into a number when you hover over it. +Labeling rows and columns differently makes cell references such as +ā€œcell 4Bā€ unambiguous; you donā€™t have to have a convention about whether +to say the row first or the column first. (ā€œCell B4ā€ is the same as +ā€œcell 4B.ā€) On the other hand, to extract a value from column B in your +program, you have to say item 2 of, not item B of. So itā€™s useful to be +able to find out a column number by hovering over its letter.

+ +

{width=ā€366pxā€ +height=ā€78pxā€}Any value that can appear in a program can +be displayed in a table cell:

+ +

{width=ā€416pxā€ +height=ā€202pxā€}This display shows that the standard cell +dimensions may not be enough for large value images. By expanding the +entire speech balloon and then the second column and all the rows, we +can make the result fit:

+ +

{width=ā€321pxā€ +height=ā€55pxā€}But we make an exception for cases in +which the value in a cell is a list (so that the entire table is +three-dimensional). Because lists are visually very big, we donā€™t try to +fit the entire value in a cell:

+ +

Even if you expand the size of the cells, Snap! will not display +sublists of sublists in table view. There are two ways to see these +inner sublists: You can switch to list view, or you can double-click on +a list icon in the table to open a dialog box showing just that +sub-sub-list in table view.

+ +

{width=ā€322pxā€ +height=ā€67pxā€}One last detail: If the first item of a +list is a list (so table view is used), but a later item isnā€™t a list, +that later item will be displayed on a red background, like an item of a +single-column list:

+ +

So, in particular, if only the first item is a list, the display will +look almost like a one-column display.

+ +

Comma-Separated Values

+ +

Spreadsheet and database programs generally offer the option to export +their data as CSV (comma-separated values lists. You can import these +files into Snap! and turn them into tables (lists of lists), and you +can export tables in CSV format. Snap! recognizes a CSV file by the +extension .csv in its filename.

+ +

A CSV file has one line per table row, with the fields separated by +commas within a row:

+ +

{width=ā€480pxā€ +height=ā€257pxā€}John,Lennon,rhythm guitar

+ +

Paul,McCartney,bass guitar

+ +

George,Harrison,lead guitar

+ +

Ringo,Starr,drums

+ +

Hereā€™s what the corresponding table looks like:

+ +

Hereā€™s how to read a spreadsheet into Snap!:

+ +

{width=ā€116pxā€ +height=ā€26pxā€}1. Make a variable with a watcher on +stage:

+ +

2. Right-click on the watcher and choose the ā€œimportā€ option. (If the +variableā€™s value is already a list, be sure to click on the outside +border of the watcher; there is a different menu if you click on the +list itself.) Select the file with your csv data.

+ +

3. There is no 3; thatā€™s it! Snap! will notice that the name of the +file youā€™re importing is something.csv and will turn the text into a +list of lists automatically.

+ +

Or, even easier, just drag and drop the file from your desktop onto the +Snap! window, and Snap! will automatically create a variable named +after the file and import the data into it.

+ +

If you actually want to import the raw CSV data into a variable, either +change the file extension to .txt before loading it, or choose ā€œraw +dataā€ instead of ā€œimportā€ in the watcher menu.

+ +

If you want to export a list, put a variable watcher containing the list +on the stage, right-click its border, and choose ā€œExport.ā€ (Donā€™t +right-click an item instead of the border; that gives a different menu.)

+ +

Multi-dimensional lists and JSON

+ +

CSV format is easy to read, but works only for one- or two-dimensional +lists. If you have a list of lists of lists, Snap! will instead export +your list as a JSON (JavaScript Object Notation) file. I modified my +list:

+ +

{width=ā€608pxā€ +height=ā€43pxā€}and then exported again, getting this +file:

+ +

[["John","Lennon","rhythm +guitar"],[["James","Paul"],"McCartney","bass +guitar"],["George","Harrison","lead +guitar"],["Ringo","Starr","drums"]]

+ +

You can also import lists, including tables, from a .json file. (And you +can import plain text from a .txt file.) Drag and drop works for these +formats also.

+ +

Hyperblocks

+ +

A scalar is anything other than a list. The name comes from +mathematics, where it means a magnitude without direction, as opposed to +a vector, which points toward somewhere. A scalar function is one whose +domain and range are scalars, so all the arithmetic operations are +scalar functions, but so are the text ones such as letter and the +Boolean ones such as not.

+ +

The major new feature in Snap! 6.0 is that the domain and range of +most scalar function blocks is extended to multi-dimensional lists, with +the underlying scalar function applied termwise:

+ +

{width=ā€246pxā€ +height=ā€88pxā€}Macintosh
+HD:Users:bh:Desktop:vector-vector.png{width=ā€321pxā€ +height=ā€88pxā€}

+ +

Macintosh
+HD:Users:bh:Desktop:matrix-matrix.png{width=ā€475pxā€ +height=ā€67pxā€}

+ +

{width=ā€551pxā€ +height=ā€67pxā€}Mathematicians, note in the last example +above that the result is just a termwise application of the underlying +function (7Ɨ3, 8Ɨ5, etc.), not matrix multiplication. See Appendix B +for that. For a dyadic (two-input) function, if the lengths donā€™t agree, +the length of the result (in each dimension) is the length of the +shorter input:

+ +

{width=ā€652pxā€ +height=ā€83pxā€}However, if the number of dimensions +differs in the two inputs, then the number of dimensions in the result +agrees with the higher-dimensional input; the lower-dimensional one is +used repeatedly in the missing dimension(s):

+ +

(7Ɨ6. 8Ɨ10, 1Ɨ20, 40Ɨ6, 20Ɨ10, etc.). In particular, a scalar +input is paired with every scalar in the other input:

+ +

{width=ā€718pxā€ +height=ā€61pxā€}{width=ā€529pxā€ +height=ā€146pxā€}One important motivation for this feature +is how it simplifies and speeds up media computation, as in this +shifting of the Alonzo costume to be bluer:

+ +

{width=ā€162pxā€ +height=ā€101pxā€}{width=ā€499pxā€ +height=ā€101pxā€}Each pixel of the result has Ā¾ of its +original red and green, and three times its original blue (with its +transparency unchanged). By putting some sliders on the stage, you can +play with colors dynamically:

+ +

{width=ā€99pxā€ +height=ā€18pxā€}{width=ā€85pxā€ +height=ā€19pxā€}There are a few naturally scalar functions that have +already had specific meanings when applied to lists and therefore are +not hyperblocks: = and identical to (because they compare entire +structures, not just scalars, always reporting a single Boolean result), +and and or (because they donā€™t evaluate their second input at all if the +first input determines the result), join (because it converts non-scalar +(and other non-text) inputs to text string form), and is a (type) +(because it applies to its input as a whole). Blocks whose inputs are +ā€œnativelyā€ lists, such as and , are never hyperblocks.

+ +

{width=ā€503pxā€ +height=ā€161pxā€}{width=ā€519pxā€ +height=ā€118pxā€}{width=ā€202pxā€ +height=ā€24pxā€}The reshape block takes a list (of any depth) as its +first input, and then takes zero or more sizes along the dimensions of +an array. In the example it will report a table (a matrix) of four rows +and three columns. If no sizes are given, the result is an empty list. +Otherwise, the cells of the specified shape are filled with the atomic +values from the input list. If more values are needed than provided, the +block starts again at the head of the list, using values more than once. +If more values are provided than needed, the extras are ignored; this +isnā€™t an error.

+ +

Icon Description automatically
+generated{width=ā€129pxā€ +height=ā€24pxā€} The item of block has a special set of rules, designed +to preserve its pre-hyperblock meaning and also provide a useful +behavior when given a list as its first (index) input:

+ +
    +
  1. +

    If the index is a number, then item of reports the indicated +top-level item of the list input; that item may be a sublist, in +which case the entire sublist is reported (the original meaning of +item of):Macintosh
+HD:Users:bh:Desktop:item-scalar.png{width=ā€529pxā€ +height=ā€88pxā€}

    +
  2. +
  3. +

    If the index is a list of numbers (no sublists), then item of +reports a list of the indicated top-level items (rows, in a matrix; +a straightforward hyperization): Macintosh
+HD:Users:bh:Desktop:item-vector.png{width=ā€577pxā€ +height=ā€83pxā€}

    +
  4. +
  5. +

    If the index is a list of lists of numbers, then item of reports an +array of only those scalars whose position in the list input matches +the index input in all dimensions (changed in Snap! +6.6!):{width=ā€577pxā€ +height=ā€66pxā€}

    +
  6. +
  7. +

    If a list of list of numbers includes an empty sublist, then all +items are chosen along that +dimension:{width=ā€577pxā€ +height=ā€66pxā€}

    +
  8. +
+ +

{width=ā€634pxā€ +height=ā€101pxā€}To get a column or columns of a +spreadsheet, use an empty list in the row selector (changed in Snap! +6.6!):

+ +

{width=ā€147pxā€ +height=ā€178pxā€}The length of block is extended to provide +various ways of looking at the shape and contents of a list. The options +other than length are mainly useful for lists of lists, to any depth. +These new options work well with hyperblocks and the APL library. +(Examples are on the next page.)

+ +

length: reports the number of (toplevel) items in the list, as always.

+ +

rank: reports the number of dimensions of the list, i.e., the maximum +depth of lists of lists of lists of lists. (That example would be rank +4.)

+ +

dimensions: reports a list of numbers, each of which is the maximum +length in one dimension, so a spreadsheet of 1000 records, each with 4 +fields, would report the list [1000 4].

+ +

flatten: reports a flat, one-dimensional list containing the atomic +(non-list) items anywhere in the input list.

+ +

columns: reports a list in which the rows and columns of the input list +are interchanged, so the shape of the transpose of a shape [1000 4] +list would be [4 1000]. This option works only for lists whose rank is +at most 2. The name reflects the fact that the toplevel items of the +reported table are the columns of the original table.

+ +

reverse: reports a list in which the (toplevel) items of the input list +are in reverse order.

+ +

The remaining three options report a (generally multi-line) text string. +The input list may not include any atomic (non-list) data other than +text or numbers. The lines option is intended for use with rank-one +lists of text strings; it reports a string in which each list item +becomes a line of text. You can think of it as the opposite of the split +by line block. The csv option (comma-separated values) is intended for +rank-two lists that represent a spreadsheet or other tabular data. Each +item of the input list should be a list of atoms; the block reports a +text string in which each item of the big list becomes a line of text in +which the items of that sublist are separated by commas. The json option +is for lists of any rank; it reports a text string in which the list +structure is explicitly represented using square brackets. These are the +opposites of split by csv and split by json.

+ +

{width=ā€610pxā€ +height=ā€646pxā€}

+ +

The idea of extending the domain and range of scalar functions to +include arrays comes from the language APL. (All the great programming +languages are based on mathematical ideas. Our primary ancestors are +Smalltalk, based on models, and Lisp, based on lambda calculus. Prolog, +a great language not (so far) influencing Snap!, is based on logic. +And APL, now joining our family, is based on linear algebra, which +studies vectors and matrices. Those other programming languages are +based on the weaknesses of computer hardware.) Hyperblocks are not the +whole story about APL, which also has mixed-domain functions and higher +order functions. Some of whatā€™s missing is provided in the APL library. +(See Appendix B.)

+ +

Typed Inputs

+ +

Scratchā€™s Type Notation

+ +

{width=ā€132pxā€ +height=ā€20pxā€}Prior to version 3, Scratch block inputs came in two +types: Text-or-number type and Number type. The former is indicated by a +rectangular box, the latter by a rounded box: . A third Scratch type, +Boolean (true/false), can be used in certain Control blocks with +hexagonal slots.

+ +

The Snap! types are an expanded collection including Procedure, List, +and Object types. Note that, with the exception of Procedure types, all +of the input type shapes are just reminders to the user of what the +block expects; they are not enforced by the language.

+ +

{width=ā€248pxā€ height=ā€154pxā€}The Snap! Input Type Dialog

+ +

In the Block Editor input name dialog, there is a right-facing arrowhead +after the ā€œInput nameā€ option:

+ +

Clicking that arrowhead opens the ā€œlongā€ input name dialog:

+ +

{width=ā€496pxā€ +height=ā€397pxā€}{width=ā€19pxā€ +height=ā€19pxā€}There are twelve input type shapes, plus +three mutually exclusive modifiers, listed in addition to the basic +choice between title text and an input name. The default type, the one +you get if you donā€™t choose anything else, is ā€œAny,ā€ meaning that this +input slot is meant to accept any value of any type. If the size input +in your block should be an oval-shaped numeric slot rather than a +generic rectangle, click ā€œNumber.ā€

+ +

{width=ā€655pxā€ +height=ā€265pxā€}The arrangement of the input types is +systematic. As the pictures on this and the next page show, each row of +types is a category, and parts of each column form a category. +Understanding the arrangement will make it a little easier to find the +type you want.

+ +

{width=ā€13pxā€ +height=ā€13pxā€}The second row of input types contains +the ones found in Scratch: Number, Any, and Boolean. (The reason these +are in the second row rather than the ļ¬rst will become clear when we +look at the column arrangement.) The ļ¬rst row contains the new Snap! +types other than procedures: Object, Text, and List. The last two rows +are the types related to procedures, discussed more fully below.

+ +

The List type is used for ļ¬rst class lists, discussed in Chapter IV +above. The red rectangles inside the input slot are meant to resemble +the appearance of lists as Snap! displays them on the stage: each +element in a red rectangle.

+ +

The Object type is for sprites, costumes, sounds, and similar data +types.

+ +

The Text type is really just a variant form of the Any type, using a +shape that suggests a text input.5

+ +

Procedure Types

+ +

Although the procedure types are discussed more fully later, they are +the key to understanding the column arrangement in the input types. Like +Scratch, Snap! has three block shapes: jigsaw-piece for command +blocks, oval for reporters, and hexagonal for predicates. (A predicate +is a reporter that always reports true or false.) In Snap! these +blocks are ļ¬rst class data; an input to a block can be of Command type, +Reporter type, or Predicate type. Each of these types is directly below +the type of value that that kind of block reports, except for Commands, +which donā€™t report a value at all. Thus, oval Reporters are related to +the Any type, while hexagonal Predicates are related to the Boolean +(true or false) type.

+ +

The unevaluated procedure types in the fourth row are explained in +Section VI.E below. In one handwavy sentence, they combine the meaning +of the procedure types with the appearance of the reported value types +two rows higher. (Of course, this isnā€™t quite right for the C-shaped +command input type, since commands donā€™t +{width=ā€350pxā€ +height=ā€299pxā€}report values. But youā€™ll see later that +itā€™s true in spirit.)

+ +

{width=ā€13pxā€ height=ā€13pxā€}Pulldown inputs

+ +

{width=ā€161pxā€ +height=ā€90pxā€}Certain primitive blocks have pulldown +inputs, either read-only, like the input to the touching block:

+ +

{width=ā€183pxā€ +height=ā€127pxā€}(indicated by the input slot being the +same (cyan, in this case) color as the body of the block), or +writeable, like the input to the point in direction block:

+ +

(indicated by the white input slot), which means that the user can type +in an arbitrary input instead of using the pulldown menu.

+ +

{width=ā€80pxā€ +height=ā€63pxā€}{width=ā€13pxā€ +height=ā€13pxā€}Custom blocks can also have such inputs. +To make a pulldown input, open the long form input dialog, choose a text +type (Any, Text, or Number) and click the icon in the bottom right +corner, or control/right-click in the dialog. You will see this menu:

+ +

{width=ā€295pxā€ +height=ā€180pxā€}Click the read-only checkbox if you want a read-only +pulldown input. Then from the same menu, choose optionsā€¦ to get this +dialog box:

+ +

Each line in the text box represents one menu item. If the line does not +contain any of the characters =~{} then the text is both whatā€™s shown +in the menu and the value of the input if that entry is chosen.

+ +

If the line contains an equal sign =, then the text to the left of the +equal sign is shown in the menu, and the text to the right is what +appears in the input slot if that entry is chosen, and is also the value +of the input as seen by the procedure.

+ +

If the line consists of a tilde ~, then it represents a separator (a +horizontal line) in the menu, used to divide long menus into visible +categories. There should be nothing else on the line. This separator is +not choosable, so there is no input value corresponding to it.

+ +

{width=ā€720pxā€ +height=ā€311pxā€}If the line ends with the two characters +equal sign and open brace ={, then it represents a submenu. The text +before the equal sign is a name for the submenu, and will be displayed +in the menu with an arrowhead ā–ŗ at the end of the line. This line is not +clickable, but hovering the mouse over it displays the submenu next to +the original menu. A line containing a close brace } ends the submenu; +nothing else should be on that line. Submenus may be nested to arbitrary +depth.

+ +

###

+ +

Alternatively, instead of giving a menu listing as described above, you +can put a JavaScript function that returns the desired menu in the +textbox. This is an experimental feature and requires that JavaScript be +enabled in the Settings menu.
+It is also possible to get the special menus used in some primitive +blocks, by choosing from the menu submenu: broadcast messages, sprites +and stage, costumes, sounds, variables that can be set in this scope, +the play note piano keyboard, or the point in direction 360Ā° dial. +Finally, you can make the input box accept more than one line of text +(that is, text including a newline character) from the special submenu, +either ā€œmulti-lineā€ for regular +{width=ā€58pxā€ +height=ā€31pxā€}text or ā€œcodeā€ for monospace-font computer +code.

+ +

{width=ā€13pxā€ +height=ā€13pxā€}{width=ā€161pxā€ +height=ā€25pxā€}If the input type is something other than +text, then clicking the button will instead show this menu:

+ +

{width=ā€720pxā€ +height=ā€252pxā€}As an example, we want to make this block: +The second input must be a read-only object menu:

+ +

{width=ā€157pxā€ +height=ā€50pxā€}

+ +

{width=ā€169pxā€ +height=ā€89pxā€}{width=ā€343pxā€ +height=ā€124pxā€}The ā€œMultiple inputsā€ option: The list +block introduced earlier accepts any number of inputs to specify the +items of the new list. To allow this, Snap! introduces the arrowhead +notation () that expands and contracts the block, adding and removing +input slots. (Shift-clicking on an arrowhead adds or removes three input +slots at once.) Custom blocks made by the Snap! user have that +capability, too. If you choose the ā€œMultiple inputsā€ button, then +arrowheads will appear after the input slot in the block. More or fewer +slots (as few as zero) may be used. When the block runs, all of the +values in all of the slots for this input name are collected into a +list, and the value of the input as seen inside the script is that list +of values:

+ +

The ellipsis (ā€¦) in the orange input slot name box in the prototype +indicates a multiple or variadic input.

+ +

The third category, ā€œUpvar - make internal variable visible to caller,ā€ +isnā€™t really an input at all, but rather a sort of output from the block +to its user. It appears as an orange variable oval in the block, rather +than as an input slot. Hereā€™s an example; the uparrow (ā†‘) in the +prototype indicates this kind of internal variable name:

+ +

{width=ā€567pxā€ +height=ā€51pxā€}

+ +

The variable i (in the block on the right above) can be dragged from the +for block into the blocks used in its C-shaped command slot. Also, by +clicking on the orange i, the user can change the name of the variable +as seen in the calling script (although the name hasnā€™t changed inside +the blockā€™s definition). This kind of variable is called an upvar for +short, because it is passed upward from the custom block to the script +that uses it.

+ +

Note about the example: for is a primitive block, but it doesnā€™t need to +be. Youā€™re about to see (next chapter) how it can be written in Snap!. +Just give it a different name to avoid confusion, such as my for as +above.

+ +

Prototype Hints

+ +

We have mentioned three notations that can appear in an input slot in +the prototype to remind you of what kind of input this is. Here is the +complete list of such notations:

+ +

{width=ā€71pxā€ +height=ā€587pxā€}= default value ā€¦ multiple input ā†‘ upvar +# number

+ +

{width=ā€16pxā€ +height=ā€13pxā€}Ī» procedure types ā«¶ list ? Boolean object +Ā¶ multi-line text

+ +

Title Text and Symbols

+ +

{width=ā€117pxā€ +height=ā€23pxā€}Some primitive blocks have symbols as +part of the block name: . Custom blocks can use symbols too. In the +Block Editor, click the plus sign in the prototype at the point where +you want to insert the symbol. Then click the title text picture below +the text box thatā€™s expecting an input slot name. The dialog will then +change to look like this:

+ +

{width=ā€119pxā€ +height=ā€26pxā€}{width=ā€195pxā€ +height=ā€121pxā€}The important part to notice is the +arrowhead that has appeared at the right end of the text box. Click it +to see the menu shown here at the left.

+ +

Choose one of the symbols. The result will have the symbol you want: The +available symbols are, pretty much, the ones that are used in Snap! +icons.

+ +

{width=ā€195pxā€ +height=ā€121pxā€}But Iā€™d like the arrow symbol bigger, and +yellow, so I edit its name:

+ +

{width=ā€115pxā€ +height=ā€26pxā€}This makes the symbol 1.5 times as big as +the letters in the block text, using a color with red-green-blue values +of 255-255-150 (each between 0 and 255). Hereā€™s the result:

+ +

The size and color controls can also be used with text: +$foo-8-255-120-0 will make a huge orange ā€œfoo.ā€

+ +

Note the last entry in the symbol menu: ā€œnew line.ā€ This can be used in +a block with many inputs to control where the text continues on another +line, instead of letting Snap! choose the line break itself.

+ +

Procedures as Data

+ +

Call and Run

+ +

{width=ā€353pxā€ +height=ā€152pxā€}In the for block example above, the input +named action has been declared as type ā€œCommand (C-shaped)ā€; thatā€™s why +the finished block is C-shaped. But how does the block actually tell +Snap! to carry out the commands inside the C-slot? Here is a simple +version of the block script:

+ +

This is simplified because it assumes, without checking, that the ending +value is greater than the starting value; if not, the block should +(depending on the designerā€™s purposes) either not run at all, or change +the variable by āˆ’1 for each repetition instead of by 1.

+ +

{width=ā€48pxā€ +height=ā€15pxā€}The important part of this script is the run block +near the end. This is a Snap! built-in command block that takes a +Command-type value (a script) as its input, and carries out its +instructions. (In this example, the value of the input is the script +that the user puts in the C-slot of the my for block.) There is a +similar call reporter block for invoking a Reporter or Predicate block. +The call and run blocks are at the heart of Snap!ā€™s ļ¬rst class +procedure feature; they allow scripts and blocks to be used as dataā€”in +this example, as an input to a blockā€”and eventually carried out under +control of the userā€™s program.

+ +

{width=ā€678pxā€ +height=ā€159pxā€}Hereā€™s another example, this time using a +Reporter-type input in a map block (see page 50):

+ +

Here we are calling the Reporter ā€œmultiply by 10ā€ three times, once with +each item of the given list as its input, and collecting the results as +a list. (The reported list will always be the same length as the input +list.) Note that the multiplication block has two inputs, but here we +have specified a particular value for one of them (10), so the call +block knows to use the input value given to it just to fill the other +(empty) input slot in the multiplication block. In the my map +definition, the input function is declared to be type Reporter, and data +is of type List.

+ +

Call/Run with inputs

+ +

{width=ā€174pxā€ +height=ā€20pxā€}The call block (like the run block) has a +right arrowhead at the end; clicking on it adds the phrase ā€œwith inputsā€ +and then a slot into which an input can be inserted:

+ +

If the left arrowhead is used to remove the last input slot, the ā€œwith +inputsā€ disappears also. The right arrowhead can be clicked as many +times as needed for the number of inputs required by the reporter block +being called.

+ +

{width=ā€262pxā€ +height=ā€31pxā€}If the number of inputs given to call +(not counting the Reporter-type input that comes first) is the same as +the number of empty input slots, then the empty slots are filled from +left to right with the given input values. If call is given exactly one +input, then every empty input slot of the called block is filled with +the same value:

+ +

If the number of inputs provided is neither one nor the number of empty +slots, then there is no automatic filling of empty slots. (Instead you +must use explicit parameters in the ring, as discussed in Section C +below.)

+ +

{width=ā€671pxā€ +height=ā€67pxā€}An even more important thing to notice +about these examples is the ring around the Reporter-type input slots +in call and map above. This notation indicates that the block itself, +not the number or other value that the block would report when called, +is the input. If you want to use a block itself in a non-Reporter-type +(e.g., Any-type) input slot, you can enclose it explicitly in a ring, +found at the top of the Operators palette.

+ +

As a shortcut, if you right-click or control-click on a block (such as +the + block in this example), one of the choices in the menu that +appears is ā€œringifyā€ and/or ā€œunringify.ā€ The ring indicating a +Reporter-type or Predicate-type input slot is essentially the same idea +for reporters as the C-shaped input slot with which youā€™re already +familiar; with a C-shaped slot, itā€™s the script you put in the slot +that becomes the input to the C-shaped block.

+ +

There are three ring shapes. All are oval on the outside, indicating +that the ring reports a value, the block or script inside it, but the +inside shapes are command, reporter, or predicate, indicating what kind +of block or script is expected. Sometimes you want to put something more +complicated than a single reporter inside a reporter ring; if so, you +can use a script, but the script must report a value, as in a custom +reporter definition.

+ +

Variables in Ring Slots

+ +

Note that the run block in the definition of the my for block (page 65) +doesnā€™t have a ring around its input variable action. When you drag a +variable into a ringed input slot, you generally do want to use the +value of the variable, which will be the block or script youā€™re trying +to run or call, rather than the orange variable reporter itself. So +Snap! automatically removes the ring in this case. If you ever do want +to use the variable block itself, rather than the value of the +variable, as a Procedure-type input, you can drag the variable into the +input slot, then control-click or right-click it and choose ā€œringifyā€ +from the menu that appears. (Similarly, if you ever want to call a +function that will report a block to use as the input, such as item 1 of +applied to a list of blocks, you can choose ā€œunringifyā€ from the menu. +Almost all the time, though, Snap! does what you mean without help.)

+ +

Writing Higher Order Procedures

+ +

A higher order procedure is one that takes another procedure as an +input, or that reports a procedure. In this document, the word +ā€œprocedureā€ encompasses scripts, individual blocks, and nested +reporters. (Unless specified otherwise, ā€œreporterā€ includes predicates. +When the word is capitalized inside a sentence, it means specifically +oval-shaped blocks. So, ā€œnested reportersā€ includes predicates, but ā€œa +Reporter-type inputā€ doesnā€™t.)

+ +

Although an Any-type input slot (what you get if you use the small +input-name dialog box) will accept a procedure input, it doesnā€™t +automatically ring the input as described above. So the declaration of +Procedure-type inputs makes the use of your custom higher order block +much more convenient.

+ +

{width=ā€228pxā€ +height=ā€130pxā€}Why would you want a block to take a +procedure as input? This is actually not an obscure thing to do; the +primitive conditional and looping blocks (the C-shaped ones in the +Control palette) take a script as input. Users just donā€™t usually think +about it in those terms! We could write the repeat block as a custom +block this way, if Snap! didnā€™t already have one:

+ +

The lambda (Ī») next to action in the prototype indicates that this is a +C-shaped block, and that the script enclosed by the C when the block is +used is the input named action in the body of the script. The only way +to make sense of the variable action is to understand that its value is +a script.

+ +

{width=ā€248pxā€ +height=ā€154pxā€}To declare an input to be Procedure-type, +open the input name dialog as usual, and click on the arrowhead:

+ +

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

+ +

{width=ā€19pxā€ +height=ā€19pxā€}{width=ā€351pxā€ +height=ā€264pxā€}
+Why would you ever choose an inline Command slot rather than a C shape? +Other than the run block +{width=ā€203pxā€ +height=ā€45pxā€}discussed below, the only case I can think of is +something like the C/C++/Java for loop, which actually has three +command script inputs (and one predicate input), only one of which is +the ā€œfeaturedā€ loop body:

+ +

Okay, now that we have procedures as inputs to our blocks, how do we use +them? We use the blocks run (for commands) and call (for reporters). The +run blockā€™s script input is an inline ring, not C-shaped, because we +anticipate that it will be rare to use a specific, literal script as the +input. Instead, the input will generally be a variable whose value is +a script.

+ +

The run and call blocks have arrowheads at the end that can be used to +open slots for inputs to the called procedures. How does Snap! know +where to use those inputs? If the called procedure (block or script) has +empty input slots, Snap! ā€œdoes the right thing.ā€ This has several +possible meanings:

+ +

{width=ā€331pxā€ +height=ā€33pxā€}1. If the number of empty slots is +exactly equal to the number of inputs provided, then Snap! fills the +empty slots from left to right:

+ +

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

+ +

{width=ā€269pxā€ +height=ā€29pxā€}

+ +

3. Otherwise, Snap! wonā€™t fill any slots, because the userā€™s intention +is unclear.

+ +

If the user wants to override these rules, the solution is to use a ring +with explicit input names that can be put into the given block or script +to indicate how inputs are to be used. This will be discussed more fully +below.

+ +

Recursive Calls to Multiple-Input Blocks

+ +

A relatively rare situation not yet considered here is the case of a +recursive block that has a variable number of inputs. Letā€™s say the user +of your project calls your block with five inputs one time, and 87 +inputs another time. How do you write the recursive call to your block +when you donā€™t know how many inputs to give it? The answer is that you +collect the inputs in a list (recall that, when you declare an input +name to represent a variable number of inputs, your block sees those +inputs as a list of values in the first place), and then, in the +recursive call, you drop that input list onto the arrowheads that +indicate a variable-input slot, rather than onto the input slot:

+ +

{width=ā€13pxā€ +height=ā€13pxā€}{width=ā€240pxā€ +height=ā€187pxā€}{width=ā€214pxā€ +height=ā€112pxā€}{width=ā€218pxā€ +height=ā€153pxā€}
+Note that the halo you see while dragging onto the arrowheads is red +instead of white, and covers the input slot as well as the arrowheads. +And when you drop the expression onto the arrowheads, the words ā€œinput +list:ā€ are added to the block text and the arrowheads disappear (in this +invocation only) to remind you that the list represents all of the +multiple inputs, not just a single input. The items in the list are +taken individually as inputs to the script. Since numbers is a list of +numbers, each individual item is a number, just what sizes wants. This +{width=ā€654pxā€ +height=ā€164pxā€}block will take any number of numbers as +inputs, and will make the sprite grow and shrink accordingly:

+ +

{width=ā€284pxā€ +height=ā€66pxā€}The user of this block calls it with any number of +individual numbers as inputs. But inside the definition of the block, +all of those numbers form a list that has a single input name, +numbers. This recursive definition ļ¬rst checks to make sure there are +any inputs at all. If so, it processes the ļ¬rst input (item 1 of the +list), then it wants to make a recursive call with all but the ļ¬rst +number. But sizes doesnā€™t take a list as input; it takes numbers as +inputs! So this would be wrong:

+ +

Formal Parameters

+ +

{width=ā€338pxā€ +height=ā€100pxā€}The rings around Procedure-type inputs +have an arrowhead at the right. Clicking the arrowhead allows you to +give the inputs to a block or script explicit names, instead of using +empty input slots as weā€™ve done until now.

+ +

The names #1, #2, etc. are provided by default, but you can change a +name by clicking on its orange oval in the input names list. Be careful +not to drag the oval when clicking; thatā€™s how you use the input +inside the ring. The names of the input variables are called the formal +parameters of the encapsulated procedure.

+ +

{width=ā€415pxā€ +height=ā€44pxā€}Hereā€™s a simple but contrived example +using explicit names to control which input goes where inside the ring:

+ +

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

+ +

{width=ā€449pxā€ +height=ā€290pxā€}Here is a more realistic, much more +advanced example:

+ +

{width=ā€417pxā€ +height=ā€135pxā€}

+ +

This is the definition of a block that takes any number of lists, and +reports the list of all possible combinations of one item from each +list. The important part for this discussion is that near the bottom +there are two nested calls to map, the higher order function that +applies an input function to each item of an input list. In the inner +block, the function being mapped is in front of, and that block takes +two inputs. The second, the empty List-type slot, will get its value in +each call from an item of the inner mapā€™s list input. But there is no +way for the outer map to communicate values to empty slots of the in +front of block. We must give an explicit name, newitem, to the value +that the outer map is giving to the inner one, then drag that variable +into the in front of block.

+ +

By the way, once the called block provides names for its inputs, Snap! +will not automatically fill empty slots, on the theory that the user has +taken control. In fact, thatā€™s another reason you might want to name the +inputs explicitly: to stop Snap! from filling a slot that should +really remain empty.

+ +

Procedures as Data

+ +

{width=ā€498pxā€ +height=ā€159pxā€}Hereā€™s an example of a situation in which a procedure +must be explicitly marked as data by pulling a ring from the Operators +palette and putting the procedure (block or script) inside it:

+ +

Here, we are making a list of procedures. But the list block accepts +inputs of any type, so its input slots are not ringed. We must say +explicitly that we want the block itself as the input, rather than +whatever value would result from evaluating the block.

+ +

{width=ā€368pxā€ +height=ā€81pxā€}Besides the list block in the example above, other +blocks into which you may want to put procedures are set (to set the +value of a variable to a procedure), say and think (to display a +procedure to the user), and report (for a reporter that reports a +procedure):

+ +

Special Forms

+ +

{width=ā€240pxā€ +height=ā€27pxā€}{width=ā€231pxā€ +height=ā€137pxā€}The primitive if else block has two +C-shaped command slots and chooses one or the other depending on a +Boolean test. Because Scratch doesnā€™t emphasize functional programming, +it lacks a corresponding reporter block to choose between two +expressions. Snap! has one, but we could write our own:

+ +

{width=ā€412pxā€ +height=ā€81pxā€}{width=ā€367pxā€ +height=ā€26pxā€}Our block works for these simple +examples, but if we try to use it in writing a recursive operator, itā€™ll +fail:

+ +

The problem is that when any block is called, all of its inputs are +computed (evaluated) before the block itself runs. The block itself +knows only the values of its inputs, not what expressions were used to +compute them. In particular, all of the inputs to our if then else block +are evaluated ļ¬rst thing. That means that even in the base case, +factorial will try to call itself recursively, causing an infinite loop. +We need our if then else block to be able to select only one of the two +alternatives to be evaluated.

+ +

We have a mechanism to allow that: declare the then and else inputs to +be of type Reporter rather than type Any. Then, when calling the block, +those inputs will be enclosed in a ring so that the expressions +themselves, rather than their values, become the inputs:

+ +

{width=ā€107pxā€ +height=ā€67pxā€}{width=ā€434pxā€ +height=ā€98pxā€}{width=ā€251pxā€ +height=ā€145pxā€}

+ +

In this version, the program works, with no infinite loop. But weā€™ve +paid a heavy price: this reporter-if is no longer as intuitively obvious +as the Scratch command-if. You have to know about procedures as data, +about rings, and about a trick to get a constant value in a ringed slot. +(The id block implements the identity function, which reports its +input.6 We need it because rings take only reporters as input, not +numbers.) What weā€™d like is a reporter-if that behaves like this one, +delaying the evaluation of its inputs, but looks like our ļ¬rst +version, which was easy to use except that it didnā€™t work.

+ +

Such blocks are indeed possible. A block that seems to take a simple +expression as input, but delays the evaluation of that input by wrapping +an ā€œinvisible ringā€ around it (and, if necessary, an id-like +transformation of constant data into constant functions) is called a +special form. To turn our if block into a special form, we edit the +blockā€™s prototype, declaring the inputs yes and no to be of type ā€œAny +(unevaluated)ā€ instead of type Reporter. The script for the block is +still that of the second version, including the use of call to evaluate +either yes or no but not both. But the slots appear as white Any-type +rectangles, not Reporter-type rings, and the factorial block will look +like our ļ¬rst attempt.

+ +

In a special formā€™s prototype, the unevaluated input slot(s) are +indicated by a lambda (Ī») next to the input name, just as if they were +declared as Procedure type. They are Procedure type, really; theyā€™re +just disguised to the user of the block.

+ +

Special forms trade off implementor sophistication for user +sophistication. That is, you have to understand all about procedures as +data to make sense of the special form implementation of my if then +else. But any experienced Scratch programmer can use my if then else +without thinking at all about how it works internally.

+ +

Special Forms in Scratch

+ +

Special forms are actually not a new invention in Snap!. Many of +Scratchā€™s conditional and looping blocks are really special forms. The +hexagonal input slot in the if block is a straightforward Boolean value, +because the value can be computed once, before the if block makes its +decision about whether or not to run its action input. But the forever +if, repeat until, and wait until blocksā€™ inputs canā€™t be Booleans; they +have to be of type ā€œBoolean (unevaluated),ā€ so that Scratch can evaluate +them over and over again. Since Scratch doesnā€™t have custom Cā€‘shaped +blocks, it can afford to handwave away the distinction between evaluated +and unevaluated Booleans, but Snap! canā€™t. The pedagogic value of +special forms is proven by the fact that no Scratcher ever notices that +thereā€™s anything strange about the way in which the hexagonal inputs in +the Control blocks are evaluated.

+ +

Also, the C-shaped slot familiar to Scratch users is an unevaluated +procedure type; you donā€™t have to use a ring to keep the commands in the +C-slot from being run before the C-shaped block is run. Those commands +themselves, not the result of running them, are the input to the +C-shaped Control block. (This is taken for granted by Scratch users, +especially because Scratchers donā€™t think of the contents of a C-slot as +an input at all.) This is why it makes sense that ā€œCā€‘shapedā€ is on the +fourth row of types in the long form input dialog, with other +unevaluated types.

+ +

Object Oriented Programming with Sprites

+ +

Object oriented programming is a style based around the abstraction +object: a collection of data and methods (procedures, which from +our point of view are just more data) that you interact 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. Our approach +is therefore less restrictive than that of some other OOP languages; we +give objects easy access to each othersā€™ data and methods.

+ +

Technically, object oriented programming rests on three legs: (1) +Message passing: There is a notation by which any object can send a +message to another object. (2) Local state: Each object can remember +the important past history of the computation it has performed. +(ā€œImportantā€ means that it need not remember every message it has +handled, but only the lasting effects of those messages that will affect +later computation.) (3) Inheritance: It would be impractical if each +individual object had to contain methods, many of them identical to +those of other objects, for all of the messages it can accept. Instead, +we need a way to say that this new object is just like that old object +except for a few differences, so that only those differences need be +programmed explicitly.

+ +

First Class Sprites

+ +

Like Scratch, Snap! comes with things that are natural objects: its +sprites. Each sprite can own local variables; each sprite has its own +scripts (methods). A Scratch animation is plainly a simulation of the +interaction of characters in a play. There are two ways in which Scratch +sprites are less versatile than the objects of an OOP language. First, +Scratch message passing is weak in three respects: Messages can only be +broadcast, not addressed to an individual sprite; messages canā€™t take +inputs; and methods canā€™t return values to their caller. Second, and +more basic, in the OOP paradigm objects are data; they can be the +value of a variable, an element of a list, and so on, but thatā€™s not the +case for Scratch sprites.

+ +

Snap! sprites are ļ¬rst class data. They can be created and deleted by +a script, stored in a variable or list, and sent messages individually. +The children of a sprite can inherit sprite-local variables, methods +(sprite-local procedures), and other attributes (e.g., x position).

+ +

{width=ā€93pxā€ +height=ā€19pxā€}{width=ā€104pxā€ +height=ā€19pxā€}{width=ā€64pxā€ +height=ā€19pxā€}The fundamental means by which programs +get access to sprites is the my reporter block. It has a dropdown-menu +input slot that, when clicked, gives access to all the sprites, plus the +stage. reports a single sprite, the one asking the question. reports a +list of all sprites other than the one asking the question. reports a +list of all sprites that are near the one askingā€”the ones that are +candidates for having collided with this one, for example. The my block +has many other options, discussed below. If you know the name of a +particular sprite, the object reporter will report the sprite itself.

+ +

{width=ā€341pxā€ +height=ā€49pxā€}{width=ā€258pxā€ +height=ā€120pxā€}An object or list of objects reported by my or object +can be used as input to any block that accepts any input type, such as +setā€™s second input. If you say an object, the resulting speech balloon +will contain a smaller image of the objectā€™s costume or (for the stage) +background.

+ +

Permanent and Temporary Clones

+ +

{width=ā€145pxā€ +height=ā€19pxā€}The block is used to create and report an +instance (a clone) of any sprite. (There is also a command version, for +historical reasons.) There are two different kinds of situations in +which clones are used. One is that youā€™ve made an example sprite and, +when you start the project, you want a fairly large number of +essentially identical sprites that behave like the example. (Hereafter +weā€™ll call the example sprite the ā€œparentā€ and the others the +ā€œchildren.ā€) Once the game or animation is over, you donā€™t need the +copies any more. (As weā€™ll see, ā€œcopiesā€ is the wrong word because the +parent and the children share a lot of properties. Thatā€™s why we use +the word ā€œclonesā€ to describe the children rather than ā€œcopies.ā€) These +are temporary clones. They are automatically deleted when the user +presses either the green flag or the red stop sign. In Scratch 2.0 and +later, all clones are temporary.

+ +

The other kind of situation is what happens when you want +specializations of sprites. For example, letā€™s say you have a sprite +named Dog. It has certain behaviors, such as running up to a person who +comes near it. Now you decide that the family in your story really likes +dogs, so they adopt a lot of them. Some are cocker spaniels, who wag +their tails when they see you. Others are rottweilers, who growl at you +when they see you. So you make a clone of Dog, perhaps rename it Cocker +Spaniel, and give it a new costume and a script for what to do when +someone gets near. You make another clone of Dog, perhaps rename it +Rottweiler, and give it a new costume, etc. Then you make three clones +of Cocker Spaniel (so there are four altogether) and two clones of +Rottweiler. Maybe you hide the Dog sprite after all this, since itā€™s no +breed in particular. Each dog has its own position, special behaviors, +and so on. You want to save all of these dogs in the project. These are +permanent clones. In BYOB 3.1, the predecessor to Snap!, all clones +are permanent.

+ +

{width=ā€145pxā€ +height=ā€19pxā€}One advantage of temporary clones is that +they donā€™t slow down Snap! even when you have a lot of them. (If +youā€™re curious, one reason is that permanent clones appear in the sprite +corral, where their pictures have to be updated to reflect the cloneā€™s +current costume, direction, and so on.) We have tried to anticipate your +needs, as follows: When you make a clone in a script, using the block, +it is ā€œbornā€ temporary. But when you make a clone from the user +interface, for example by right-clicking on a sprite and choosing +ā€œclone,ā€ it is born permanent. The reason this makes sense is that you +donā€™t create 100 kinds of dogs automatically. Each kind has many +different characteristics, programmed by hand. But when your project is +running, it might create 100 rottweilers, and those will be identical +unless you change them in the program.

+ +

{width=ā€145pxā€ +height=ā€25pxā€}You can change a temporary sprite to +permanent by right-clicking it and choosing ā€œedit.ā€ (Itā€™s called ā€œeditā€ +rather than, say, ā€œpermanentā€ because it also shifts the scripting area +to reflect that sprite, as if youā€™d pressed its button in the sprite +corral.) You can change a permanent sprite to temporary by +right-clicking it and choosing ā€œrelease.ā€ You can also change the status +of a clone in your program with with true or false as the second input.

+ +

Sending Messages to Sprites

+ +

The messages that a sprite accepts are the blocks in its palettes, +including both all-sprites and this-sprite-only blocks. (For custom +blocks, the corresponding methods are the scripts as seen in the Block +Editor.

+ +

{width=ā€547pxā€ +height=ā€35pxā€}The way to send a message to a sprite (or +the stage) is with the tell block (for command messages) or the ask +block (for reporter messages).

+ +

{width=ā€599pxā€ +height=ā€77pxā€}A small point to note in the examples +above: all dropdown menus include an empty entry at the top, which can +be selected for use in higher order procedures like the for each and map +examples. Each of the sprites in my neighbors or my other sprites is +used to fill the blank space in turn.

+ +

{width=ā€496pxā€ +height=ā€27pxā€}By the way, if you want a list of all +the sprites, including this sprite, you can use either of these:

+ +

{width=ā€340pxā€ +height=ā€79pxā€}Tell and ask wait until the other sprite +has carried out its method before this spriteā€™s script continues. (That +has to be the case for ask, since we want to do something with the value +it reports.) So tell is analogous to broadcast and wait. Sometimes the +other spriteā€™s method may take a long time, or may even be a forever +loop, so you want the originating script to continue without waiting. +For this purpose we have the launch block:

+ +

Launch is analogous to broadcast without the ā€œwait.ā€

+ +

Snap! 4.1, following BYOB 3.1, used an extension of the of block to +provide access to other spritesā€™ methods. That interface was designed +back when we were trying hard to avoid adding new primitive blocks; it +allowed us to write ask and tell as tool procedures in Snap! itself. +That technique still works, but is deprecated, because nobody understood +it, and now we have the more straightforward primitives.

+ +

Polymorphism

+ +

{width=ā€161pxā€ +height=ā€135pxā€}Suppose you have a Dog sprite with two +clones CockerSpaniel and PitBull. In the Dog sprite you define this +method (ā€œFor this sprite onlyā€ block):

+ +

Note the location (map-pin) symbol before the blockā€™s name. The symbol +is not part of the block title; itā€™s a visual reminder that this is a +sprite-local block. Sprite-local variables are similarly marked.

+ +

But you donā€™t define greet as friend or greet as enemy in Dog. Each kind +of dog has a different behavior. Hereā€™s what a CockerSpaniel does:

+ +

{width=ā€389pxā€ +height=ā€71pxā€}{width=ā€391pxā€ +height=ā€67pxā€}And hereā€™s what a PitBull does:

+ +

Greet is defined in the Dog sprite. If Fido is a particular cocker +spaniel, and you ask Fido to greet someone, Fido inherits the greet +method from Dog, but Dog itself couldnā€™t actually run that method, +because Dog doesnā€™t have greet as friend or greet as enemy. And perhaps +only individual dogs such as Fido have friend? methods. Even though the +greet method is defined in the Dog sprite, when itā€™s running it +remembers what specific dog sprite called it, so it knows which greet as +friend to use. Dogā€™s greet block is called a polymorphic method, +because it means different things to different dogs, even though they +all share the same script.

+ +

Local State in Sprites: Variables and Attributes

+ +

A spriteā€™s memory of its own past history takes two main forms. It has +variables, created explicitly by the user with the ā€œMake a variableā€ +button; it also has attributes, the qualities every sprite has +automatically, such as position, direction, and pen color. Each variable +can be examined using its own orange oval block; there is one set block +to modify all variables. Attributes, however, have a less uniform +programming interface in Scratch:

+ + + +

The block, if any, that examines a variable or attribute is called its +getter; a block (there may be more than one, as in the direction +example above) that modifies a variable or attribute is called a +setter.

+ +

{width=ā€215pxā€ +height=ā€200pxā€}In Snap! we allow virtually all +attributes to be examined. But instead of adding dozens of reporters, we +use a more uniform interface for attributes: The my blockā€™s menu (in +Sensing; see page 78) includes many of the attributes of a sprite. It +serves as a general getter for those attributes, e.g., my [anchor] to +find the sprite, if any, to which this sprite is attached in a nesting +arrangement (see page 10). Similarly, the same set block used to set +variable values allows setting some sprite attributes.

+ +

Prototyping: Parents and Children

+ +

Most current OOP languages use a class/instance approach to creating +objects. A class is a particular kind of object, and an instance is an +actual object of that type. For example, there might be a Dog class, +and several instances Fido, Spot, and Runt. The class typically +specifies the methods shared by all dogs (RollOver, SitUpAndBeg, Fetch, +and so on), and the instances contain data such as species, color, and +friendliness. Snap! uses a different approach called prototyping, in +which there is no distinction between classes and instances. Prototyping +is better suited to an experimental, tinkering style of work: You make a +single dog sprite, with both methods (blocks) and data (variables); you +can actually watch it and interact with it on the stage; and when you +like it, you use it as the prototype from which to clone other dogs. If +you later discover a bug in the behavior of dogs, you can edit a method +in the parent, and all of the children will automatically share the new +version of the method block. Experienced class/instance programmers may +find prototyping strange at first, but it is actually a more expressive +system, because you can easily simulate a class/instance hierarchy by +hiding the prototype sprite! Prototyping is also a better fit with the +Scratch design principle that everything in a project should be concrete +and visible on the stage; in class/instance OOP the programming process +begins with an abstract, invisible entity, the class, that must be +designed before any concrete objects can be made.7

+ +

{width=ā€720pxā€ +height=ā€151pxā€}There are three ways to make a child +sprite. If you control-click or right-click on a sprite in the ā€œsprite +corralā€ at the bottom right corner of the window, you get a menu that +includes ā€œcloneā€ as one of the choices. There is an a new clone of block +in the Control palette that creates and reports a child sprite. And +sprites have a ā€œparentā€ attribute that can be set, like any attribute, +thereby changing the parent of an existing sprite.

+ +

Inheritance by Delegation

+ +

A clone inherits properties of its parent. ā€œPropertiesā€ include +scripts, custom blocks, variables, named lists, system attributes, +costumes, and sounds. Each individual property can be shared between +parent and child, or not shared (with a separate one in the child). The +getter block for a shared property, in the childā€™s palette, is displayed +in a lighter color; separate properties of the child are displayed in +the traditional colors.

+ +
+

When a new clone is created, by default it shares only its methods, +wardrobe, and jukebox with its parent. All other properties are copied +to the clone, but not shared. (One exception is that a new permanent +clone is given a random position. Another is that temporary clones +share the scripts in their parentā€™s scripting area. A third is that +sprite-local variables that the parent creates after cloning are +shared with its children.) If the value of a shared property is +changed in the parent, then the children see the new value. If the +value of a shared property is changed in the child, then the sharing +link is broken, and a new private version is created in that child. +(This is the mechanism by which a child chooses not to share a +property with its parent.) ā€œChangedā€ in this context means using the +set or change block for a variable, editing a block in the Block +Editor, editing a costume or sound, or inserting, deleting, or +reordering costumes or sounds. To change a property from unshared to +shared, the child uses the inherit command block. The pulldown menu in +the block lists all the things this sprite can inherit from its parent +(which might be nothing, if this sprite has no parent) and is not +already inheriting. But that would prevent telling a child to inherit, +so if the inherit block is inside a ring, its pulldown menu includes +all the things a child could inherit from this sprite. Right-clicking +on the scripting area of a permanent clone gives a menu option to +share the entire collection of scripts from its parent, as a temporary +clone does.

+
+ +

The rules are full of details, but the basic idea is simple: Parents can +change their children, but children canā€™t directly change their parents. +Thatā€™s what youā€™d expect from the word ā€œinheritā€: the influence just +goes in one direction. When a child changes some property, itā€™s +declaring independence from its parent (with respect to that one +property). What if you really want the child to be able to make a change +in the parent (and therefore in itself and all its siblings)? Remember +that in this system any object can tell any other object to do +something:

+ +

{width=ā€487pxā€ +height=ā€56pxā€}When a sprite gets a message for which it +doesnā€™t have a corresponding block, the message is delegated to that +spriteā€™s parent. When a sprite does have the corresponding block, then +the message is not delegated. If the script that implements a delegated +message refers to my (self), it means the child to which the message was +originally sent, not the parent to which the message was delegated.

+ +

{width=ā€76pxā€ height=ā€333pxā€}List of attributes

+ +

{width=ā€114pxā€ +height=ā€24pxā€}{width=ā€113pxā€ +height=ā€587pxā€}At the right is a picture of the dropdown +menu of attributes in the my block.

+ +

Several of these are not real attributes, but things related to +attributes:

+ + + +

The others are individual attributes:

+ + + +
+

bounding box, rounded oļ¬€ā€“the geometric center of the costume.

+
+ +

First Class Costumes and Sounds

+ +

Costumes and sounds donā€™t have methods, as sprites do; you canā€™t ask +them to do things. But they are first class: you can make a list of +them, put them in variables, use them as input to a procedure, and so +on. My [costumes] and my [sounds] report lists of them.

+ +

Media Computation with Costumes

+ +

{width=ā€157pxā€ +height=ā€18pxā€}The components of a costume are its name, width, +height, and pixels. The block gives access to these components using its +left menu. From its right menu you can choose the current costume, the +Turtle costume, or any costume in the spriteā€™s wardrobe. Since costumes +are first class, you can also drop an expression whose value is a +costume, or a list of costumes, on that second input slot. (Due to a +misfeature, even though you can select Turtle in the right menu, the +block reports 0 for its width and height, and an empty string for the +other components.) The costumeā€™s width and height are in its standard +orientation, regardless of the spriteā€™s current direction. (This is +different from the spriteā€™s width and height, reported by the my +block.)

+ +

But the really interesting part of a costume is its bitmap, a list of +pixels. (A pixel, short for ā€œpicture element,ā€ represents one dot on +your display.) Each pixel is itself a list of four items, the red, +green, and blue components of its color (in the range 0-255) and what is +standardly called its ā€œtransparencyā€ but should be called its opacity, +also in the range 0-255, in which 0 means that the pixel is invisible +and 255 means that itā€™s fully opaque: you canā€™t see anything from a +rearward layer at that point on the stage. (Costume pixels typically +have an opacity of 0 only for points inside the bounding box of the +costume but not actually part of the costume; points in the interior of +a costume typically have an opacity of 255. Intermediate values appear +mainly at the edge of a costume, or at sharp boundaries between colors +inside the costume, where they are used to reduce ā€œjaggiesā€: the +stairstep-like shape of a diagonal line displayed on an array of +discrete rectangular screen coordinates. Note that the opacity of a +sprite pixel is determined by combining the costumeā€™s opacity with the +spriteā€™s ghost effect. (The latter really is a measure of transparency: +0 means opaque and 100 means invisible.)

+ +

{width=ā€586pxā€ +height=ā€133pxā€}The bitmap is a one-dimensional list of +pixels, not an array of height rows of width pixels each. Thatā€™s why +the pixel list has to be combined with the dimensions to produce a +costume. This choice partly reflects the way bitmaps are stored in the +computerā€™s hardware and operating system, but also makes it easy to +produce transformations of a costume with map:

+ +

In this simplest possible transformation, the red value of all the +pixels have been changed to a constant 150. Colors that were red in the +original (such as the logo printed on the t-shirt) become closer to +black (the other color components being near zero); the blue jeans +become purple (blue plus red); perhaps counterintuitively, the white +t-shirt, which has the maximum value for all three color components, +loses some of its red and becomes cyan, the color opposite red on the +color wheel. In reading the code, note that the function that is the +first input to map is applied to a single pixel, whose first item is its +red component. Also note that this process works only on bitmap +costumes; if you call pixels of on a vector costume (one with ā€œsvgā€ in +the corner of its picture), it will be converted to pixels first.

+ +

{width=ā€217pxā€ +height=ā€27pxā€}One important point to see here is that a +bitmap (list of pixels) is not, by itself, a costume. The new costume +block creates a costume by combining a bitmap, a width, and a height. +But, as in the example above, switch to costume will accept a bitmap as +input and will automatically use the width and height of the current +costume. Note that thereā€™s no name input; costumes computed in this way +are all named costume. Note also that the use of switch to costume does +not add the computed costume to the spriteā€™s wardrobe; to do that, say

+ +

{width=ā€721pxā€ +height=ā€116pxā€}Hereā€™s a more interesting example of color +manipulation:

+ +

{width=ā€438pxā€ +height=ā€39pxā€}Each color value is constrained to be 0, +80, 160, or 240. This gives the picture a more cartoonish look. +Alternatively, you can do the computation taking advantage of +hyperblocks:

+ +

Hereā€™s one way to exchange red and green values:

+ +

{width=ā€720pxā€ +height=ā€63pxā€}{width=ā€92pxā€ +height=ā€17pxā€}Itā€™s the list that determines the +rearrangement of colors: greenāž”red, redāž”green, and the other two +unchanged. That list is inside another list because otherwise it would +be selecting rows of the pixel array, and we want to select columns. +We use pixels of costume current rather than costume apple because the +latter is always a red apple, so this little program would get stuck +turning it green, instead of alternating colors.

+ +

{width=ā€535pxā€ +height=ā€41pxā€}{width=ā€165pxā€ +height=ā€22pxā€}The stretch block takes a costume as its +first input, either by selecting a costume from the menu or by dropping +a costume-valued expression such as onto it. The other two inputs are +percents of the original width and height, as advertised, so you can +make fun house mirror versions of costumes:

+ +

The resulting costumes can be used with switch to costume and so on.

+ +

{width=ā€512pxā€ +height=ā€34pxā€}Finally, you can use pictures from your +computerā€™s camera in your projects using these blocks:

+ +

{width=ā€141pxā€ +height=ā€23pxā€}Using the video on block turns on the +camera and displays what it sees on the stage, regardless of the inputs +given. The camera remains on until you click the red stop button, your +program runs the stop all block, or you turn it off explicitly with the +block. The video image on the stage is partly ghosted, to an extent +determined by the set video transparency block, whose input really is +transparency and not opacity. (Small numbers make the video more +visible.) By default, the video image is mirrored, like the selfie +camera on your cell phone: When you raise your left hand, your image +raises its right hand. You can control this +{width=ā€135pxā€ +height=ā€23pxā€}mirroring with the block.

+ +

{width=ā€116pxā€ +height=ā€155pxā€}The video snap on block then takes a still picture +from the camera, and trims it to fit on the selected sprite. (Video snap +on stage means to use the entire stage-sized rectangle.) For example, +hereā€™s a camera snapshot trimmed to fit Alonzo:

+ +

{width=ā€256pxā€ +height=ā€125pxā€}The ā€œVideo Captureā€ project in the +Examples collection repeatedly takes such trimmed snapshots and has the +Alonzo sprite use the current snapshot as its costume, so it looks like +this:

+ +

{width=ā€256pxā€ +height=ā€192pxā€}{width=ā€320pxā€ +height=ā€240pxā€}(The picture above was actually taken with transparency +set to 50, to make the background more visible for printing.) Because +the sprite is always still in the place where the snapshot was taken, +its costume exactly fits in with the rest of the full-stage video. If +you were to add a move 100 steps block after the switch to costume, +youā€™d see something like this:

+ +

This time, the spriteā€™s costume was captured at one position, and then +the sprite is shown at a different position. (You probably wouldnā€™t want +to do this, but perhaps itā€™s helpful for explanatory purposes.)

+ +

{width=ā€708pxā€ +height=ā€158pxā€}What you would want to do is push the +sprite around the stage:

+ +

{width=ā€297pxā€ +height=ā€185pxā€}(Really these should be Jensā€™s picture; +itā€™s his project. But heā€™s vacationing. ā˜ŗ) Video motion compares two +snapshots a moment apart, looking only at the part within the given trim +(here myself, meaning the current sprite, not the person looking into +the camera), to detect a difference between them. It reports a number, +measuring the number of pixels through which some part of the picture +has moved. Video direction also compares two snapshots to detect motion, +but what it reports is the direction (in the point in direction sense) +of the motion. So the script above moves the sprite in the direction in +which itā€™s being pushed, but only if a significant amount of motion is +found; otherwise the sprite would jiggle around too much. And yes, you +can run the second script without the first to push a balloon around the +stage.

+ +

Media Computation with Sounds {#media-computation-with-sounds .ListParagraph}

+ +

The starting point for computation with sound is the microphone block. +It starts by recording a brief burst of sound from your microphone. (How +brief? On my computer, 0.010667 seconds, but youā€™ll see shortly how to +ļ¬nd out or control the sample size on your computer.)

+ +

{width=ā€189pxā€ +height=ā€25pxā€}{width=ā€576pxā€ +height=ā€252pxā€}Just as the pixel is the smallest piece +of a picture, the sample is the smallest piece of a sound. It says +here: that on my computer, 48,000 samples are recorded per second, so +each sample is 1/48,000 of a second. The value of a sample is between -1 +and 1, and represents the sound pressure on the microphoneā€”how hard +the air is pushingā€”at that instant. (You can skip the next page or so +if you know about Fourier analysis.) Hereā€™s a picture of 400 samples:

+ +

In this graph, the x axis represents the time at which each sample was +measured; the y axis measures the value of the sample at that time. +The first obvious thing about this graph is that it has a lot of ups and +downs. The most basic up-and-down function is the sine wave:

+ +

Every periodic function (more or less, any sample that sounds like music +rather than sounding like static) is composed of a sum of sine waves of +different frequencies.

+ +

Look back at the graph of our sampled sound. There is a green dot every +seven samples. Thereā€™s nothing magic about the number seven; I tried +different values until I found one that looked right. What ā€œrightā€ means +is that, for the first few dots at least, they coincide almost perfectly +with the high points and low points of the graph. Near the middle +(horizontally) of the graph, the green dots donā€™t seem anywhere near the +high and low points, but if you find the very lowest point of the graph, +about 2/3 of the way along, the dots start lining up almost perfectly +again.

+ +

The red graph above shows two cycles of a sine wave. One cycle goes +up, then down, then up again. The amount of time taken for one cycle is +the period of the sine function. If the green dots match both ups and +downs in the captured sound, then two dotsā€”14 samples, or 14/48000 of +a secondā€”represent the period. The first cycle and a half of the graph +looks like it could be a pure sine wave, but after that, the tops and +bottoms donā€™t line up, and there are peculiar little jiggles, such as +the one before the fifth green dot. This happens because sine waves of +different periods are added together.

+ +

It turns out to be more useful to measure the reciprocal of the period, +in our case, 48000/14 or about 3429 cycles per second. Another name +for ā€œcycles per secondā€ is ā€œHertz,ā€ abbreviated Hz, so our sound has a +component at 3249 Hz. As a musical note, thatā€™s about an A (a little +flat), four octaves above middle C. (Donā€™t worry too much about the note +being a little off; remember that the 14-sample period was just +eyeballed and is unlikely to be exactly right.)

+ +

Four octaves above middle C is really high! That would be a +shrill-sounding note. But remember that a complex waveform is the sum of +multiple sine waves at different frequency. Hereā€™s a different +up-and-down regularity:

+ +

{width=ā€268pxā€ +height=ā€117pxā€}{width=ā€267pxā€ +height=ā€101pxā€}Itā€™s not obvious, but in the left part of +the graph, the signal is more above the x axis than below it. Toward +the right, it seems to be more below than above the axis. At the very +right it looks like it might be climbing again.

+ +

The period of the red sine wave is 340 samples, or 340/48000 second. +Thatā€™s a frequency of about 141 Hz, about D below middle C. Again, this +is measuring by eyeball, but likely to be close to the right frequency.

+ +

All this eyeballing doesnā€™t seem very scientific. Canā€™t we just get the +computer to find all the relevant frequencies? Yes, we can, using a +mathematical technique called Fourier analysis. (Jean-Baptiste Joseph +Fourier, 1768ā€“1830, made many contributions to mathematics and physics, +but is best known for working out the nature of periodic functions as a +sum of sine waves.) Luckily we donā€™t have to do the math; the microphone +block will do it for us, if we ask for microphone spectrum:

+ +

{width=ā€719pxā€ +height=ā€143pxā€}These are frequency spectra from (samples +of) three different songs. The most obvious thing about these graphs is +that their overall slope is downward; the loudest frequency is the +lowest frequency. Thatā€™s typical of music.

+ +

The next thing to notice is that thereā€™s a regularity in the spacing of +spikes in the graph. This is partly just an artifact; the frequency +(horizontal) axis isnā€™t continuous. There are a finite number of +ā€œbucketsā€ (default: 512), and all the frequencies within a bucket +contribute to the amplitude (vertical axis) of that bucket. The spectrum +is a list of that many amplitudes. But the patterns of alternating +rising and falling values are real; the frequencies that are multiples +of the main note being sampled will have higher amplitude than other +frequencies.

+ +

Samples and spectrum are the two most detailed representations of a +sound. But the microphone block has other, simpler options also:

+ +

volume the instantaneous volume when the block is called

+ +

note the MIDI note number (as in play note) of the main note heard

+ +

frequency the frequency in Hz of the main note heard

+ +

sample rate the number of samples being collected per second

+ +

{width=ā€280pxā€ +height=ā€27pxā€}resolution the size of the array in which data are +collected (typically 512, must be a power of 2)

+ +

The block for sounds that corresponds to new picture for pictures is

+ +

Its first input is a list of samples, and its second input specifies how +many samples occupy one second.

+ +

OOP with Procedures

+ +

The idea of object oriented programming is often taught in a way that +makes it seem as if a special object oriented programming language is +necessary. In fact, any language with ļ¬rst class procedures and lexical +scope allows objects to be implemented explicitly; this is a useful +exercise to help demystify objects.

+ +

The central idea of this implementation is that an object is represented +as a dispatch procedure that takes a message as input and reports the +corresponding method. In this section we start with a stripped-down +example to show how local state works, and build up to full +implementations of class/instance and prototyping OOP.

+ +

Local State with Script Variables

+ +

{width=ā€333pxā€ +height=ā€305pxā€}{width=ā€215pxā€ +height=ā€145pxā€}This script implements an object class, +a type of object, namely the counter class. In this ļ¬rst simplified +version there is only one method, so no explicit message passing is +necessary. When the make a counter block is called, it reports a +procedure, the ringed script inside its body. That procedure implements +a specific counter object, an instance of the counter class. When +invoked, a counter instance increases and reports its count variable. +Each counter has its own local count:

+ +

This example will repay careful study, because it isnā€™t obvious why each +instance has a separate count. From the point of view of the make a +counter procedure, each invocation causes a new count variable to be +created. Usually such script variables are temporary, going out of +existence when the script ends. But this one is special, because make a +counter returns another script that makes reference to the count +variable, so it remains active. (The script variables block makes +variables local to a script. It can be used in a spriteā€™s script area or +in the Block Editor. Script variables can be ā€œexportedā€ by being used in +a reported procedure, as here.)

+ +

In this approach to OOP, we are representing both classes and instances +as procedures. The make a counter block represents the class, while each +instance is represented by a nameless script created each time make a +counter is called. The script variables created inside the make a +counter block but outside the ring are instance variables, belonging +to a particular counter.

+ +

Messages and Dispatch Procedures

+ +

{width=ā€424pxā€ +height=ā€304pxā€}In the simplified class above, there is +only one method, and so there are no messages; you just call the +instance to carry out its one method. Here is a more refined version +that uses message passing:

+ +

Again, the make a counter block represents the counter class, and again +the script creates a local variable count each time it is invoked. The +large outer ring represents an instance. It is a dispatch procedure: +it takes a message (just a text word) as input, and it reports a method. +The two smaller rings are the methods. The top one is the next method; +the bottom one is the reset method. The latter requires an input, named +value.

+ +

In the earlier version, calling the instance did the entire job. In this +version, calling the instance gives access to a method, which must then +be called to finish the job. We can provide a block to do both procedure +calls in one:

+ +

{width=ā€385pxā€ +height=ā€68pxā€}

+ +

The ask block has two required inputs: an object and a message. It also +accepts optional additional inputs, which Snap! puts in a list; that +list is named args inside the block. Ask has two nested call blocks. The +inner one calls the object, i.e., the dispatch procedure. The dispatch +procedure always takes exactly one input, namely the message. It reports +a method, which may take any number of inputs; note that this is the +situation in which we drop a list of values onto the arrowheads of a +multiple input (in the outer call block). Note also that this is one of +the rare cases in which we must unringify the inner call block, whose +value when called gives the method.

+ +

{width=ā€375pxā€ +height=ā€155pxā€}

+ +

Inheritance via Delegation

+ +

So, our objects now have local state variables and message passing. What +about inheritance? We can provide that capability using the technique of +delegation. Each instance of the child class contains an instance of +the parent class, and simply passes on the messages it doesnā€™t want to +specialize:

+ +

{width=ā€366pxā€ +height=ā€344pxā€}

+ +

This script implements the buzzer class, which is a child of counter. +Instead of having a count (a number) as a local state variable, each +buzzer has a counter (an object) as a local state variable. The class +specializes the next method, reporting what the counter reports unless +that result is divisible by 7, in which case it reports ā€œbuzz.ā€ (Yeah, +it should also check for a digit 7 in the number, but this code is +complicated enough already.) If the message is anything other than next, +though, such as reset, then the buzzer simply invokes its counterā€™s +dispatch procedure. So the counter handles any message that the buzzer +doesnā€™t handle explicitly. (Note that in the non-next case we call the +counter, not ask it something, because we want to report a method, not +the value that the message reports.) So, if we ask a buzzer to reset to +a value divisible by 7, it will end up reporting that number, not +ā€œbuzz.ā€

+ +

An Implementation of Prototyping OOP

+ +

In the class/instance system above, it is necessary to design the +complete behavior of a class before you can make any instances of the +class. This is okay for top-down design, but not great for +experimentation. Here we sketch the implementation of a prototyping +OOP system: You make an object, tinker with it, make clones of it, and +keep tinkering. Any changes you make in the parent are inherited by its +children. In effect, that first object is both the class and an instance +of the class. In the implementation below, children share properties +(methods and local variables) of their parent unless and until a child +changes a property, at which point that child gets a private copy. (If a +child wants to change something for its entire family, it must ask the +parent to do it.)

+ +

Because we want to be able to create and delete properties dynamically, +we wonā€™t use Snap! variables to hold an objectā€™s variables or methods. +Instead, each object has two tables, called methods and data, each of +which is an association list: a list of two-item lists, in which each +of the latter contains a key and a corresponding value. We provide a +lookup procedure to locate the key-value pair corresponding to a given +key in a given table.

+ +

{width=ā€309pxā€ +height=ā€227pxā€}

+ +

{width=ā€252pxā€ +height=ā€75pxā€}

+ +

{width=ā€538pxā€ +height=ā€111pxā€}{width=ā€538pxā€ +height=ā€111pxā€}

+ +

There are also commands to insert and delete entries:

+ +

{width=ā€357pxā€ +height=ā€175pxā€}{width=ā€310pxā€ +height=ā€204pxā€}

+ +

As in the class/instance version, an object is represented as a dispatch +procedure that takes a message as its input and reports the +corresponding method. When an object gets a message, it will ļ¬rst look +for that keyword in its methods table. If itā€™s found, the corresponding +value is the method we want. If not, the object looks in its data table. +If a value is found there, what the object returns is not that value, +but rather a reporter method that, when called, will report the value. +This means that what an object returns is always a method.

+ +

If the object has neither a method nor a datum with the desired name, +but it does have a parent, then the parent (that is, the parentā€™s +dispatch procedure) is invoked with the message as its input. +Eventually, either a match is found, or an object with no parent is +found; the latter case is an error, meaning that the user has sent the +object a message not in its repertoire.

+ +

Messages can take any number of inputs, as in the class/instance system, +but in the prototyping version, every method automatically gets the +object to which the message was originally sent as an extra ļ¬rst input. +We must do this so that if a method is found in the parent (or +grandparent, etc.) of the original recipient, and that method refers to +a variable or method, it will use the childā€™s variable or method if the +child has its own version.

+ +

{width=ā€420pxā€ +height=ā€717pxā€}The clone of block below takes an object as +its input and makes a child object. It should be considered as an +internal part of the implementation; the preferred way to make a child +of an object is to send that object a clone message.

+ +

{width=ā€151pxā€ +height=ā€66pxā€}Every object is created with predefined methods for +set, method, delete-var, delete-method, and clone. It has one predefined +variable, parent. Objects without a parent are created by calling new +object:

+ +

As before, we provide procedures to call an objectā€™s dispatch procedure +and then call the method. But in this version, we provide the desired +object as the ļ¬rst method input. We provide one procedure for Command +methods and one for Reporter methods:

+ +

{width=ā€666pxā€ +height=ā€96pxā€}(Remember that the ā€œInput list:ā€ variant of the run and +call blocks is made by dragging the input expression over the arrowheads +rather than over the input slot.)

+ +

The script below demonstrates how this prototyping system can be used to +make counters. We start with one prototype counter, called counter1. We +count this counter up a few times, then create a child counter2 and give +it its own count variable, but not its own total variable. The next +method always sets counter1ā€™s total variable, which therefore keeps +count of the total number of times that any counter is incremented. +Running this script should [say] and (think) the following lists:

+ +

{width=ā€404pxā€ +height=ā€422pxā€}[1 1] [2 2] [3 3] [4 4] (1 5) (2 6) +(3 7) [5 8] [6 9] [7 10] [8 11]

+ +

The Outside World

+ +

{width=ā€156pxā€ +height=ā€24pxā€}The facilities discussed so far are fine for projects +that take place entirely on your computerā€™s screen. But you may want to +write programs that interact with physical devices (sensors or robots) +or with the World Wide Web. For these purposes Snap! provides a single +primitive block:

+ +

This might not seem like enough, but in fact it can be used to build the +desired capabilities.

+ +

The World Wide Web

+ +

The input to the url block is the URL (Uniform Resource Locator) of a +web page. The block reports the body of the Web serverā€™s response (minus +HTTP header), without interpretation. This means that in most cases +the response is a description of the page in HTML (HyperText Markup +Language) notation. Often, especially for commercial web sites, the +actual information youā€™re trying to find on the page is actually at +another URL included in the reported HTML. The Web page is typically a +very long text string, and so the primitive split block is useful to get +the text in a manageable form, namely, as a list of lines:

+ +

{width=ā€626pxā€ +height=ā€411pxā€}

+ +

The second input to split is the character to be used to separate the +text string into a list of lines, or one of a set of common cases (such +as line, which separates on carriage return and/or newline characters.

+ +

This might be a good place for a reminder that list-view watchers scroll +through only 100 items at a time. The downarrow near the bottom right +corner of the speech balloon in the picture presents a menu of +hundred-item ranges. (This may seem unnecessary, since the scroll bar +should allow for any number of items, but doing it this way makes +Snap! much faster.) In table view, the entire list is included.

+ +

If you include a protocol name in the input to the url block (such as +http:// or https://), that protocol will be used. If not, the block +first tries HTTPS and then, if that fails, HTTP.

+ +

A security restriction in JavaScript limits the ability of one web site +to initiate communication with another site. There is an official +workaround for this limitation called the CORS protocol (Cross-Origin +Resource Sharing), but the target site has to allow snap.berkeley.edu +explicitly, and of course most donā€™t. To get around this problem, you +can use third-party sites (ā€œcors proxiesā€) that are not limited by +JavaScript and that forward your requests.

+ +

Hardware Devices

+ +

Another JavaScript security restriction prevents Snap! from having +direct access to devices connected to your computer, such as sensors and +robots. (Mobile devices such as smartphones may also have useful devices +built in, such as accelerometers and GPS receivers.) The url block is +also used to interface Snap! with these external capabilities.

+ +

The idea is that you run a separate program that both interfaces with +the device and provides a local HTTP server that Snap! can use to make +requests to the device. Unlike Snap! itself, these programs have +access to anything on your computer, so you have to trust the author of +the software! Our web site, snap.berkeley.edu, provides links to +drivers for several devices, including, at this writing, the Lego NXT, +Finch, Hummingbird, and Parallax S2 robots; the Nintendo Wiimote and +Leap Motion sensors, the Arduino microcomputer, and Super-Awesome +Sylviaā€™s Water Color Bot. The same server technique can be used for +access to third party software libraries, such as the speech synthesis +package linked on our web site.

+ +

Most of these packages require some expertise to install; the links are +to source code repositories. This situation will improve with time.

+ +

Date and Time

+ +

{width=ā€509pxā€ +height=ā€31pxā€}The current block in the Sensing palette +can be used to find out the current date or time. Each call to this +block reports one component of the date or time, so you will probably +combine several calls, like this:

+ +

{width=ā€509pxā€ +height=ā€31pxā€}for Americans, or like this:

+ +

for Europeans.

+ +

Continuations

+ +

Blocks are usually used within a script. The continuation of a block +within a particular script is the part of the computation that remains +to be completed after the block does its job. A continuation can be +represented as a ringed script. Continuations are always part of the +interpretation of any program in any language, but usually these +continuations are implicit in the data structures of the language +interpreter or compiler. Making continuations explicit is an advanced +but versatile programming technique that allows users to create control +structures such as nonlocal exit and multithreading.

+ +

{width=ā€135pxā€ +height=ā€148pxā€}In the simplest case, the continuation of +a command block may just be the part of the script after the block. For +example, in the script

+ +

{width=ā€153pxā€ +height=ā€68pxā€}the continuation of the move 100 steps +block is

+ +

{width=ā€142pxā€ +height=ā€77pxā€}But some situations are more complicated. +For example, what is the continuation of move 100 steps in the following +script?

+ +

{width=ā€160pxā€ +height=ā€103pxā€}Thatā€™s a trick question; the move block is +run four times, and it has a different continuation each time. The first +time, its continuation is

+ +

Note that there is no repeat 3 block in the actual script, but the +continuation has to represent the fact that there are three more times +through the loop to go. The fourth time, the continuation is just

+ +

{width=ā€153pxā€ +height=ā€29pxā€}What counts is not whatā€™s physically +below the block in the script, but what computational work remains to be +done.

+ +

(This is a situation in which visible code may be a little misleading. +We have to put a repeat 3 block in the picture of the continuation, +but the actual continuation is made from the evaluatorā€™s internal +bookkeeping of where itā€™s up to in a script. So itā€™s really the original +script plus some extra information. But the pictures here do correctly +represent what work the process still has left to do.)
+{width=ā€142pxā€ +height=ā€120pxā€}When a block is used inside a custom block, its +continuation may include parts of more than one script. For example, if +we make a custom square block

+ +

and then use that block in a script:

+ +

{width=ā€70pxā€ +height=ā€57pxā€}then the continuation of the first use of move 100 +steps is

+ +

{width=ā€160pxā€ +height=ā€121pxā€}in which part comes from inside the square +block and part comes from the call to square. Nevertheless, ordinarily +when we display a continuation we show only the part within the +current script.

+ +

{width=ā€210pxā€ +height=ā€55pxā€}The continuation of a command block, as +weā€™ve seen, is a simple script with no input slots. But the continuation +of a reporter block has to do something with the value reported by the +block, so it takes that value as input. For example, in the script

+ +

the continuation of the 3+4 block is

+ +

{width=ā€343pxā€ +height=ā€55pxā€}Of course the name result in that picture +is arbitrary; any name could be used, or no name at all by using the +empty-slot notation for input substitution.

+ +

Continuation Passing Style

+ +

Like all programming languages, Snap! evaluates compositions of nested +reporters from the inside out. For example, in the expression +{width=ā€126pxā€ +height=ā€22pxā€}Snap! first adds 4 and 5, then +multiplies 3 by that sum. This often means that the order in which the +operations are done is backwards from the order in which they appear in +the expression: When reading the above expression you say ā€œtimesā€ before +you say ā€œplus.ā€ In English, instead of saying ā€œthree times four plus +five,ā€ which actually makes the order of operations ambiguous, you could +say, ā€œtake the sum of four and five, and then take the product of three +and that sum.ā€ This sounds more awkward, but it has the virtue of +putting the operations in the order in which theyā€™re actually performed.

+ +

{width=ā€306pxā€ +height=ā€34pxā€}That may seem like overkill in a simple +expression, but suppose youā€™re trying to convey the expression

+ +

to a friend over the phone. If you say ā€œfactorial of three times +factorial of two plus two plus fiveā€ you might mean any of these:

+ +

{width=ā€306pxā€ +height=ā€165pxā€}{width=ā€719pxā€ +height=ā€348pxā€}Wouldnā€™t it be better to say, ā€œAdd two and +two, take the factorial of that, add five to that, multiply three by +that, and take the factorial of the resultā€? We can do a similar +reordering of an expression if we first define versions of all the +reporters that take their continuation as an explicit input. In the +following picture, notice that the new blocks are commands, not +reporters.

+ +

{width=ā€389pxā€ +height=ā€157pxā€}We can check that these blocks give the +results we want:

+ +

{width=ā€531pxā€ +height=ā€223pxā€}The original expression can now be +represented as

+ +

{width=ā€211pxā€ +height=ā€101pxā€}If you read this top to bottom, donā€™t you +get ā€œAdd two and two, take the factorial of that, add five to that, +multiply three by that, and take the factorial of the resultā€? Just what +we wanted! This way of working, in which every block is a command that +takes a continuation as one of its inputs, is called +continuation-passing style (CPS). Okay, it looks horrible, but it has +subtle virtues. One of them is that each script is just one block long +(with the rest of the work buried in the continuation given to that one +block), so each block doesnā€™t have to remember what else to doā€”in the +vocabulary of this section, the (implicit) continuation of each block is +empty. Instead of the usual picture of recursion, with a bunch of little +people all waiting for each other, with CPS what happens is that each +little person hands off the problem to the next one and goes to the +beach, so thereā€™s only one active little person at a time. In this +example, we start with Alfred, an add specialist, who computes the value +4 and then hands off the rest of the problem to Francine, a factorial +specialist. She computes the value 24, then hands the problem off to +Anne, another add specialist, who computes 29. And so on, until finally +Sam, a say specialist, says the value 2.107757298379527Ɨ10^132^, which +is a very large number!

+ +

Go back to the definitions of these blocks. The ones, such as add, that +correspond to primitive reporters are simple; they just call the +reporter and then call their continuation with its result. But the +definition of factorial is more interesting. It doesnā€™t just call our +original factorial reporter and send the result to its continuation. CPS +is used inside factorial too! It says, ā€œSee if my input is zero. Send +the (true or false) result to if. If the result is true, then call my +continuation with the value 1. Otherwise, subtract 1 from my input. Send +the result of that to factorial, with a continuation that multiplies the +smaller numberā€™s factorial by my original input. Finally, call my +continuation with the product.ā€ You can use CPS to unwind even the most +complicated branched recursions.

+ +

By the way, I cheated a bit above. The if/else block should also use +CPS; it should take one true/false input and two continuations. It +will go to one or the other continuation depending on the value of its +input. But in fact the C-shaped blocks (or E-shaped, like if/else) are +really using CPS in the first place, because they implicitly wrap rings +around the sub-scripts within their branches. See if you can make an +explicitly CPS if/else block.

+ +

Call/Run w/Continuation

+ +

To use explicit continuation passing style, we had to define special +versions of all the reporters, add and so on. Snap! provides a +primitive mechanism for capturing continuations when we need to, without +using continuation passing throughout a project.

+ +

Hereā€™s the classic example. We want to write a recursive block that +takes a list of numbers as input, and reports the product of all the +numbers:

+ +

{width=ā€374pxā€ +height=ā€186pxā€}{width=ā€374pxā€ +height=ā€129pxā€}But we can improve the efficiency of this +block, in the case of a list that includes a zero; as soon as we see the +zero, we know that the entire product is zero.

+ +

But this is not as efficient as it might seem. Consider, as an example, +the list 1,2,3,0,4,5. We find the zero on the third recursive call (the +fourth call altogether), as the first item of the sublist 0,4,5. What is +the continuation of the report 0 block? Itā€™s

+ +

{width=ā€416pxā€ +height=ā€40pxā€}Even though we already know that result is +zero, weā€™re going to do three unnecessary multiplications while +unwinding the recursive calls.

+ +

{width=ā€388pxā€ +height=ā€185pxā€}{width=ā€379pxā€ +height=ā€105pxā€}We can improve upon this by capturing the +continuation of the top-level call to product:

+ +

{width=ā€260pxā€ +height=ā€28pxā€}The +{width=ā€153pxā€ +height=ā€18pxā€} block takes as its input a one-input +script, as shown in the product example. It calls that script with the +continuation of the call-with-continuation block itself as its input. +In this case, that continuation is

+ +

{width=ā€423pxā€ +height=ā€111pxā€}reporting to whichever script called product. If the +input list doesnā€™t include a zero, then nothing is ever done with that +continuation, and this version works just like the original product. But +if the input list is 1,2,3,0,4,5, then three recursive calls are made, +the zero is seen, and product-helper runs the continuation, with an +input of 0. The continuation immediately reports that 0 to the caller of +product, without unwinding all the recursive calls and without the +unnecessary multiplications.

+ +

{width=ā€421pxā€ +height=ā€49pxā€}I could have written product a little more +simply using a Reporter ring instead of a Command ring:

+ +

but itā€™s customary to use a script to represent the input to +callĀ w/continuation because very often that input takes the form

+ +

so that the continuation is saved permanently and can be called from +anywhere in the project. Thatā€™s why the input slot in call +w/continuation has a Command ring rather than a Reporter ring.

+ +

First class continuations are an experimental feature in Snap! and +there are many known limitations in it. One is that the display of +reporter continuations shows only the single block in which the call +w/continuation is an input.

+ +

Nonlocal exit

+ +

{width=ā€602pxā€ +height=ā€108pxā€}Many programming languages have a break command that +can be used inside a looping construct such as repeat to end the +repetition early. Using first class continuations, we can generalize +this mechanism to allow nonlocal exit even within a block called from +inside a loop, or through several levels of nested loops:

+ +

{width=ā€178pxā€ +height=ā€255pxā€}The upvar break has as its value a +continuation that can be called from anywhere in the program to jump +immediately to whatever comes after the catch block in its script. +Hereā€™s an example with two nested invocations of catch, with the upvar +renamed in the outer one:

+ +

As shown, this will say 1, then 2, then 3, then exit both nested catches +and think ā€œHmm.ā€ If in the run block the variable break is used instead +of outer, then the script will say 1, 2, 3, and ā€œHello!ā€ before thinking +ā€œHmm.ā€

+ +

{width=ā€418pxā€ +height=ā€141pxā€}There are corresponding catch and throw +blocks for reporters. The catch block is a reporter that takes an +expression as input instead of a C-shaped slot. But the throw block is a +command; it doesnā€™t report a value to its own continuation, but instead +reports a value (which it takes as an additional input, in addition to +the catch tag) to the corresponding catch blockā€™s continuation:

+ +

Without the throw, the inner call reports 5, the + block reports 8, so +the catch block reports 8, and the Ɨ block reports 80. With the throw, +the inner call doesnā€™t report at all, and neither does the + block. The +throw blockā€™s input of 20 becomes the value reported by the catch block, +and the Ɨ block multiplies 10 and 20.
+Creating a Thread System

+ +

Snap! can be running several scripts at once, within a single sprite +and across many sprites. If you only have one computer, how can it do +many things at once? The answer is that only one is actually running at +any moment, but Snap! switches its attention from one script to +another frequently. At the bottom of every looping block (repeat, repeat +until, forever), there is an implicit ā€œyieldā€ command, which remembers +where the current script is up to, and switches to some other script, +each in turn. At the end of every script is an implicit ā€œend threadā€ +command (a thread is the technical term for the process of running a +script), which switches to another script without remembering the old +one.

+ +

{width=ā€283pxā€ +height=ā€408pxā€}{width=ā€629pxā€ +height=ā€266pxā€}Since this all happens automatically, there +is generally no need for the user to think about threads. But, just to +show that this, too, is not magic, here is an implementation of a simple +thread system. It uses a global variable named tasks that initially +contains an empty list. Each use of the C-shaped thread block adds a +continuation (the ringed script) to the list. The yield block uses run +w/continuation to create a continuation for a partly done thread, adds +it to the task list, and then runs the first waiting task. The +endĀ thread block (which is automatically added at the end of every +threadā€™s script by the thread block) just runs the next waiting task.

+ +

Here is a sample script using the thread system. One thread says +numbers; the other says letters. The number thread yields after every +prime number, while the letter thread yields after every vowel. So the +sequence of speech balloons is +1,2,a,3,b,c,d,e,4,5,f,g,h,i,6,7,j,k,l,m,n,o,8,9,10,11, +p,q,r,s,t,u,12,13,v,w,x,y,z,14,15,16,17,18,ā€¦30.

+ +

If we wanted this to behave exactly like Snap!ā€™s own threads, weā€™d +define new versions of repeat and so on that run yield after each +repetition.

+ +

Metaprogramming

+ +

The scripts and custom blocks that make up a program can be examined or +created by the program itself.

+ +

{width=ā€719pxā€ height=ā€196pxā€}Reading a block

+ +

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.

+ +

{width=ā€710pxā€ +height=ā€241pxā€}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.

+ +

{width=ā€720pxā€ +height=ā€200pxā€}Using split by blocks to select custom +blocks whose definitions contain another block gives us this debugging +aid:

+ +

Note in passing the my blocks block, which reports a list of all visible +blocks, primitive and custom. (Thereā€™s also a my categories block, which +reports a list of the names of the palette categories.) Also note +custom? of block, which reports True if its input is a custom block.

+ +

Writing a block

+ +

{width=ā€583pxā€ +height=ā€212pxā€}The inverse function to split by blocks is +provided by the join block, which when given a syntax tree as input +reports the corresponding expression or script.

+ +

Here we are taking the definition of square, modifying the repetition +count (to 6), modifying the turning angle (to 60), using join to turn +the result back into a ringed definition, and using the define block to +create a new hexagon block.

+ +

The define block has three ā€œinputā€ slots. The quotation marks are there +because the first slot is an upvar, i.e., a way for define to provide +information to its caller, rather than the other way around. In this +case, the value of block is the new block itself (the hexagon block, in +this example). The second slot is where you give the label for the new +block. In this example, the label is ā€œhexagon _ā€ in which the +underscore represents an input slot. So, here are a few examples of +block labels:

+ +

set pen _ to _

+ +

for _ = _ to _ _

+ +

ask _ and wait

+ +

_ of _

+ +

Note that the underscores are separated from the block text by spaces. +Note in the case of the for blockā€™s label that the upvar (the i) and the +C-slot both count as inputs. Note also that the label is not meant to be +a unique symbol that represents only this block. For example, +{width=ā€83pxā€ +height=ā€19pxā€} and A picture containing text, hitting
+Description automatically
+generated{width=ā€110pxā€ +height=ā€18pxā€} both have the label

+ +

_ of _. The label does not give the input slots names (thatā€™s done in +the body, coming next) or types (thatā€™s done in the set _ of block _ +to _ block, coming in two paragraphs).

+ +

The third slot is for the definition of the new block. This is a +(ringed) script whose input names (formal parameters) will become the +formal parameters of the new block. And the script is its script.

+ +

So far we know the blockā€™s label, parameters, and script. There are +other things to specify about the block, and one purpose of the block +upvar is to allow that. In the example on the previous page, there are +four

+ +

{width=ā€272pxā€ +height=ā€93pxā€}set _ of block _ to _ blocks, reproduced below for +your convenience:

+ +

The category of the block can be set to any primitive or custom +category. The default is other. The type is command, reporter, or +predicate. Command is the default, so this setting is redundant, but we +want to show all the choices in the set block. The scope is either +global or sprite, with global as the default. The last input to set +slots is a list of length less than or equal to the number of +underscores in the label. Each item of the list is a type name, like the +ones in the is (5) a (number)? block. If there is only one input, you +can use just the name instead of putting it in a list. An empty or +missing list item means type Any.

+ +

{width=ā€414pxā€ +height=ā€80pxā€}It's very important that these set blocks appear in the +same script as the define that creates the block, because the block +upvar is local to that script. You canā€™t later say, for example,

+ +

because the copy of the hexagon block in this instruction counts as +ā€œusingā€ it.

+ +

{width=ā€250pxā€ +height=ā€31pxā€}The of block reporter is useful to copy attributes from +one block to another, as we copied the definition of square, modified +it, and used it to define hexagon. Some of the values this block reports +are a little unfriendly:

+ +

ā€œ1ā€? Yes, this block reports numbers instead of names for category, +type, and scope. The reason is that maybe someday weā€™ll have +translations to other languages for custom category names, as we already +do for the built-in categories, types, and scopes; if you translate a +program using this block to another language, the numeric outputs wonā€™t +change, simplifying comparisons in your code. The set block accepts +these numbers as an alternative to the names.

+ +

{width=ā€324pxā€ +height=ā€36pxā€}{width=ā€98pxā€ +height=ā€24pxā€}There are a few more attributes of a block, less +commonly used.

+ +

{width=ā€338pxā€ +height=ā€59pxā€}{width=ā€185pxā€ +height=ā€59pxā€}{width=ā€316pxā€ +height=ā€59pxā€}{width=ā€226pxā€ +height=ā€246pxā€}{width=ā€160pxā€ +height=ā€24pxā€}The list input is just like the one for set slots except +for default values instead of types. Now for a block with a menu input:

+ +

{width=ā€400pxā€ +height=ā€122pxā€}We passed too quickly over how the script +turned the square block into a hexagon block:

+ +

{width=ā€641pxā€ +height=ā€352pxā€}Those replace item blocks arenā€™t very +elegant. I had to look at foo by hand to figure out where the numbers I +wanted to change are. This situation can be improved with a little +programming:

+ +

Exercise for the reader: Implement this:Graphical user interface
+Description automatically
+generated{width=ā€299pxā€ +height=ā€55pxā€}

+ +

{width=ā€720pxā€ +height=ā€203pxā€}Returning to the define block, thereā€™s +another reason for the block upvar: Itā€™s helpful in defining a recursive +procedure using define. For a procedure to call itself, it needs a name +for itself. But in the definition input to the define block, define +itself hasnā€™t been called yet, so the new block isnā€™t in the palette +yet. So you do this:

+ +

Yes, you put block in the define, but it gets changed into this script +in the resulting definition. You could use this script directly in a +simple case like this, but in a complicated case with a recursive call +inside a ring inside the one giving the block definition, this script +always means the innermost ring. But the upvar means the outer +{width=ā€720pxā€ +height=ā€51pxā€}{width=ā€462pxā€ +height=ā€38pxā€}{width=ā€462pxā€ +height=ā€143pxā€}ring:

+ +

Itā€™s analogous to using explicit formal parameters when you nest calls +to higher order functions.

+ +

{width=ā€554pxā€ height=ā€372pxā€}Macros

+ +

Users of languages in the C family have learned to think of macros as +entirely about text strings, with no relation to the syntax of the +language. So you can do things like

+ +

#define foo baz)

+ +

with the result that you can only use the foo macro after an open +parenthesis.

+ +

In the Lisp family of languages we have a different tradition, in which +macros are syntactically just like procedure calls, except that the +ā€œprocedureā€ is a macro, with different evaluation rules from ordinary +procedures. Two things make a macro different: its input expressions are +not evaluated, so a macro can establish its own syntax (but still +delimited by parentheses, in Lisp, or still one block, in Snap! ); and +the result of a macro call is a new expression that is evaluated as if +it appeared in the caller of the macro, with access to the callerā€™s +variables and, implicitly, its continuation.

+ +

Snap! has long had the first part of this, the ability to make inputs +unevaluated. In version 8.0 we add the ability to run code in the +context of another procedure, just as we can run code in the context of +another sprite, using the same mechanism: the of block. In the example +on the previous page, the if _ report _ caller block runs a report +block, but not in its own context; it causes the fizzbuzz block to +report ā€œfizzā€ or ā€œbuzzā€ as appropriate. (Yes, we know that the rules +implemented here are simplified compared to the real game.) It doesnā€™t +just report out of the entire toplevel script; you can see that map is +able to prepend ā€œThe answer isā€ to each reported value.

+ +

This macro capability isnā€™t fully implemented. First, we shouldnā€™t have +to use the calling script as an explicit input to the macro. In a later +release, this will be fixed; when defining a block youā€™ll be able to say +that itā€™s a macro, and it will automatically get its callerā€™s context as +an invisible input. Second, there is a possibility of confusion between +the variables of the macro and the variables of its caller. (What if the +macro wanted to refer to a variable value in its caller?) The one +substantial feature of Scheme that we donā€™t yet implement is hygienic +macros, which make it possible to keep the two namespaces separate.

+ +

User Interface Elements

+ +

In this chapter we describe in detail the various buttons, menus, and +other clickable elements of the Snap! user interface. Here again is +the map of the Snap! window:

+ +

{width=ā€719pxā€ +height=ā€448pxā€}

+ +

Tool Bar Features

+ +

Holding down the Shift key while clicking on any of the menu buttons +gives access to an extended menu with options, shown in red, that are +experimental or for use by the developers. Weā€™re not listing those extra +options here because they change frequently and you shouldnā€™t rely on +them. But theyā€™re not secrets.

+ +

The Snap! Logo Menu

+ +

The Snap! logo at the left end of the tool bar is clickable. It shows +a menu of options about Snap! itself:

+ +

{width=ā€224pxā€ +height=ā€98pxā€}

+ +

The About option displays information about Snap! itself, including +version numbers for the source modules, the implementors, and the +license (AGPL: you can do anything with it except create proprietary +versions, basically).

+ +

The Reference manual option downloads a copy of the latest revision of +this manual in PDF format.

+ +

The Snap! website option opens a browser window pointing to +snap.berkeley.edu, the web site for Snap!.

+ +

The Download source option opens a browser window displaying the Github +repository of the source files for Snap!. At the bottom of the page +are links to download the latest official release. Or you can navigate +around the site to find the current development version. You can read +the code to learn how Snap! is implemented, host a copy on your own +computer (this is one way to keep working while on an airplane), or make +a modified version with customized features. (However, access to cloud +accounts is limited to the official version hosted at Berkeley.)

+ +

The File Menu

+ +

{width=ā€31pxā€ +height=ā€17pxā€}The file icon shows a menu mostly about +saving and loading projects. You may not see all these options, if you +donā€™t have multiple sprites, scenes, custom blocks, and custom +categories.

+ +

The Notes option opens a window in which you can type notes about the +project: How to use it, what it does, whose project you modified to +create it, if any, what other sources of ideas you used, or any other +information about the project. This text is saved with the project, and +is useful if you share it with other users.

+ +

The New option starts a new, empty project. Any project you were working +on before disappears, so you are asked to confirm that this is really +what you want. (It disappears only from the current working Snap! +window; you should save the current project, if you want to keep it, +before using New.)

+ +

Note the \^N at the end of the line. This indicates that you can type +control-N as a shortcut for this menu item. Alas, this is not the case +in every browser. Some Mac browsers require command-N (āŒ˜N) instead, +while others open a new browser window instead of a new project. Youā€™ll +have to experiment. In general, the keyboard shortcuts in Snap! are +the standard ones you expect in other software.

+ +

{width=ā€277pxā€ +height=ā€201pxā€}The Openā€¦ option shows a project open +dialog box in which you can choose a project to open:

+ +

In this dialog, the three large buttons at the left select a source of +projects: Cloud means your Snap! accountā€™s cloud storage. Examples +means a collection of sample projects we provide. Computer is for +projects saved on your own computer; when you click it, this dialog is +replaced with your computerā€™s system dialog for opening files. The text +box to the right of those buttons is an alphabetical listing of projects +from that source; selecting a project by clicking shows its thumbnail (a +picture of the stage when it was saved) and its project notes at the +right.

+ +

{width=ā€262pxā€ +height=ā€190pxā€}The search bar at the top can be used to +find a project by name or text in the project notes. So in this example:

+ +

{width=ā€261pxā€ +height=ā€190pxā€}I was looking for my ice cream projects +and typed ā€œcreaā€ in the search bar, then wondered why ā€œferrisā€ matched. +But then when I clicked on ferris I saw this:

+ +

My search matched the word ā€œrecreateā€ in the project notes.

+ +

The six buttons at the bottom select an action to perform on the +selected project. In the top row, Recover looks in your cloud account +for older versions of the chosen project. If your project is damaged, +donā€™t keep saving broken versions! Use Recover first thing. You will +see a list of saved versions; choose one to open it. Typically, youā€™ll +see the most recent version before the last save, and the newest version +saved before today. Then come buttons Share/Unshare and +Publish/Unpublish. The labelling of the buttons depends on your +projectā€™s publication status. If a project is neither shared nor +published (the ones in lightface type in the project list), it is +private and nobody can see it except you, its owner. If it is shared +(boldface in the project list), then when you open it youā€™ll see a URL +like this one:

+ +

https://snap.berkeley.edu/snapsource/snap.html#present:Username=bh&ProjectName=count%20change

+ +

but with your username and project name. (ā€œ%20ā€ in the project name +represents a space, which canā€™t be part of a URL.) Anyone who knows this +URL can see your project. Finally, if your project is published +(bold italic in the list), then your project is shown on the +Snap! web site for all the world to see. (In all of these cases, you +are the only one who can write to (save) your project. If another user +saves it, a separate copy will be saved in that userā€™s account. Projects +remember the history of who created the original version and any other +ā€œremixā€ versions along the way.

+ +

In the second row, the first button, Open, loads the project into +Snap! and closes the dialog box. The next button (if Cloud is the +source) is Delete, and if clicked it deletes the selected project. +Finally, the Cancel button closes the dialog box without opening a +project. (It does not undo any sharing, unsharing, or deletion youā€™ve +done.)

+ +

Back to the File menu, the Save menu option saves the project to the +same source and same name that was used when opening the project. (If +you opened another userā€™s shared project or an example project, the +project will be saved to your own cloud account. You must be logged in +to save to the cloud.)

+ +

{width=ā€311pxā€ +height=ā€226pxā€}The Save asā€¦ menu option opens a dialog +box in which you can specify where to save the project:

+ +

This is much like the Open dialog, except for the horizontal text box at +the top, into which you type a name for the project. You can also +publish, unpublish, share, unshare, and delete projects from here. There +is no Recover button.

+ +

The Importā€¦ menu option is for bringing some external resource into +the current project, or it can load an entirely separate project, from +your local disk. You can import costumes (any picture format that your +browser supports), sounds (again, any format supported by your browser), +and block libraries or sprites (XML format, previously exported from +Snap! itself). Imported costumes and sounds will belong to the +currently selected sprite; imported blocks are global (for all sprites). +Using the Import option is equivalent to dragging the file from your +desktop onto the Snap! window.

+ +

Depending on your browser, the Export projectā€¦ option either directly +saves to your disk or opens a new browser tab containing your complete +project in XML notation (a plain text format). You can then use the +browserā€™s Save feature to save the project as an XML file, which should +be named something.xml so that Snap! will recognize it as a project +when you later drag it onto a Snap! window. This is an alternative to +saving the project to your cloud account: keeping it on your own +computer. It is equivalent to choosing Computer from the Save dialog +described earlier.

+ +

The Export summaryā€¦ option creates a web page, in HTML, with all of +the information about your project: its name, its project notes, a +picture of whatā€™s on its stage, definitions of global blocks, and then +per-sprite information: name, wardrobe (list of costumes), and local +variables and block definitions. The page can be converted to PDF by the +browser; itā€™s intended to meet the documentation requirements of the +Advanced Placement Computer Science Principles create task.

+ +

The Export blocksā€¦ option is used to create a block library. It +presents a list of all the global (for all sprites) blocks in your +project, and lets you select which to export. It then opens a browser +tab with those blocks in XML format, or stores directly to your local +disk, as with the Export project option. Block libraries can be imported +with the Import option or by dragging the file onto the Snap! window. +This option is shown only if you have defined custom blocks.

+ +

The Unused blocksā€¦ option presents a listing of all the global custom +blocks in your project that arenā€™t used anywhere, and offers to delete +them. As with Export blocks, you can choose a subset to delete with +checkboxes. This option is shown only if you have defined custom blocks.

+ +

The Hide blocksā€¦ option shows all blocks, including primitives, with +checkboxes. This option does not remove any blocks from your project, +but it does hide selected block in your palette. The purpose of the +option is to allow teachers to present students with a simplified +Snap! with some features effectively removed. The hiddenness of +primitives is saved with each project, so students can load a shared +project and see just the desired blocks. But users can always unhide +blocks by choosing this option and unclicking all the checkboxes. +(Right-click in the background of the dialog box to get a menu from +which you can check all boxes or uncheck all boxes.)

+ +

The New categoryā€¦ option allows you to add your own categories to the +palette. It opens a dialog box in which you specify a name and a color +for the category. (A lighter version of the same color will be used for +the zebra coloring feature.)

+ +

The Remove a categoryā€¦ option appears only if youā€™ve created custom +categories. It opens a very small, easy-to-miss menu of category names +just under the file icon in the menu bar. If you remove a category that +has blocks in it, all those blocks are also removed.

+ +

{width=ā€112pxā€ +height=ā€19pxā€}The next group of options concern the +scenes feature, new in Snap! 7.0. A scene is a complete project, +with its own stage, sprites, and code, but several can be merged into +one project, using the block to bring another scene onscreen. The +Scenesā€¦ option presents a menu of all the scenes in your project, +where the File menu was before you clicked it. The New scene option +creates a new, empty scene, which you can rename as you like from its +context menu. Add sceneā€¦ is like Importā€¦ but for scenes. (A complete +project can be imported as a scene into another project, so you have to +specify that youā€™re importing the project as a scene rather than +replacing the current project.)

+ +

The Librariesā€¦ option presents a menu of useful, optional block +libraries:{width=ā€711pxā€ +height=ā€311pxā€}

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs. The libraries are described in detail in Section I.H, page 25.

+ +

{width=ā€411pxā€ +height=ā€311pxā€}The Costumesā€¦ option opens a browser +into the costume library:

+ +

You can import a single costume by clicking it and then clicking the +Import button. Alternatively, you can import more than one costume by +double-clicking each one, and then clicking Cancel when done. Notice +that some costumes are tagged with ā€œsvgā€ in this picture; those are +vector-format costumes that are not (yet) editable within Snap!.

+ +

If you have the stage selected in the sprite corral, rather than a +sprite, the Costumesā€¦ option changes to a Backgroundsā€¦ option, with +different choices in the browser:

+ +

{width=ā€411pxā€ +height=ā€311pxā€}The costume and background libraries +include both bitmap (go jagged if enlarged) and vector (enlarge +smoothly) images. Thanks to Scratch 2.0/3.0 for most of these images! +Some older browsers refuse to import a vector image, but instead convert +it to bitmap.

+ +

The Soundsā€¦ option opens the third kind of media browser:

+ +

{width=ā€411pxā€ +height=ā€311pxā€}The Play buttons can be used to preview +the sounds.

+ +

Finally, the Undelete spritesā€¦ option appears only if you have deleted +a sprite; it allows you to recover a sprite that was deleted by accident +(perhaps intending to delete only a costume).

+ +

The Cloud Menu

+ +

{width=ā€138pxā€ +height=ā€73pxā€}{width=ā€28pxā€ +height=ā€16pxā€}{width=ā€64pxā€ +height=ā€16pxā€}The cloud icon shows a menu of options +relating to your Snap! cloud account. If you are not logged in, you +see the outline icon and get this menu:

+ +

Choose Loginā€¦ if you have a Snap! account and remember your +password. Choose Signupā€¦ if you donā€™t have an account. Choose Reset +Passwordā€¦ if youā€™ve forgotten your password or just want to change it. +You will then get an email, at the address you gave when you created +your account, with a new temporary password. Use that password to log +in, then you can choose your own password, as shown below. Choose Resend +Verification Emailā€¦ if you have just created a Snap! account but +canā€™t find the email we sent you with the link to verify that itā€™s +really your email. (If you still canā€™t find it, check your spam folder. +If you are using a school email address, your school may block incoming +email from outside the school.) The Open in Community Site option +appears only if you have a project open; it takes you to the community +site page about that project.

+ +

{width=ā€155pxā€ +height=ā€63pxā€}If you are already logged in, youā€™ll see +the solid icon +{width=ā€28pxā€ +height=ā€16pxā€} and get this menu:

+ +

Logout is obvious, but has the additional benefit of showing you whoā€™s +logged in. Change passwordā€¦ will ask for your old password (the +temporary one if youā€™re resetting your password) and the new password +you want, entered twice because it doesnā€™t echo. Open in Community Site +is the same as above.

+ +

The Settings Menu

+ +

{width=ā€120pxā€ +height=ā€248pxā€}{width=ā€28pxā€ +height=ā€16pxā€}The settings icon shows a menu of Snap! +options, either for the current project or for you permanently, +depending on the option:

+ +

The Languageā€¦ option lets you see the Snap! user interface (blocks +and messages) in a language other than English. (Note: Translations have +been provided by Snap! users. If your native language is missing, send +us an email!)

+ +

The Zoom blocks... option lets you change the size of blocks, both in +the palettes and in scripts. The standard size is 1.0 units. The main +purpose of this option is to let you take very high-resolution pictures +of scripts for use on posters. It can also be used to improve +readability when projecting onto a screen while lecturing, but bear in +mind that it doesnā€™t make the palette or script areas any wider, so your +computerā€™s command-option-+ feature may be more practical. Note that a +zoom of 2 is gigantic! Donā€™t even try 10.

+ +

The Fade blocksā€¦ option opens a dialog in which you can change the +appearance of blocks:

+ +

{width=ā€719pxā€ +height=ā€247pxā€}Mostly this is a propaganda aid to use on +people who think that text languages are somehow better or more grown up +than block languages, but some people do prefer less saturated block +colors. You can use the pulldown menu for preselected fadings, use the +slider to see the result as you change the fading amount, or type a +number into the text box once youā€™ve determined your favorite value.

+ +

The Stage sizeā€¦ option lets you set the size of the full-size stage +in pixels. If the stage is in half-size or double-size (presentation +mode), the stage size values donā€™t change; they always reflect the +full-size stage.

+ +

The Microphone resolutionā€¦ option sets the buffer size used by the +microphone block in Settings. ā€œResolutionā€ is an accurate name if you +are getting frequency domain samples; the more samples, the narrower the +range of frequencies in each sample. In the time domain, the buffer size +determines the length of time over which samples are collected.

+ +

The remaining options let you turn various features on and off. There +are three groups of checkboxes. The first is for temporary settings not +saved in your project nor in your user preferences.

+ +

The JavaScript extensions option enables the use of the JavaScript +function block. Because malicious projects could use JavaScript to +collect private information about you, or to delete or modify your saved +projects, you must enable JavaScript each time you load a project that +uses it.

+ +

{width=ā€114pxā€ +height=ā€18pxā€}{width=ā€118pxā€ +height=ā€25pxā€}The Extension blocks option adds two +blocks to the palette:

+ +

These blocks provide assorted capabilities to official libraries that +were formerly implemented with the JavaScript function block. This +allows these libraries to run without requiring the JavaScript +extensions option. Details are subject to change.

+ +

{width=ā€106pxā€ +height=ā€200pxā€}{width=ā€157pxā€ +height=ā€40pxā€}Input sliders provides an alternate way to +put values in numeric input slots; if you click in such a slot, a slider +appears that you can control with the mouse:

+ +

The range of the slider will be from 25 less than the inputā€™s current +value to 25 more than the current value. If you want to make a bigger +change than that, you can slide the slider all the way to either end, +then click on the input slot again, getting a new slider with a new +center point. But you wonā€™t want to use this technique to change the +input value from 10 to 1000, and it doesnā€™t work at all for non-integer +input ranges. This feature was implemented because software keyboard +input on phones and tablets didnā€™t work at all in the beginning, and +still doesnā€™t work perfectly on Android devices, so sliders provide a +workaround. It has since found another use in providing ā€œlivelyā€ +response to input changes; if Input sliders is checked, reopening the +settings menu will show an additional option called Execute on slider +change. If this option is also checked, then changing a slider in the +scripting area automatically runs the script in which that input +appears. The project live-tree in the Examples collection shows how this +can be used; it features a fractal tree custom block with several +inputs, and you can see how each input affects the picture by moving a +slider.

+ +

Turbo mode makes many projects run much faster, at the cost of not +keeping the stage display up to date. (Snap! ordinarily spends most of +its time drawing sprites and updating variable watchers, rather than +actually carrying out the instructions in your scripts.) So turbo mode +isnā€™t a good idea for a project with glide blocks or one in which the +user interacts with animated characters, but itā€™s great for drawing a +complicated fractal, or computing the first million digits of šœ‹, so that +you donā€™t need to see anything until the final result. While in turbo +mode, the button that normally shows a green flag instead shows a green +lightning bolt. (But when āš‘ clicked hat blocks still activate when the +button is clicked.)

+ +

Visible stepping enables the slowed-down script evaluation described in +Chapter I. Checking this option is equivalent to clicking the footprint +button above the scripting area. You donā€™t want this on except when +youā€™re actively debugging, because even the fastest setting of the +slider is still slowed a lot.

+ +

Log pen vectors tells Snap! to remember lines drawn by sprites as +exact vectors, rather than remember only the pixels that the drawing +leaves on the stage. This remembered vector picture can be used in two +ways: First, right-clicking on a pen trails block gives an option to +relabel it into a pen vectors block which, when run, reports the logged +lines as a vector (svg) costume. Second, right-clicking on the stage +when there are logged vectors shows an extra option, svgā€¦, that +exports a picture of the stage in vector format. Only lines are logged, +not color regions made with the fill block.

+ +

The next group of four are user preference options, preserved when you +load a new project. Long form input dialog, if checked, means that +whenever a custom block input name is created or edited, you immediately +see the version of the input name dialog that includes the type options, +default value setting, etc., instead of the short form with just the +name and the choice between input name and title text. The default +(unchecked) setting is definitely best for beginners, but more +experienced Snap! programmers may find it more convenient always to +see the long form.

+ +

Plain prototype labels eliminates the plus signs between words in the +Block Editor prototype block. This makes it harder to add an input to a +custom block; you have to hover the mouse where the plus sign would have +been, until a single plus sign appears temporarily for you to click on. +Itā€™s intended for people making pictures of scripts in the block editor +for use in documentation, such as this manual. You probably wonā€™t need +it otherwise.

+ +

Clicking sound causes a really annoying sound effect whenever one block +snaps next to another in a script. Certain very young children, and our +colleague Dan Garcia, like this, but if you are such a child you should +bear in mind that driving your parents or teachers crazy will result in +you not being allowed to use Snap!. It might, however, be useful for +visually impaired users.

+ +

Flat design changes the ā€œskinā€ of the Snap! window to a really hideous +design with white and pale-grey background, rectangular rather than +rounded buttons, and monochrome blocks (rather than the shaded, somewhat +3D-looking normal blocks). The monochrome blocks are the reason for the +ā€œflatā€ in the name of this option. The only thing to be said for this +option is that, because of the white background, it may blend in better +with the rest of a web page when a Snap! project is run in a frame in +a larger page. (I confess I used it to make the picture of blocks faded +all the way to just text two pages ago, though.)

+ +

The final group of settings change the way Snap! interprets your +program; they are saved with the project, so anyone who runs your +project will experience the same behavior. Thread safe scripts changes +the way Snap! responds when an event (clicking the green flag, say) +starts a script, and then, while the script is still running, the same +event happens again. Ordinarily, the running process stops where it is, +ignoring the remaining commands in the script, and the entire script +starts again from the top. This behavior is inherited from Scratch, and +some converted Scratch projects depend on it; thatā€™s why itā€™s the +default. Itā€™s also sometimes the right thing, especially in projects +that play music in response to mouse clicks or keystrokes. If a note is +still playing but you ask for another one, you want the new one to start +right then, not later after the old process finishes. But if your script +makes several changes to a database and is interrupted in the middle, +the result may be that the database is inconsistent. When you select +Thread safe scripts, the same event happening again in the middle of +running a script is simply ignored. (This is arguably still not the +right thing; the event should be remembered and the script run again as +soon as it finishes. Weā€™ll probably get around to adding that choice +eventually.) Keyboard events (when __ key pressed) are always +thread-safe.

+ +

Flat line ends affects the drawing of thick lines (large pen width). +Usually the ends are rounded, which looks best when turning corners. +With this option selected, the ends are flat. Itā€™s useful for drawing a +brick wall or a filled rectangle.

+ +

Codification support enables a feature that can translate a Snap! +project to a text-based (rather than block-based) programming language. +The feature doesnā€™t know about any particular other language; instead, +you can provide a translation for each primitive block using these +special blocks:

+ +

{width=ā€300pxā€ +height=ā€52pxā€}

+ +

Using these primitive blocks, you can build a block library to translate +into any programming language. Watch for such libraries to be added to +our library collection (or contribute one). To see some examples, open +the project ā€œCodificationā€ in the Examples project list. Edit the blocks +map to Smalltalk, map to JavaScript, etc., to see examples of how to +provide translations for blocks.

+ +

{width=ā€212pxā€ +height=ā€477pxā€}{width=ā€132pxā€ +height=ā€460pxā€}The Single palette option puts all blocks, regardless of +category, into a single palette. Itā€™s intended mainly for use by +curriculum developers building Parsons problems: projects in which +only a small set of blocks are provided, and the task is to arrange +those blocks to achieve a set goal. In that application, this option is +combined with the hiding of almost all primitive blocks. (See page 119.) +When Single palette is turned on, two additional options (initially on) +appear in the settings menu; the Show categories option controls the +appearance of the palette category names such as +{width=ā€35pxā€ height=ā€15pxā€} +and A picture containing logo Description automatically
+generated{width=ā€32pxā€ +height=ā€17pxā€}, while the Show buttons option controls the appearance +of the {width=ā€59pxā€ +height=ā€15pxā€} and +{width=ā€51pxā€ height=ā€15pxā€} +buttons in the palette.

+ +

The HSL pen color model option changes the set pen, change pen, and pen +blocks to provide menu options hue, saturation, and lightness instead of +hue, saturation, and brightness (a/k/a value). Note: the name +ā€œsaturationā€ means something different in HSL from in HSV! See Appendix +A for all the information you need about colors.

+ +

The Disable click-to-run option tells Snap! to ignore user mouse +clicks on blocks and scripts if it would ordinarily run the block or +script. (Right-clicking and dragging still work, and so does clicking in +an input slot to edit it.) This is another Parsons problem feature; the +idea is that there will be buttons displayed that run code only in +teacher-approved ways. But kids can uncheck the checkbox. ā˜ŗļøŽ

+ +

Visible Stepping Controls

+ +

{width=ā€36pxā€ +height=ā€21pxā€}After the menu buttons youā€™ll see the +project name. After that comes the footprint button used to turn on +visible stepping and, when itā€™s on, the slider to control the speed of +stepping.

+ +

Stage Resizing Buttons

+ +

{width=ā€36pxā€ +height=ā€21pxā€}{width=ā€36pxā€ +height=ā€21pxā€}{width=ā€36pxā€ +height=ā€21pxā€}{width=ā€36pxā€ +height=ā€21pxā€}Still in the tool bar, but above the left +edge of the stage, are two buttons that change the size of the stage. +The first is the shrink/grow button. Normally it looks like this: +Clicking the button displays the stage at half-normal size horizontally +and vertically (so it takes up Ā¼ of its usual area). When the stage is +half size the button looks like this: and clicking it returns the stage +to normal size. The main reason youā€™d want a half size stage is during +the development process, when youā€™re assembling scripts with wide input +expressions and the normal scripting area isnā€™t wide enough to show the +complete script. Youā€™d typically then switch back to normal size to try +out the project. The next presentation mode button normally looks like +this: Clicking the button makes the stage double size in both dimensions +and eliminates most of the other user interface elements (the palette, +the scripting area, the sprite corral, and most of the tool bar). When +you open a shared project using a link someone has sent you, the project +starts in presentation mode. While in presentation mode, the button +looks like this: Clicking it returns to normal (project development) +mode.

+ +

Project Control Buttons {#project-control-buttons .ListParagraph}

+ +

Above the right edge of the stage are three buttons that control the +running of the project.

+ +

{width=ā€36pxā€ +height=ā€21pxā€}Technically, the green flag is no more a project control +than anything else that can trigger a hat block: typing on the keyboard +or clicking on a sprite. But itā€™s a convention that clicking the flag +should start the action of the project from the beginning. Itā€™s only a +convention; some projects have no flag-controlled scripts at all, but +respond to keyboard controls instead. Clicking the green flag also +deletes temporary clones.

+ +

{width=ā€34pxā€ +height=ā€19pxā€}Whenever any script is running (not necessarily in the +current sprite), the green flag is lit: .

+ +

{width=ā€34pxā€ +height=ā€19pxā€}{width=ā€130pxā€ +height=ā€85pxā€}Shift-clicking the button enters Turbo +mode, and the button then looks like a lightning bolt: . Shift-clicking +again turns Turbo mode off.

+ +

{width=ā€36pxā€ +height=ā€21pxā€}Scripts can simulate clicking the green +flag by broadcasting the special message +{width=ā€29pxā€ +height=ā€29pxā€}.

+ +

{width=ā€36pxā€ +height=ā€21pxā€}{width=ā€36pxā€ +height=ā€21pxā€}The pause button suspends running all +scripts. If clicked while scripts are running, the button changes shape +to become a play button: Clicking it while in this form resumes the +suspended scripts. There is also a pause all block in the Control +palette that can be inserted in a script to suspend all scripts; this +provides the essence of a breakpoint debugging capability. The use of +the pause button is slightly different in visible stepping mode, +described in Chapter I.

+ +

{width=ā€53pxā€ +height=ā€17pxā€}The stop button stops all scripts, like +the stop all block. It does not prevent a script from starting again +in response to a click or keystroke; the user interface is always +active. There is one exception: generic when blocks will not fire after +a stop until some non-generic event starts a script. The stop button +also deletes all temporary clones.

+ +

The Palette Area

+ +

At the top of the palette area are the eight buttons that select which +palette (which block category) is shown: Motion, Looks, Sound, Pen, +Control, Sensing, Operators, and Variables (which also includes the List +and Other blocks). There are no menus behind these buttons.

+ +

Buttons in the Palette

+ +

{width=ā€25pxā€ +height=ā€25pxā€}Under the eight palette selector buttons, +at the top of the actual palette, are two semi-transparent buttons. The +first is the search button, which is equivalent to typing control-F: +It replaces the palette with a search bar into which you can type part +of the title text of the block youā€™re trying to find. To leave this +search mode, click one of the eight palette selectors, or type the +Escape key.

+ +

{width=ā€25pxā€ +height=ā€25pxā€}The other button is equivalent to the +ā€œMake a blockā€ button, except that the dialog window that it opens has +the current palette (color) preselected.

+ +

Context Menus for Palette Blocks

+ +

{width=ā€83pxā€ +height=ā€44pxā€}Most elements of the Snap! display can +be control-clicked/right-clicked to show a context menu, with items +relevant to that element. If you control-click/right-click a primitive +block in the palette, you see this menu:

+ +

The helpā€¦ option displays a box with documentation about the block. +Hereā€™s an example:

+ +

{width=ā€156pxā€ +height=ā€85pxā€}{width=ā€319pxā€ +height=ā€233pxā€}If you control-click/right-click a +custom (user-defined) block in the palette, you see this menu:

+ +

The helpā€¦ option for a custom block displays the comment, if any, +attached to the custom blockā€™s hat block in the Block Editor. Here is an +example of a block with a comment and its help display:

+ +

{width=ā€649pxā€ +height=ā€235pxā€}If the help text includes a URL, it is +clickable and will open the page in a new tab.

+ +

The delete block definitionā€¦ option asks for confirmation, then +deletes the custom block and removes it from any scripts in which it +appears. (The result of this removal may not leave a sensible script; +itā€™s best to find and correct such scripts before deleting a block.) +Note that there is no option to hide a custom block; this can be done +in the Block Editor by right-clicking on the hat block.

+ +

The duplicate block definitionā€¦ option makes a copy of the block and +opens that copy in the Block Editor. Since you canā€™t have two custom +blocks with the same title text and input types, the copy is created +with ā€œ(2)ā€ (or a higher number if necessary) at the end of the block +prototype.

+ +

The export block definitionā€¦ option writes a file in your browserā€™s +downloads directory containing the definition of this block and any +other custom blocks that this block invokes, directly or indirectly. So +the resulting file can be loaded later without the risk of red +Undefined! blocks because of missing dependencies.

+ +

The editā€¦ option opens a Block Editor with the definition of the +custom block.

+ +

Context Menu for the Palette Background

+ +

{width=ā€95pxā€ +height=ā€57pxā€}Right-click/control-click on the grey +background of the palette area shows this menu:

+ +

{width=ā€154pxā€ +height=ā€207pxā€}The find blocksā€¦ option does the same +thing as the magnifying-glass button. The hide blocksā€¦ option opens a +dialog box in which you can choose which blocks (custom as well as +primitive) should be hidden. (Within that dialog box, the context menu +of the background allows you to check or uncheck all the boxes at once.)

+ +

The make a categoryā€¦ option, which is intended mainly for authors of +snap extensions, lets you add custom categories to the palette. It +opens a small dialog window in which you specify a name and a color +for the new category:

+ +

{width=ā€137pxā€ +height=ā€279pxā€}{width=ā€147pxā€ +height=ā€108pxā€}Pick a dark color, because it will be lightened for +zebra coloring when users nest blocks of the same category. Custom +categories are shown below the built-in categories in the category +selector:

+ +

{width=ā€130pxā€ +height=ā€177pxā€}This example comes from Eckart Modrowā€™s +SciSnap! library. Note that the custom category list has its own +scroll bar, which appears if you have more than six custom categories. +Note also that the buttons to select a custom category occupy the full +width of the palette area, unlike the built-in categories, which occupy +only half of the width. Custom categories are listed in alphabetical +order; this is why Prof. Modrow chose to start each category name with a +number, so that he could control their order.

+ +

If there are no blocks visible in a category, the category name is +dimmed in the category selector:

+ +

Here we see that category foo has blocks in it, but categories bar and +garply are empty. The built-in categories are also subject to dimming, +if all of the blocks of a category are hidden.

+ +


+Palette Resizing

+ +

At the right end of the palette area, just to the left of the scripting +area, is a resizing +handle{width=ā€136pxā€ +height=ā€145pxā€} that can be dragged rightward to increase +the width of the palette area. This is useful if you write custom blocks +with very long names. You canā€™t reduce the width of the palette below +its standard value.

+ +

The Scripting Area

+ +

The scripting area is the middle vertical region of the Snap! window, +containing scripts and also some controls for the appearance and +behavior of a sprite. There is always a current sprite, whose scripts +are shown in the scripting area. A dark grey rounded rectangle in the +sprite corral shows which sprite (or the stage) is current. Note that +itā€™s only the visible display of the scripting area that is ā€œcurrentā€ +for a sprite; all scripts of all sprites may be running at the same +time. Clicking on a sprite thumbnail in the sprite corral makes it +current. The stage itself can be selected as current, in which case the +appearance is different, with some primitives not shown.

+ +

Sprite Appearance and Behavior Controls

+ +

At the top of the scripting area are a picture of the sprite and some +controls for it:

+ +

{width=ā€335pxā€ +height=ā€100pxā€}

+ +

Note that the sprite picture reflects its rotation, if any. There are +three things that can be controlled here:

+ +

1. The three circular buttons in a column at the left control the +spriteā€™s rotation behavior. Sprite costumes are designed to be +right-side-up when the sprite is facing toward the right (direction = +90). If the topmost button is lit, the default as shown in the picture +above, then the spriteā€™s costume rotates as the sprite changes +direction. If the middle button is selected, then the costume is +reversed left-right when the spriteā€™s direction is roughly leftward +(direction between 180 and 359, or equivalently, between -180 and -1). +If the bottom button is selected, the costumeā€™s orientation does not +change regardless of the spriteā€™s direction.

+ +

2. The spriteā€™s name can be changed in the text box that, in this +picture, says ā€œSprite.ā€

+ +

3. Finally, if the draggable checkbox is checked, then the user can move +the sprite on the stage by clicking and dragging it. The common use of +this feature is in game projects, in which some sprites are meant to be +under the playerā€™s control but others are not.

+ +

Scripting Area Tabs

+ +

{width=ā€297pxā€ +height=ā€24pxā€}Just below the sprite controls are three tabs that +determine what is shown in the scripting area:

+ +

Scripts and Blocks Within Scripts

+ +

Most of whatā€™s described in this section also applies to blocks and +scripts in a Block Editor.

+ +

Clicking on a script (which includes a single unattached block) runs it. +If the script starts with a hat block, clicking on the script runs it +even if the event in the hat block doesnā€™t happen. (This is a useful +debugging technique when you have a dozen sprites and they each have +five scripts with green-flag hat blocks, and you want to know what a +single one of those scripts does.) The script will have a green ā€œhaloā€ +around it while itā€™s running. If the script is shared with clones, then +while it has the green halo it will also have a count of how many +instances of the script are running. Clicking a script with such a halo +stops the script. (If the script includes a warp block, which might be +inside a custom block used in the script, then Snap! may not respond +immediately to clicks.)

+ +

{width=ā€32pxā€ +height=ā€25pxā€}If a script is shown with a red halo, +that means that an error was caught in that script, such as using a list +where a number was needed, or vice versa. Clicking the script will turn +off the halo.

+ +

{width=ā€30pxā€ +height=ā€23pxā€}{width=ā€32pxā€ +height=ā€25pxā€}If any blocks have been dragged into the +scripting area, then in its top right corner youā€™ll see an undo and/or +redo button that can be used to undo or redo block and script drops. +When you undo a drop into an input slot, whatever used to be in the slot +is restored. The redo button appears once youā€™ve used undo.

+ +

The third button starts keyboard editing mode (Section D, page 130).

+ +

Control-click/right-clicking a primitive block within a script shows a +menu like this one:

+ +

{width=ā€60pxā€ +height=ā€102pxā€}{width=ā€60pxā€ +height=ā€105pxā€}

+ +

command block: reporter block:

+ +

The helpā€¦ option shows the help screen for the block, just as in the +palette. The other options appear only when a block is +right-clicked/control-clicked in the scripting area.

+ +

{width=ā€147pxā€ +height=ā€204pxā€}Not every primitive block has a relabelā€¦ option. When +present, it allows the block to be replaced by another, similar block, +keeping the input expressions in place. For example, hereā€™s what happens +when you choose relabelā€¦ for an arithmetic operator:

+ +

Note that the inputs to the existing ā€“ block are displayed in the menu +of alternatives also. Click a block in the menu to choose it, or click +outside the menu to keep the original block. Note that the last three +choices are not available in the palette; you must use the relabel +feature to access them.

+ +

Not every reporter has a compile option; it exists only for the higher +order functions. When selected, a lightning bolt appears before the +block name: +{width=ā€135pxā€ +height=ā€19pxā€} and Snap! tries to compile the function +inside the ring to JavaScript, so it runs at primitive speed. This works +only for simple functions (but the higher order function still works +even if the compilation doesnā€™t). The function to be compiled must be +quick, because it will be uninterruptable; in particular, if itā€™s an +infinite loop, you may have to quit your browser to recover. Therefore, +save your project before you experiment with the compilation +feature. The right-click menu for a compiled higher order function will +have an uncompile option. This is an experimental feature.

+ +

The duplicate option for a command block makes a copy of the entire +script starting from the selected block. For a reporter, it copies only +that reporter and its inputs. The copy is attached to the mouse, and you +can drag it to another script (or even to another Block Editor window), +even though you are no longer holding down the mouse button. Click the +mouse to drop the script copy.

+ +

The block picture underneath the word duplicate for a command block is +another duplication option, but it duplicates only the selected block, +not everything under it in the script. Note that if the selected block +is a C-shaped control block, the script inside its C-shaped slot is +included. If the block is at the end of its script, this option does not +appear. (Use duplicate instead.)

+ +

The extract option removes the selected block from the script and leaves +you holding it with the mouse. In other words, itā€™s like the block +picture option, but it doesnā€™t leave a copy of the block in the original +script. If the block is at the end of its script, this option does not +appear. (Just grab the block with the mouse.) A shorthand for this +operation is to shift-click and drag out the block.

+ +

The delete option deletes the selected block from the script.

+ +

The add comment option creates a comment, like the same option in the +background of the scripting area, but attaches it to the block you +clicked.

+ +

The script picā€¦ option saves a picture of the entire script, not just +from the selected block to the end, into your download folder; or, in +some browsers, opens a new browser tab containing the picture. In the +latter case, you can use the browserā€™s Save feature to put the picture +in a file. This is a super useful feature if you happen to be writing a +Snap! manual! (If you have a Retina display, consider turning off +Retina support before making script pictures; if not, they end up huge.) +For reporters not inside a script, there is an additional result picā€¦ +option that calls the reporter and includes a speech balloon with the +result in the picture. Note: The downloaded file is a ā€œsmart pictureā€: +It also contains the code of the script, as if youā€™d exported the +project. If you later drag the file into the costumes tab, it will be +loaded as a costume. But if you drag it into the scripts tab, it will +be loaded as a script, which you can drop wherever you want it in the +scripting area.

+ +

If the script does not start with a hat block, or you clicked on a +reporter, then thereā€™s one more option: ringify (and, if there is +already a grey ring around the block or script, unringify). Ringify +surrounds the block (reporter) or the entire script (command) with a +grey ring, meaning that the block(s) inside the ring are themselves +data, as an input to a higher order procedure, rather than something to +be evaluated within the script. See Chapter VI, Procedures as Data.

+ +

{width=ā€93pxā€ +height=ā€125pxā€}Clicking a custom block in a script +gives a similar but different menu:

+ +

The relabelā€¦ option for custom blocks shows a menu of other same-shape +custom blocks with the same inputs. At present you canā€™t relabel a +custom block to a primitive block or vice versa. The two options at the +bottom, for custom blocks only, are the same as in the palette. The +other options are the same as for primitive commands.

+ +

{width=ā€85pxā€ +height=ā€104pxā€}If a reporter block is in the scripting +area, possibly with inputs included, but not itself serving as input to +another block, then the menu is a little different again:

+ +

Whatā€™s new here is the result picā€¦ option. Itā€™s like script picā€¦ but +it includes in the picture a speech balloon with the result of calling +the block.

+ +

Broadcast and broadcast and wait blocks in the scripting area have an +additional option: receiversā€¦. When clicked, it causes a momentary (be +looking for it when you click!) halo around the picture in the sprite +corral of those sprites that have a when I receive hat block for the +same message. Similarly, when I receive blocks have a sendersā€¦ option +that light up the sprite corral icons of sprites that broadcast the same +message.

+ +

Scripting Area Background Context Menu

+ +

{width=ā€124pxā€ +height=ā€123pxā€}Control-click/right-click on the grey +striped background of the scripting area gives this menu:

+ +

{width=ā€81pxā€ +height=ā€18pxā€}The undrop option is a sort of ā€œundoā€ +feature for the common case of dropping a block somewhere other than +where you meant it to go. It remembers all the dragging and dropping +youā€™ve done in this spriteā€™s scripting area (that is, other sprites have +their own separate drop memory), and undoes the most recent, returning +the block to its former position, and restoring the previous value in +the relevant input slot, if any. Once youā€™ve undropped something, the +redrop option appears, and allows you to repeat the operation you just +undid. These menu options are equivalent to the and buttons described +earlier.

+ +

The clean up option rearranges the position of scripts so that they are +in a single column, with the same left margin, and with uniform spacing +between scripts. This is a good idea if you canā€™t read your own project!

+ +

{width=ā€133pxā€ +height=ā€68pxā€}The add comment option puts a comment box, +like the picture to the right, in the scripting area. Itā€™s attached to +the mouse, as with duplicating scripts, so you position the mouse where +you want the comment and click to release it. You can then edit the text +in the comment as desired.

+ +

{width=ā€133pxā€ +height=ā€23pxā€}You can drag the bottom right corner of +the comment box to resize it. Clicking the arrowhead at the top left +changes the box to a single-line compact form, , so that you can have a +number of collapsed comments in the scripting area and just expand one +of them when you want to read it in full.

+ +

If you drag a comment over a block in a script, the comment will be +attached to the block with a yellow line:

+ +

{width=ā€143pxā€ +height=ā€81pxā€}{width=ā€320pxā€ +height=ā€90pxā€}Comments have their own context menu, with +obvious meanings:

+ +

Back to the options in the menu for the background of the scripting area +(picture on the previous page):

+ +

The scripts picā€¦ option saves, or opens a new browser tab with, a +picture of all scripts in the scripting area, just as they appear, but +without the grey striped background. Note that ā€œall scripts in the +scripting areaā€ means just the top-level scripts of the current sprite, +not other spritesā€™ scripts or custom block definitions. This is also a +ā€œsmart pictureā€; if you drag it into the scripting area, it will create +a new sprite with those scripts in its scripting area.

+ +

Finally, the make a blockā€¦ option does the same thing as the ā€œMake a +blockā€ button in the palettes. Itā€™s a shortcut so that you donā€™t have to +keep scrolling down the palette if you make a lot of blocks.

+ +

Controls in the Costumes Tab

+ +

{width=ā€188pxā€ +height=ā€205pxā€}If you click on the word ā€œCostumesā€ under +the sprite controls, youā€™ll see something like this:

+ +

{width=ā€36pxā€ +height=ā€21pxā€}{width=ā€28pxā€ +height=ā€16pxā€}The Turtle costume is always present in +every sprite; it is costume number 0. Other costumes can be painted +within Snap! or imported from files or other browser tabs if your +browser supports that. Clicking on a costume selects it; that is, the +sprite will look like the selected costume. Clicking on the paint brush +icon
+opens the Paint Editor, in which you can create a new costume. +Clicking on the camera icon opens a window in which you see what your +computerā€™s camera is seeing, and you can take a picture (which will be +the full size of the stage unless you shrink it in the Paint Editor). +This works only if you give Snap! permission to use the camera, and +maybe only if you opened Snap! in secure (HTTPS) mode, and then only +if your browser loves you.

+ +

{width=ā€343pxā€ +height=ā€305pxā€} Brianā€™s bedroom when heā€™s staying at +Paulā€™s house.

+ +

Control-clicking/right-clicking on the turtle picture gives this menu:

+ +

{width=ā€101pxā€ +height=ā€87pxā€}In this menu, you choose the turtleā€™s +rotation point, which is also the point from which the turtle draws +lines. The two pictures below show what the stage looks like after +drawing a square in each mode; tip (otherwise known as ā€œJens modeā€) is +on the left in the pictures below, middle (ā€œBrian modeā€) on the right:

+ +

{width=ā€301pxā€ +height=ā€113pxā€}As you see, ā€œtipā€ means the front tip of +the arrowhead; ā€œmiddleā€ is not the middle of the shaded region, but +actually the middle of the four vertices, the concave one. (If the shape +were a simple isosceles triangle instead of a fancier arrowhead, it +would mean the midpoint of the back edge.) The advantage of tip mode is +that the sprite is less likely to obscure the drawing. The advantage of +middle mode is that the rotation point of a sprite is rarely at a tip, +and students are perhaps less likely to be confused about just what will +happen if you ask the turtle to turn 90 degrees from the position shown. +(Itā€™s also the traditional rotation point of the Logo turtle, which +originated this style of drawing.)

+ +

{width=ā€94pxā€ +height=ā€127pxā€}Costumes other than the turtle have a +different context menu:

+ +

The edit option opens the Paint Editor on this costume. The rename +option opens a dialog box in which you can rename the costume. (A +costumeā€™s initial name comes from the file from which it was imported, +if any, or is something like costume5.) Duplicate makes a copy of the +costume, in the same sprite. (Presumably youā€™d do that because you +intend to edit one of the copies.) Delete is obvious. The get blocks +option appears only for a smart costume, and brings its script to the +scripting area. The export option saves the costume as a file on your +computer, in your usual downloads folder.

+ +

You can drag costumes up and down in the Costumes tab in order to +renumber them, so that next costume will behave as you prefer.

+ +

{width=ā€123pxā€ +height=ā€83pxā€}If you drag a smart picture of a script +into the Costumes tab, its icon will display the text ā€œ</>ā€ in the +corner to remind you that it includes code:

+ +

Its right-click menu will have an extra get blocks option that switches +to the Scripts tab with the script ready to be dropped there.

+ +

The Paint Editor

+ +

{width=ā€378pxā€ +height=ā€247pxā€}Here is a picture of a Paint Editor window:

+ +

If youā€™ve used any painting program, most of this will be familiar to +you. Currently, costumes you import can be edited only if they are in a +bitmap format (png, jpeg, gif, etc.). There is a vector editor, but it +works only for creating a costume, not editing an imported vector (svg) +picture. Unlike the case of the Block Editor, only one Paint Editor +window can be open at a time.

+ +

The ten square buttons in two rows of five near the top left of the +window are the tools. The top row, from left to right, are the +paintbrush tool, the outlined rectangle tool, the outlined ellipse tool, +the eraser tool, and the rotation point tool. The bottom row tools are +the line drawing tool, the solid rectangle tool, the solid ellipse tool, +the floodfill tool, and the eyedropper tool. Below the tools is a row of +four buttons that immediately change the picture. The first two change +its overall size; the next two flip the picture around horizontally or +vertically. Below these are a color palette, a greyscale tape, and +larger buttons for black, white, and transparent paint. Below these is a +solid bar displaying the currently selected color. Below that is a +picture of a line showing the brush width for painting and drawing, and +below that, you can set the width either with a slider or by typing a +number (in pixels) into the text box. Finally, the checkbox constrains +the line tool to draw horizontally or vertically, the rectangle tools to +draw squares, and the ellipse tools to draw circles. You can get the +same effect temporarily by holding down the shift key, which makes a +check appear in the box as long as you hold it down. (But the Caps Lock +key doesnā€™t affect it.)

+ +

You can correct errors with the undo button, which removes the last +thing you drew, or the clear button, which erases the entire picture. +(Note, it does not revert to what the costume looked like before you +started editing it! If thatā€™s what you want, click the Cancel button at +the bottom of the editor.) When youā€™re finished editing, to keep your +changes, click OK.

+ +

Note that the ellipse tools work more intuitively than ones in other +software you may have used. Instead of dragging between opposite corners +of the rectangle circumscribing the ellipse you want, so that the +endpoints of your dragging have no obvious connection to the actual +shape, in Snap! you start at the center of the ellipse you want and +drag out to the edge. When you let go of the button, the mouse cursor +will be on the curve. If you drag out from the center at 45 degrees to +the axes, the resulting curve will be a circle; if you drag more +horizontally or vertically, the ellipse will be more eccentric. (Of +course if you want an exact circle you can hold down the shift key or +check the checkbox.) The rectangle tools, though, work the way you +expect: You start at one corner of the desired rectangle and drag to the +opposite corner.

+ +

Using the eyedropper tool, you can click anywhere in the Snap! window, +even outside the Paint Editor, and the tool will select the color at the +mouse cursor for use in the Paint Editor. You can only do this once, +because the Paint Editor automatically selects the paintbrush when you +choose a color. (Of course you can click on the eyedropper tool button +again.)

+ +

The only other non-obvious tool is the rotation point tool. It shows in +the Paint Editor where the spriteā€™s current rotation center is (the +point around which it turns when you use a turn block); if you click or +drag in the picture, the rotation point will move where you click. +(Youā€™d want to do this, for example, if you want a character to be able +to wave its arm, so you use two sprites connected together. You want the +rotation point of the arm sprite to be at the end where it joins the +body, so it remains attached to the shoulder while waving.)

+ +

{width=ā€368pxā€ +height=ā€245pxā€}{width=ā€21pxā€ +height=ā€21pxā€}{width=ā€21pxā€ +height=ā€21pxā€}{width=ā€21pxā€ +height=ā€21pxā€}The vector editorā€™s controls are much like +those in the bitmap editor. One point of difference is that the bitmap +editor has two buttons for solid and outline rectangles, and similarly +for ellipses, but in the vector editor there is always an edge color and +a fill color, even if the latter is ā€œtransparent paint,ā€ and so only one +button per shape is needed. Since each shape that you draw is a separate +layer (like sprites on the stage), there are controls to move the +selected shape up (frontward) or down (rearward) relative to other +shapes. There is a selection tool to drag out a rectangular area and +select all the shapes within that area.

+ +

###

+ +

Controls in the Sounds Tab

+ +

{width=ā€34pxā€ +height=ā€19pxā€}There is no Sound Editor in Snap!, and also no current +sound the way thereā€™s a current costume for each sprite. (The sprite +always has an appearance unless hidden, but it doesnā€™t sing unless +explicitly asked.) So the context menu for sounds has only rename, +delete, and export options, and it has a clickable button labeled Play +or Stop as appropriate. There is a sound recorder, which appears if +you click the red record button ( ):

+ +

{width=ā€223pxā€ +height=ā€99pxā€}The first, round button starts recording. +The second, square button stops recording. The third, triangular button +plays back a recorded sound. If you donā€™t like the result, click the +round button again to re-record. When youā€™re satisfied, push the Save +button. If you need a sound editor, consider the free (both senses) +http://audacity.sourceforge.net.

+ +

Keyboard Editing

+ +

An ongoing area of research is how to make visual programming languages +usable by people with visual or motoric disabilities. As a first step in +this direction, we provide a keyboard editor, so that you can create and +edit scripts without tracking the mouse. So far, not every user +interface element is controllable by keyboard, and we havenā€™t even begun +providing output support, such as interfacing with a speech +synthesizer. This is an area in which we know we have a long way to go! +But itā€™s a start. The keyboard editor may also be useful to anyone who +can type faster than they can drag blocks.

+ +

Starting and stopping the keyboard editor

+ +

There are three ways to start the keyboard editor. Shift-clicking +anywhere in the scripting area will start the editor at that point: +either editing an existing script or, if you shift-click on the +background of the scripting area, editing a new script at the mouse +position. Alternatively, typing shift-enter will start the editor on an +existing script, and you can use the tab key to switch to another +script. Or you can click the keyboard button at the top of the scripting +area.

+ +

When the script editor is running, its position is represented by a +blinking white bar:

+ +

{width=ā€212pxā€ +height=ā€153pxā€}To leave the keyboard editor, type the escape key, or +just click on the background of the scripting area.

+ + + +

To move to a different script, type the tab key. Shift-tab to move +through the scripts in reverse order.

+ +

A script is a vertical stack of command blocks. A command block may have +input slots, and each input slot may have a reporter block in it; the +reporter may itself have input slots that may have other reporters. You +can navigate through a script quickly by using the up arrow and down +arrow keys to move between command blocks. Once you find the command +block that you want to edit, the left and right arrow keys move between +editable items within that command. (Left and right arrow when there are +no more editable items within the current command block will move up or +down to another command block, respectively.) Here is a sequence of +pictures showing the results of repeated right arrow keys starting from +the position shown above:

+ +

{width=ā€702pxā€ +height=ā€120pxā€}You can rearrange scripts within the +scripting area from the keyboard. Typing shift-arrow keys (left, right, +up, or down) will move the current script. If you move it onto another +script, the two wonā€™t snap together; the one youā€™re moving will overlap +the one already there. This means that you can move across another +script to get to a free space.

+ +

Editing a script

+ +

Note that the keyboard editor focus, the point shown as a white bar or +halo, is either between two command blocks or on an input slot. The +editing keys do somewhat different things in each of those two cases.

+ +

The backspace key deletes a block. If the focus is between two commands, +the one before (above) the blinking bar is deleted. If the focus is on +an input slot, the reporter in that slot is deleted. (If that input slot +has a default value, it will appear in the slot.) If the focus is on a +variadic input (one that can change the number of inputs by clicking +on arrowheads), then one input slot is deleted. (When you right-arrow +into a variadic input, the focus first covers the entire thing, +including the arrowheads; another right-arrow focuses on the first slot +within that input group. The focus is ā€œon the variadic inputā€ when it +covers the entire thing.)

+ +

The enter key does nothing if the focus is between commands, or on a +reporter. If the focus is on a variadic input, the enter key adds one +more input slot. If the focus is on a white input slot (one that doesnā€™t +have a reporter in it), then the enter key selects that input slot for +editing; that is, you can type into it, just as if youā€™d clicked on +the input slot. (Of course, if the focus is on an input slot containing +a reporter, you can use the backspace key to delete that reporter, and +then use the enter key to type a value into it.) When you finish typing +the value, type the enter key again to accept it and return to +navigation, or the escape key if you decide not to change the value +already in the slot.

+ +

The space key is used to see a menu of possibilities for the input slot +in focus. It does nothing unless the focus is on a single input slot. If +the focus is on a slot with a pulldown menu of options, then the space +key shows that menu. (If itā€™s a block-colored slot, meaning that only +the choices in the menu can be used, the enter key will do the same +thing. But if itā€™s a white slot with a menu, such as in the turn blocks, +then enter lets you type a value, while space shows the menu.) +Otherwise, the space key shows a menu of variables available at this +point in the script. In either case, use the up and down arrow keys to +navigate the menu, use the enter key to accept the highlighted entry, or +use the escape key to leave the menu without choosing an option.

+ +

{width=ā€147pxā€ +height=ā€163pxā€}Typing any other character key (not +special keys on fancy keyboards that do something other than generating +a character) activates the block search palette. This palette, which +is also accessible by typing control-F or command-F outside the keyboard +editor, or by clicking the search button floating at the top of the +palette, has a text entry field at the top, followed by blocks whose +title text includes what you type. The character key you typed to start +the block search palette is entered into the text field, so you start +with a palette of blocks containing that character. Within the palette, +blocks whose titles start with the text you type come first, then +blocks in which a word of the title starts with the text you type, and +finally blocks in which the text appears inside a word of the title. +Once you have typed enough text to see the block you want, use the arrow +keys to navigate to that block in the palette, then enter to insert that +block, or escape to leave the block search palette without inserting the +block. (When not in the keyboard editor, instead of navigating with the +arrow keys, you drag the block you want into the script, as you would +from any other palette.)

+ +

{width=ā€272pxā€ +height=ā€81pxā€}If you type an arithmetic operator (+-*/) +or comparison operator (<=>) into the block search text box, you can +type an arbitrarily complicated expression, and a collection of +arithmetic operator blocks will be constructed to match:

+ +

As the example shows, you can also use parentheses for grouping, and +non-numeric operands are treated as variables or primitive functions. (A +variable name entered in this way may or may not already exist in the +script. Only round and the ones in the pulldown menu of the sqrt block +can be used as function names.)

+ +

Running the selected script

+ +

Type control-shift-enter to run the script with the editor focus, like +clicking the script.

+ +

Controls on the Stage

+ +

The stage is the area in the top right of the Snap! window in which +sprites move.

+ +

Sprites

+ +

{width=ā€58pxā€ +height=ā€104pxā€}Most sprites can be moved by clicking and +dragging them. (If you have unchecked the draggable checkbox for a +sprite, then dragging it has no effect.) Control-clicking/right-clicking +a sprite shows this context menu:

+ +

The duplicate option makes another sprite with copies of the same +scripts, same costumes, etc., as this sprite. The new sprite starts at a +randomly chosen position different from the original, so you can see +quickly which is which. The new sprite is selected: It becomes the +current sprite, the one shown in the scripting area. The clone option +makes a permanent clone of this sprite, with some shared attributes, and +selects it.

+ +

The delete option deletes the sprite. Itā€™s not just hidden; itā€™s gone +for good. (But you can undelete it by clicking the wastebasket just +below the right edge of the stage.) The edit option selects the sprite. +It doesnā€™t actually change anything about the sprite, despite the name; +itā€™s just that making changes in the scripting area will change this +sprite.

+ +

{width=ā€63pxā€ +height=ā€85pxā€}The move option shows a ā€œmove handleā€ +inside the sprite (the diagonal striped square in the middle):

+ +

You can ordinarily just grab and move the sprite without this option, +but there are two reasons you might need it: First, it works even if the +ā€œdraggableā€ checkbox above the scripting area is unchecked. Second, it +works for part sprites relative to their anchor; ordinarily, dragging a +part moves the entire nested sprite.

+ +

The rotate option displays a rotation menu:

+ +

{width=ā€90pxā€ +height=ā€152pxā€}You can choose one of the four compass +directions in the lower part (the same as in the point in direction +block) or use the mouse to rotate the handle on the dial in 15Ā° +increments.

+ +

{width=ā€63pxā€ +height=ā€81pxā€}The pivot option shows a crosshair inside +the sprite:

+ +

You can click and drag the crosshair anywhere onstage to set the +costumeā€™s pivot point. (If you move it outside the sprite, then turning +the sprite will revolve as well as rotate it around the pivot.) When +done, click on the stage not on the crosshair. Note that, unlike moving +the pivot point in the Paint Editor, this technique does not visibly +move the sprite on the stage. Instead, the values of x position and y +position will change.

+ +

The edit option makes this the selected sprite, highlighting it in the +sprite corral and showing its scripting area. If the sprite was a +temporary clone, it becomes permanent.

+ +

The exportā€¦ option saves, or opens a new browser tab containing, the +XML text representation of the sprite. (Not just its costume, but all of +its costumes, scripts, local variables and blocks, and other +properties.) You can save this tab into a file on your computer, and +later import the sprite into another project. (In some browsers, the +sprite is directly saved into a file.)

+ +

{width=ā€92pxā€ height=ā€139pxā€}Variable watchers

+ +

Right-clicking on a variable watcher shows this menu:

+ +

The first section of the menu lets you choose one of three +visualizations of the watcher:

+ +

{width=ā€222pxā€ +height=ā€31pxā€}

+ +

The first (normal) visualization is for debugging. The second (large) is +for displaying information to the user of a project, often the score in +a game. And the third (slider) is for allowing the user to control the +program behavior interactively. When the watcher is displayed as a +slider, the middle section of the menu allows you to control the range +of values possible in the slider. It will take the minimum value when +the slider is all the way to the left, the maximum value when all the +way to the right.

+ +

The third section of the menu allows data to be passed between your +computer and the variable. The importā€¦ option will read a computer +text file. Its name must end with .txt, in which case the text is read +into the variable as is, or .csv or .json, in which case the text is +converted into a list structure, which will always be a two-dimensional +array for csv (comma-separated values) data, but can be any shape for +json data. The raw dataā€¦ option prevents that conversion to list form. +The exportā€¦ option does the opposite conversion, passing a text-valued +variable value into a .txt file unchanged, but converting a list value +into csv format if the list is one- or two-dimensional, or into json +format if the list is more complicated. (The scalar values within the +list must be numbers and/or text; lists of blocks, sprites, costumes, +etc. cannot be exported.)

+ +

An alternative to using the importā€¦ option is simply to drag the file +onto the Snap! window, in which case a variable will be created if +necessary with the same name as the file (but without the extension).

+ +

If the value of the variable is a list, then the menu will include an +additional blockify option; clicking it will generate an expression with +nested list blocks that, if evaluated, will reconstruct the list. Itā€™s +useful if you imported a list and then want to write code that will +construct the same list later.

+ +

The stage itself

+ +

Control-clicking/right-clicking on the stage background (that is, +anywhere on the stage except on a sprite or watcher) shows the stageā€™s +own context menu:

+ +

{width=ā€79pxā€ +height=ā€81pxā€}The stageā€™s edit option selects the stage, +so the stageā€™s scripts and backgrounds are seen in the scripting area. +Note that when the stage is selected, some blocks, especially the Motion +ones, are not in the palette area because the stage canā€™t move.

+ +

The show all option makes all sprites visible, both in the sense of the +show block and by bringing the sprite onstage if it has moved past the +edge of the stage.

+ +

The picā€¦ option saves, or opens a browser tab with, a picture of +everything on the stage: its background, lines drawn with the pen, and +any visible sprites. What you see is what you get. (If you want a +picture of just the background, select the stage, open its costumes tab, +control-click/right-click on a background, and export it.)

+ +

The pen trails option creates a new costume for the currently selected +sprite consisting of all lines drawn on the stage by the pen of any +sprite. The costumeā€™s rotation center will be the current position of +the sprite.

+ +

If you previously turned on the log pen vectors option, and there are +logged vectors, the menu includes an extra option, svgā€¦, that exports +a picture of the stage in vector format. Only lines are logged, not +color regions made with the fill block.

+ +

The Sprite Corral and Sprite Creation Buttons

+ +

{width=ā€36pxā€ +height=ā€20pxā€}{width=ā€28pxā€ +height=ā€16pxā€}{width=ā€28pxā€ +height=ā€16pxā€}Between the stage and the sprite corral +at the bottom right of the Snap! window is a dark grey bar containing +three buttons at the left and one at the right. The first three are used +to create a new sprite. The first button makes a sprite with just the +turtle costume, with a randomly chosen position and pen color. (If you +hold down the Shift key while clicking, the new spriteā€™s direction will +also be random.) The second button makes a sprite and opens the Paint +Editor so that you can make your own costume for it. (Of course you +could click the first button and then click the paint button in its +costumes tab; this paint button is a shortcut for all that.) Similarly, +the third button uses your camera, if possible, to make a costume for +the new sprite.

+ +

The trash can button +{width=ā€28pxā€ +height=ā€17pxā€} at the right has two uses. You can drag a +sprite thumbnail onto it from the sprite corral to delete that sprite, +or you can click it to undelete a sprite you deleted by accident.

+ +

In the sprite corral, you click on a spriteā€™s ā€œthumbnailā€ picture to +select that sprite (to make it the one whose scripts, costumes, etc. are +shown in the scripting area). You can drag sprite thumbnails (but not +the stage one) to reorder them; this has no special effect on your +project, but lets you put related ones next to each other, for example. +Double-clicking a thumbnail flashes a halo around the actual sprite on +the stage.

+ +

You can right-click/control-click a spriteā€™s thumbnail to get this +context menu:

+ +

{width=ā€65pxā€ +height=ā€106pxā€}The show option makes the sprite visible, +if it was hidden, and also brings it onto the stage, if it had moved +past the stage boundary. The next three options are the same as in the +context menu of the actual sprite on the stage, discussed above.

+ +

The parentā€¦ option displays a menu of all other sprites, showing which +if any is this spriteā€™s parent, and allowing you to choose another +sprite (replacing any existing parent). The release option is shown only +if this sprite is a (permanent, or it wouldnā€™t be in the sprite corral) +clone; it changes the sprite to a temporary clone. (The name is supposed +to mean that the sprite is released from the corral.) The exportā€¦ +option exports the sprite, like the same option on the stage.

+ +

The context menu for the stage thumbnail has only one option, picā€¦, +which takes a picture of everything on the stage, just like the same +option in the context menu of the stage background. If pen trails are +being logged, there will also be an svgā€¦ option.

+ +

If your project includes scenes, then under the stage icon in the sprite +corral will be the scene corral:

+ +

{width=ā€320pxā€ +height=ā€164pxā€}Clicking on a scene will select it; +right-clicking will present a menu in which you can rename, delete, or +export the scene.

+ +

Preloading a Project when Starting Snap!

+ +

There are several ways to include a pointer to a project in the URL when +starting Snap! in order to load a project automatically. You can think +of such a URL as just running the project rather than as running +Snap!, especially if the URL says to start in presentation mode and +click the green flag. The general form is

+ +

http://snap.berkeley.edu/run#verb:project&flag&flagā€¦

+ +

The ā€œverbā€ above can be any of open, run, cloud, present, or dl. The +last three are for shared projects in the Snap! cloud; the first two +are for projects that have been exported and made available anywhere on +the Internet.

+ +

Hereā€™s an example that loads a project stored at the Snap! web site +(not the Snap! cloud!):

+ +

http://snap.berkeley.edu/run#open:http://snap.berkeley.edu/snapsource/Examples/vee.xml

+ +

The project file will be opened, and Snap! will start in edit mode +(with the program visible). Using #run: instead of #open: will start +in presentation mode (with only the stage visible) and will ā€œstartā€ the +project by clicking the green flag. (ā€œStartā€ is in quotation marks +because there is no guarantee that the project includes any scripts +triggered by the green flag. Some projects are started by typing on the +keyboard or by clicking a sprite.)

+ +

If the verb is run, then you can also use any subset of the following +flags:

+ +

&editMode Start in edit mode, not presentation mode.

+ +

&noRun Donā€™t click the green flag.

+ +

&hideControls Donā€™t show the row of buttons above the stage (edit mode, +green flag, pause, stop).

+ +

&lang=fr Set language to (in this example) French.

+ +

&noCloud Donā€™t allow cloud operations from this project (for running +projects from unknown

+ +

sources that include JavaScript code)

+ +

&noExitWarning When closing the window or loading a different URL, donā€™t +show the browser

+ +

ā€œare you sure you want to leave this pageā€ message.

+ +

&blocksZoom=n Like the Zoom blocks option in the Settings menu.

+ +

The last of these flags is intended for use on a web page in which a +Snap! window is embedded.

+ +

Hereā€™s an example that loads a shared (public) project from the Snap! +cloud:

+ +

http://snap.berkeley.edu/run#present:Username=jens&ProjectName=tree%20animation

+ +

(Note that ā€œUsernameā€ and ā€œProjectNameā€ are TitleCased, even though the +flags such as ā€œnoRunā€ are camelCased. Note also that a space in the +project name must be represented in Unicode as %20.) The verb present +behaves like run: it ordinarily starts the project in presentation mode, +but its behavior can be modified with the same four flags as for run. +The verb cloud (yes, we know itā€™s not a verb in its ordinary use) +behaves like open except that it loads from the Snap! cloud rather +than from the Internet in general. The verb dl (short for ā€œdownloadā€) +does not start Snap! but just downloads a cloud-saved project to your +computer as an .xml file. This is useful for debugging; sometimes a +defective project that Snap! wonā€™t run can be downloaded, edited, and +then re-saved to the cloud.

+ +

Mirror Sites

+ +

If the site snap.berkeley.edu is ever unavailable, you can load Snap! +at the following mirror sites:

+ + + +

Appendix A. Snap! color library {#appendix-a.-snap-color-library .ListParagraph}

+ +

{width=ā€557pxā€ +height=ā€209pxā€}The Colors and Crayons library provides +several tools for manipulating color. Although its main purpose is +controlling a spriteā€™s pen color, it also establishes colors as a first +class data type:

+ +

{width=ā€301pxā€ +height=ā€50pxā€}For people who just want colors in their +projects without having to be color experts, we provide two simple +mechanisms: a color number scale with a broad range of continuous +color variation and a set of 100 crayons organized by color family +(ten reds, ten oranges, etc.) The crayons include the block colors:

+ +

{width=ā€688pxā€ +height=ā€106pxā€}For experts, we provide color selection by RGB, HSL, HSV, +X11/W3C names, and variants on those scales.

+ +

Introduction to Color

+ +

{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€43pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}Your computer monitor can display millions +of colors, but you probably canā€™t distinguish that many. For example, +hereā€™s red 57, green 180, blue 200: And hereā€™s red 57, green 182, blue +200: You might be able to tell them apart if you see them side by side: +ā€¦ but maybe not even then.

+ +

Color spaceā€”the collection of all possible colorsā€”is +three-dimensional, but there are many ways to choose the dimensions. RGB +(red-green-blue), the one most commonly used in computers, matches the +way TVs and displays produce color. Behind every dot on the screen are +three tiny lights: a red one, a green one, and a blue one. But if you +want to print colors on paper, your printer probably uses a different +set of three colors: CMY (cyan-magenta-yellow). You may have seen the +abbreviation CMYK, which represents the common technique of adding black +ink to the collection. (Mixing cyan, magenta, and yellow in equal +amounts is supposed to result in black ink, but typically it comes out a +muddy brown instead, because chemistry.) Other systems that try to mimic +human perception are HSL (hue-saturation-lightness) and HSV +(hue-saturation-value). There are many, many more, each designed for a +particular purpose.

+ +

If you are a color professionalā€”a printer, a web designer, a graphic +designer, an artistā€”then you need to understand all this. It can also +be interesting to learn about. For example, there are colors that you +can see but your computer display canā€™t generate. If that intrigues you, +look up color theory in +Wikipedia.

+ +

Crayons and Color Numbers

+ +

{width=ā€576pxā€ +height=ā€79pxā€}But if you just want some colors in your project, we +provide a simple, one-dimensional subset of the available colors. Two +subsets, actually: crayons and color numbers. Hereā€™s the difference:

+ +

{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}The first row shows 100 distinct colors. +They have names; this is pumpkin, and this is denim. Youā€™re supposed to +think of them as a big box of 100 crayons. Theyā€™re arranged in families: +grays, pinks, reds, browns, oranges, etc. But theyā€™re not consistently +ordered within a family; youā€™d be unlikely to say ā€œnext crayonā€ in a +project. (But look at the crayon spiral on page 145.) Instead, youā€™d +think ā€œI want this to look like a really old-fashioned photoā€ and so +youā€™d find sepia as crayon number 33. You donā€™t have to memorize the +numbers! You can find them in a menu with a submenu for each family.

+ +

{width=ā€207pxā€ +height=ā€25pxā€}{width=ā€725pxā€ +height=ā€207pxā€}Or, if you know the crayon name, just .

+ +

{width=ā€556pxā€ +height=ā€29pxā€}The crayon numbers are chosen so that skipping by 10 +gives a sensible box of ten crayons:

+ +

Alternatively, skipping by 5 gives a still-sensible set of twenty +crayons:

+ +

{width=ā€557pxā€ height=ā€29pxā€}

+ +

{width=ā€600pxā€ +height=ā€25pxā€}The set of color numbers is arranged so that each +color number is visually near each of its neighbors. Bright and dark +colors alternate for each family. Color numbers range from 0 to 99, like +crayon numbers, but you can use fractional numbers to get as tiny a step +as you like:

+ +

(ā€œAs tiny as you likeā€ isnā€™t quite true because in the end, your color +has to be rounded to integer RGB values for display.)

+ +

Both of these scales include the range of shades of gray, from black to +white. Since black is the initial pen color, and black isnā€™t a hue, +Scratch and Snap! users would traditionally try to use set color to +escape from black, and it wouldnā€™t work. By including black in the same +scale as other colors, we eliminate the Black Hole problem if people use +only the recommended color scales.

+ +

We are making a point of saying ā€œcolor numberā€ for what was sometimes +called just ā€œcolorā€ in earlier versions of the library, because we now +reserve the name ā€œcolorā€ for an actual color, an instance of the color +data type.
+How to Use the Library

+ +

There are three library blocks specifically about controlling the pen. +They have the same names as three of the primitive Pen blocks:

+ +

{width=ā€582pxā€ +height=ā€30pxā€}

+ +

{width=ā€719pxā€ +height=ā€106pxā€}The first (Pen block-colored) input slot is used to +select which color scale you want to use. (These blocks also allow +reading or setting two block properties that are not colors: the pen +size and its transparency.) The pen reporter requires no other inputs; +it reports the state of the pen in whatever dimension you choose.

+ +

As the last example shows, you canā€™t ask for the pen color in a scale +incompatible with how you set it, unless the block can deduce what you +want from what it knows about the current pen color.

+ +

The change pen block applies only to numeric scales (including vectors +of three or four numbers). It adds its numeric or list input to the +current pen value(s), doing vector (item-by-item) addition for vector +scales.

+ +

{width=ā€719pxā€ +height=ā€106pxā€}The set pen block changes the pen color to +the value(s) you specify. The meaning of the white input slots depends +on which attribute of the pen youā€™re setting:

+ +

In the last example, the number 37 sets the transparency, on the scale +0=opaque, 100=invisible. (All color attributes are on a 0ā€“100 scale +except for RGB components, which are 0ā€“255.) A transparency value can +be combined with any of these attribute scales.

+ +

{width=ā€517pxā€ +height=ā€22pxā€}The library also includes two +constructors and a selector for colors as a data type:

+ +

{width=ā€173pxā€ +height=ā€19pxā€}The latter two are inverses of each +other, translating between colors and their attributes. The color from +blockā€™s attribute menu has fewer choices than the similar set pen block +because you can, for example, set the Red value of the existing pen +color leaving the rest unchanged, but when creating a color out of +nothing you have to provide its entire specification, e.g., all of Red, +Green, and Blue, or the equivalent in other scales. (As youā€™ll see on +the next page, we provide two linear (one-dimensional) color scales +that allow you to specify a color with a single number, at the cost of +including only a small subset of the millions of colors your computer +can generate.) If you have a color and want another color thatā€™s the +same except for one number, as in the Red example, you can use this +block:

+ +

Finally, the library includes the mix block and a helper:

+ +

{width=ā€587pxā€ +height=ā€22pxā€}Weā€™ll have more to say about these after +a detour through color theory.

+ +

Thatā€™s all you have to know about colors! Crayons for specific +interesting ones, color numbers for gradual transformation from one +color to the next. But thereā€™s a bit more to say, if youā€™re interested. +If not, stop here. (But look at the samples of the different scales on +page 145.)
+More about Colors: Fair Hues and Shades

+ +

Several of the three-dimensional arrangements of colors use the concept +of ā€œhue,ā€ which more or less means where a color would appear in a +rainbow (magenta, near the right, is a long +story):

+ +

{width=ā€557pxā€ +height=ā€29pxā€}

+ +

These are called ā€œspectralā€ colors, after the spectrum of rainbow +colors. But these colors arenā€™t equally distributed. Thereā€™s an awful +lot of green, hardly any yellow, and just a sliver of orange. And no +brown at all.

+ +

And this is already a handwave, because the range of colors that can be +generated by RGB monitors doesnā€™t include some of the true spectral +colors. See Spectral +color in Wikipedia for +all the gory details.

+ +

This isnā€™t a problem with the physics of rainbows. Itā€™s in the human eye +and the human brain that certain ranges of wavelength of light waves are +lumped together as named colors. The eye is just ā€œtunedā€ to recognize a +wide range of colors as green. (See Rods and +Cones.) And +different human cultures give names to different color ranges. +Nevertheless, in old Scratch projects, youā€™d say change pen color by 1 +and itā€™d take forever to reach a color that wasnā€™t green.

+ +

{width=ā€575pxā€ +height=ā€29pxā€}For color professionals, there are good +reasons to want to work with the physical rainbow hue layout. But for +amateurs using a simplified, one-dimensional color model, thereā€™s no +reason not to use a more programmer-friendly hue scale:

+ +

{width=ā€140pxā€ +height=ā€130pxā€}In this scale, each of the seven rainbow +colors and brown get an equal share. (Redā€™s looks too small, but thatā€™s +because itā€™s split between the two ends: hue 0 is pure red, brownish +reds are to its right, and purplish reds are wrapped around to the right +end.) We call this scale ā€œfair hueā€ because each color family gets a +fair share of the total hue range. (By the way, you were probably taught +ā€œā€¦ green, blue, indigo, violetā€ in school, but it turns out that color +names were different in Isaac Newtonā€™s day, and the color he called +ā€œblueā€ is more like modern cyan, while his ā€œindigoā€ is more like modern +blue. See Wikipedia Indigo.)

+ +

{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}{width=ā€23pxā€ +height=ā€23pxā€}Our color number scale is based on fair +hues, adding a range of grays from black (color number 0) to white +(color number14) and also adding shades of the spectral colors. (In +color terminology, a shade is a darker version of a color; a lighter +version is called a tint.) Why do we add shades but not tints? Partly +because I find shades more exciting. A shade of red can be dark candy +apple red or maroon , but a tint is just some kind of pink . This +admitted prejudice is supported by an objective fact: Most projects are +made on a white background, so dark colors stand out better than light +ones.

+ +

{width=ā€576pxā€ +height=ā€145pxā€}So, in our color number scale, color +numbers 0 to 14 are kinds of gray; the remaining color numbers go +through the fair hues, but alternating full-strength colors with shades.

+ +

This chart shows how the color scales discussed so far are related. Note +that all scales range from 0 to 100; the fair hues scale has been +compressed in the chart so that similar colors line up vertically. (Its +dimensions are different because it doesnā€™t include the grays at the +left. Since there are eight color families, the pure, named fair hues +are at multiples of 100/8=12.5, starting with red=0.)

+ +

{width=ā€178pxā€ +height=ā€104pxā€}White is crayon 14 and color number 14. +This value was deliberately chosen not to be a multiple of 5 so that +the every-fifth-crayon and every-tenth-crayon selections donā€™t include +it, so that all of the crayons in those smaller boxes are visible +against a white stage background.

+ +

Among purples, the official spectral violet (crayon 90) is the end of +the spectrum. Magenta, brighter than violet, isnā€™t a spectral color at +all. (In the picture at the left, the top part is the spectrum of white +light spread out through a prism; the middle part is a photograph of a +rainbow, and the bottom part is a digital simulation of a rainbow.) +Magenta is a mixture of red and blue. (attribution: Wikipedia user +Andys. CC BY-SA.)

+ +

The light gray at color number 10 is slightly different from crayon 10 +just because of roundoff in computing crayon values. Color number 90 is +different from crayon 90 because the official RGB violet (equal parts +red and blue) is actually lighter than spectral violet. The purple +family is also unusual because magenta, crayon and color number 95, is +lighter than the violet at 90. In other families, the color numbers, +crayons, and (scaled) fair hues all agree at multiples of ten. These +multiple-of-ten positions are the standard RGB primary and secondary +colors, e.g., the yellow at color number 50 is (255, 255, 0) in RGB. +(Gray, brown, and orange donā€™t have such simple RGB settings.)

+ +

The color numbers at odd multiples of five are generally darker shades +than the corresponding crayons. The latter are often official named +shades, e.g., teal, crayon 65, is a half-intensity shade of cyan. The +odd-five color numbers, though, are often darker, since they are +chosen to be the darkest color in a given family thatā€™s visibly +different from black. The pink at color number 15, though, is quite +different from crayon 15, because the former is a pure tint of red, +whereas the crayon, to get a more interesting pink, has a little magenta +mixed in. Color numbers at multiples of five are looked up in a table; +other color values are determined by linear interpolation in RGB space. +(Crayons are of course all found by table lookup.)

+ +

The from color block behaves specially when you ask for the color +number of a color. Most colors donā€™t exactly match a color number, and +for other attributes of a color (crayon number, X11 name) you donā€™t get +an answer unless the color exactly matches one of the names or numbers +in that attribute. But for color number, the block tries to find the +nearest color number to the color you specify. The result will be only +approximate; you canā€™t use the number you get to recreate the input +color. But you can start choosing nearby color numbers as you animate +the sprite.

+ +

Perceptual Spaces: HSV and HSL

+ +

{width=ā€71pxā€ +height=ā€69pxā€}RGB is the right way to think about colors +if youā€™re building or programming a display monitor; CMYK is the right +way if youā€™re building or programming a color printer. But neither of +those coordinate systems is very intuitive if youā€™re trying to +understand what color you see if, for example, you mix 37% red light, +52% green, and 11% blue. The hue scale is one dimension of most +attempts at a perceptual scale. The square at the right has pale blues +along the top edge, dark blues along the right edge, various shades of +gray toward the left, black at the bottom, and pure spectral blue in the +top right corner. Although no other point in the square is pure blue, +you can tell at a glance that no other spectral color is mixed with the +blue.

+ +

{width=ā€258pxā€ +height=ā€114pxā€}Aside from hue, the other two dimensions +of a color space have to represent how much white and/or black is mixed +with the spectral color. (Bear in mind that ā€œmixing blackā€ is a metaphor +when it comes to monitors. There really is black paint, but thereā€™s no +such thing as black light.) One such space, HSV, has one dimension for +the amount of color (vs. white), called saturation, and one for the +amount of black, imaginatively called value. HSV stands for +Hue-Saturation-Value. (Value is also called brightness.) The value +is actually measured backward from the above description; that is, if +value is 0, the color is pure black; if value is 100, then a saturation +of 0 means all white, no spectral color; a saturation of 100 means no +white at all. In the square in the previous paragraph, the x axis is +the saturation and the y axis is the value. The entire bottom edge is +black, but only the top left corner is white. HSV is the traditional +color space used in Scratch and Snap!. Set pen color set the hue; set +pen shade set the value. There was originally no Pen block to set the +saturation, but thereā€™s a set brightness effect Looks block to control +the saturation of the spriteā€™s costume. (I speculate that the Scratch +designers, like me, thought tints were less vivid than shades against a +white background, so they made it harder to control tinting.)

+ +

{width=ā€150pxā€ +height=ā€28pxā€}{width=ā€149pxā€ +height=ā€26pxā€}{width=ā€73pxā€ +height=ā€73pxā€}But if youā€™re looking at colors on a +computer display, HSV isnā€™t really a good match for human perception. +Intuitively, black and white should be treated symmetrically. This is +the HSL (hue-saturation-lightness) color space. Saturation, in HSL, is +a measure of the grayness or dullness of a color (how close it comes +to being on a black-and-white scale) and lightness measures +spectralness with pure white at one end, pure black at the other end, +and spectral color in the middle. The saturation number is actually +the opposite of grayness: 0 means pure gray, and 100 means pure spectral +color, provided that the lightness is 50, midway between black and +white. Colors with lightness other than 50 have some black or white +mixed in, but saturation 100 means that the color is as fully saturated +as it can be, given the amount of white or black needed to achieve that +lightness. Saturation less than 100 means that both white and black +are mixed with the spectral color. (Such mixtures are called tones of +the spectral color. Perceptually, colors with saturation 100% donā€™t look +gray: but colors with saturation 75% do:

+ +

Note that HSV and HSL both have a dimension called ā€œsaturation,ā€ but +theyā€™re not the same thing! In HSV, ā€œsaturationā€ means non-whiteness, +whereas in HSL it means non-grayness (vividness).

+ +

More fine print: Itā€™s misleading to talk about the spectrum of light +wavelengths as if it were the same as perceived hue. If your computer +display is showing you a yellow area, for example, itā€™s doing it by +turning on its red and green LEDs over that area, and what hits your +retina is still two wavelengths of light, red and green, superimposed. +You could make whatā€™s perceptually the same yellow by using a single +intermediate wavelength. Your eye and brain donā€™t distinguish between +those two kinds of yellow. Also, your brain automatically adjusts +perceived hue to correct for differences in illumination. When you place +a monochrome object so that itā€™s half in sunlight and half in the shade, +you see it as one even though whatā€™s reaching your eyes from the two +regions differs a lot. And, sadly, itā€™s HSL whose use of ā€œsaturationā€ +disagrees with the official international color vocabulary +standardization committee. I learned all this from this +tutorial, which you might find +more coherent than jumping around Wikipedia if youā€™re interested.

+ +

{width=ā€158pxā€ +height=ā€81pxā€}Although traditional Scratch and Snap! +use HSV in programs, they use HSL in the color picker. The horizontal +axis is hue (fair hue, in this version) and the vertical axis is +lightness, the scale with black at one end and white at the other end. +It would make no sense to have only the bottom half of this selector +(HSV Value) or only the top half (HSV Saturation). And, given that you +can only fit two dimensions on a flat screen, it makes sense to pick HSL +saturation (vividness) as the one to keep at 100%. (In this fair-hue +picker, some colors appear twice: ā€œspectralā€ (50% lightness) browns as +shades (ā‰ˆ33% lightness) of red or orange, and shades of those browns.)

+ +

{width=ā€19pxā€ +height=ā€19pxā€}{width=ā€18pxā€ +height=ā€18pxā€}Software that isnā€™t primarily about +colors (so, not including Photoshop, for example) typically use HSV or +HSL, with web-based software more likely to use HSV because thatā€™s +whatā€™s built into the JavaScript programming language provided by +browsers. But if the goal is to model human color perception, neither of +these color spaces is satisfactory, because they assume that all +full-intensity spectral colors are equally bright. But if youā€™re like +most people, you see spectral yellow as much brighter than spectral blue +. There are better perceptual color spaces with names like L*u*v* and +L*a*b* that are based on research with human subjects to determine +true perceived brightness. Wikipedia explains all this and more at HSL +and HSV, where they +recommend ditching both of these simplistic color spaces.

+ +

Mixing Colors

+ +

Given first class colors, the next question is, what operations apply to +them, the way arithmetic operators apply to numbers and higher order +functions apply to lists? The equivalent to adding numbers is mixing +colors, but unfortunately there isnā€™t a simple answer to what that +means.

+ +

{width=ā€417pxā€ +height=ā€54pxā€}The easiest kind of color mixing to understand is +additive mixing, which is what happens when you shine two colored +lights onto a (white) wall. Itā€™s also what happens in your computer +screen, where each dot (pixel) of an image is created by a tiny red +light, a tiny green light, and a tiny blue light that can be combined at +different strengths to make different colors. Essentially, additive +mixing of two colors is computed by adding the two red components, the +two green components, and the two blue components. Itā€™s not quite that +simple only because each component of the result must be in the range 0 +to 255. So, red (255, 0, 0) mixed with green (0, 255, 0) gives (255, +255, 0), which is yellow. But red (255, 0, 0) plus yellow (255, 255, 0) +canā€™t give (510, 255, 0). Just limiting the red in the result to 255 +would mean that red plus yellow is yellow, which doesnā€™t make sense. +Instead, if the red value has to be reduced by half (from 510 to 255), +then all three values must be reduced by half, so the result is (255, +128, 0), which is orange. (Half of 255 is 127.5, but each RGB value must +be an integer.)

+ +

{width=ā€431pxā€ +height=ā€53pxā€}A different kind of color mixing based on light is done +when different colored transparent plastic sheets are held in front of a +white light, as is done in theatrical lighting. In that situation, the +light that gets through both filters is what remains after some light is +filtered out by the first one and some of whatā€™s left is filtered out by +the second one. In red-green-blue terms, a red filter filters out green +and blue; a yellow filter allows red and green through, filtering out +blue. But there isnā€™t any green light for the yellow filter to pass; it +was filtered out by the red filter. Each filter can only remove light, +not add light, so this is called subtractive mixing:

+ +

Perhaps confusingly, the numerical computation of subtractive mixing is +done by multiplying the RGB values, taken as fractions of the maximum +255, so red (1, 0, 0) times yellow (1, 1, 0) is red again.

+ +

Those are both straightforward to compute. Much, much more complicated +is trying to simulate the result of mixing paints. Itā€™s not just that +weā€™d have to compute a more complicated function of the red, green, and +blue values; itā€™s that RGB values (or any other three-dimensional color +space) are inadequate to describe the behavior of paints. Two paints can +look identical, and have the same RGB values, but may still behave very +differently when mixed with other colors. The differences are mostly due +to the chemistry of the paints, but are also affected by exactly how the +colors are mixed. The mixing is mostly subtractive; red paint absorbs +most of the colors other than red, so whatā€™s reflected off the surface +is whatever isnā€™t absorbed by the colors being mixed. But there can be +an additive component also.

+ +

{width=ā€720pxā€ +height=ā€84pxā€}The proper mathematical abstraction to describe a paint +is a reflectance graph, like this:

+ +

(These arenā€™t paints, but minerals, and one software-generated spectrum, +from the US Geological Surveyā€™s Spectral +Library. +The details donā€™t matter, just the fact that a graph like these gives +much more information than three RGB numbers.) To mix two paints +properly, you multiply the y values (as fractions) at each matching +x coordinate of the two graphs.

+ +

{width=ā€444pxā€ +height=ā€55pxā€} Having said all that, the mix block takes +the colors it is given as inputs and converts them into what we hope are +typical paint reflectance spectra that would look like those colors, +and then mixes those spectra and converts back to RGB.

+ +

But unlike the other two kinds of mixing, in this case we canā€™t say that +these colors are ā€œthe right answerā€; what would happen with real paints +depends on their chemical composition and how theyā€™re mixed. There are +three more mixing options, but these three are the ones that correspond +to real-world color mixing.

+ +

{width=ā€417pxā€ +height=ā€63pxā€}The mix block will accept any number of +colors, and will mix them in equal proportion. If (for any kind of +mixing) you want more of one color than another, use the color at weight +block to make a ā€œweighted colorā€:

+ +

{width=ā€496pxā€ +height=ā€41pxā€}This mixes four parts red paint to one +part green paint. All colors in a mixture can be weighted:

+ +

(Thanks to Scott +Burns for his help in +understanding paint mixing, along with David +Briggsā€™s tutorial. Remaining +mistakes are bhā€™s.)

+ +

tl;dr

+ +

{width=ā€186pxā€ +height=ā€213pxā€}{width=ā€214pxā€ +height=ā€218pxā€}For normal people, Snap! provides three +simple, one-dimensional scales: [crayons]{.underline} for specific +interesting colors, [color numbers]{.underline} for a continuum of +high-contrast colors with a range of hues and shading, and [fair +hues]{.underline} for a continuum without shading. For color nerds, it +provides three-dimensional color spaces RGB, HSL, HSV, and fair-hue +variants of the latter two. We recommend ā€œfair HSLā€ for zeroing in on a +desired color.

+ +

{width=ā€147pxā€ +height=ā€177pxā€}

+ +

{width=ā€212pxā€ height=ā€218pxā€}{width=ā€198pxā€ height=ā€213pxā€}{width=ā€184pxā€ height=ā€215pxā€} Subappendix: Geeky details on fair hue

+ +

{width=ā€599pxā€ +height=ā€240pxā€}The left graph shows that, unsurprisingly, all of the +brown fair hues make essentially no progress in real hue, with the +orange-brown section actually a little retrograde, since browns are +really shades of orange and so the real hues overlap between fair browns +and fair oranges. Green makes up some of the distance, because there are +too many green real hues and part of the goal of the fair hue scale is +to squeeze that part of the hue spectrum. But much of the catching up +happens very quickly, between pure magenta at fair hue 93.75 and the +start of the purple-red section at fair hue 97. This abrupt change is +unfortunate, but the alternatives involve either stealing space from red +or stealing space from purple (which already has to include both +spectral violet and RGB magenta). The graph has discontinuous derivative +at the table-lookup points, of which there are two in each color family, +one at the pure-named-RGB colors at multiples of 12.5, and the other +roughly halfway to the next color family, except for the purple +family, which has lookup points at 87.5 (approximate spectral violet), +93.75 (RGB magenta), and 97 (turning point toward the red family). (In +the color picker, blue captures cyan and purple space in dark shades. +This, too, is an artifact of human vision.)

+ +

The right graph shows the HSV saturation and value for all the fair +hues. Saturation is at 100%, as it should be in a hue scale, except for +a very slight drop in part of the browns. (Browns are shades of orange, +not tints, so one would expect full saturation, except that some of the +browns are actually mixtures with related hues.) But value, also as +expected, falls substantially in the browns, to a low of about 56% +(halfway to black) for the ā€œpureā€ brown at 45Ā° (fair hue 12.5). But the +curve is smooth, without inflection points other than that minimum-value +pure brown.

+ +

ā€œFair saturationā€ and ā€œfair valueā€ are by definition 100% for the entire +range of fair hues. This means that in the browns, the real saturation +and value are the product (in percent) of the innate shading of the +specific brown fair hue and the userā€™s fair saturation/value setting. +When the userā€™s previous color setting was in a real scale and the new +setting is in a fair scale, the program assumes that the previous +saturation and value were entirely user-determined; when the previous +color setting was in a brown fair hue and the new setting is also in a +fair scale, the program remembers the userā€™s intention from the previous +setting. (Internal calculations are based on HSV, even though we +recommend HSL to users, because HSV comes to us directly from the +JavaScript color management implementation.) This is why the set pen +block includes options for ā€œfair saturationā€ and so on.

+ +

{width=ā€575pxā€ +height=ā€36pxā€}For the extra-geeky, here are the exact +table lookup points (fair hue, [0,100]):

+ +

and here are the RGB settings at those points:

+ +

{width=ā€574pxā€ height=ā€132pxā€} Subappendix: Geeky details on color numbers

+ +

{width=ā€200pxā€ +height=ā€220pxā€}Here is a picture of integer color +numbers, but remember that color numbers are continuous. (As usual, +ā€œcontinuousā€ values are ultimately converted to integer RGB values, so +thereā€™s really some granularity.) Color numbers 0-14 are continuously +varying grayscale, from 0=black to 14=white. Color numbers 14+Īµ to 20 +are linearly varying shades of pink, with RGB Red at color number 20.

+ +

Beyond that point, in each color family, the multiple of ten color +number in the middle is the RGB standard color of that family, in which +each component is either 255 or 0. (Exceptions are brown, which is of +course darker than any of those colors; orange, with its green component +half-strength: [255, 127, 0]; and violet, discussed below.) The +following multiple of five is the number of the darkest color in that +family, although not necessarily the same hue as the multiple of ten +color number. Color numbers between the multiple of ten and the +following multiple of five are shades of colors entirely within the +family. Color numbers in the four before the multiple of ten are +mixtures of this family and the one before it. So, for example, in the +green family, we have

+ +

55 Darkest yellow.

+ +

(55, 60) shades of yellow-green mixtures. As the color number increases, +both the hue and the lightness (or value, depending on your religion) +increase, so we get brighter and greener colors.

+ +

60 Canonical green, [0, 255, 0], whose W3C color name is ā€œlime,ā€ not +ā€œgreen.ā€

+ +

(60, 65) Shades of green. No cyan mixed in.

+ +

65 Darkest green.

+ +

(65,70) Shades of green-cyan mixtures.

+ +

In the color number chart, all the dark color numbers look a lot like +black, but theyā€™re quite different. Here are the darkest colors in each +color number family.

+ +

{width=ā€133pxā€ +height=ā€133pxā€}Darkest yellow doesnā€™t look entirely +yellow. You might see it as greenish or brownish. As it turns out, the +darkest color that really looks yellow is hardly dark at all. This color +was hand-tweaked to look neither green nor brown to me, but ymmv.

+ +

In some families, the center+5 crayon is an important named darker +version of the center color: In the red family, [128, 0, 0] is +ā€œmaroon.ā€ In the cyan family, [0, 128, 128] is ā€œteal.ā€ An early +version of the color number scale used these named shades as the +center+5 color number also. But on this page we use the word ā€œdarkestā€ +advisedly: You canā€™t find a darker shade of this family anywhere in the +color number scale, but you can find lighter shades. Teal is color +number 73.1, ($70 + 5 \bullet \frac{255 - 128}{255 - 50}$), because +darkest cyan, color 75, is [0, 50, 50]. The color number for maroon is +left as an exercise for the reader.

+ +

The purple family is different from the others, because it has to +include both spectral violet and extraspectral RGB magenta. Violet is +usually given as RGB [128, 0, 255], but thatā€™s much brighter than the +violet in an actual spectrum (see page 142). We use [80, 0, 90], a +value hand-tweaked to look as much as possible like the violet in +rainbow photos, as color number 90. (Crayon 90 is [128, 0, 255].) +Magenta, [255, 0, 255], is color number 95. This means that the colors +get brighter, not darker, between 90 and 95. The darkest violet is +actually color number 87.5, so itā€™s bluer than standard violet, but +still plainly a purple and not a blue. Itā€™s [39,0,76]. Itā€™s not +hand-tweaked; itā€™s a linear interpolation between darkest blue, [0, 0, +64], and the violet at color number 90. I determined by experiment that +color number 87.5 is the darkest one thatā€™s still unambiguously purple. +(According to Wikipedia, ā€œvioletā€ names only the spectral color, while +ā€œpurpleā€ is the name of the whole color family.)

+ +

Here are the reference points for color numbers that are multiples of +five, except for item 4, which is used for color 14, not color 15:

+ +

{width=ā€440pxā€ +height=ā€123pxā€}

+ +

Appendix B. APL features {#appendix-b.-apl-features .ListParagraph}

+ +

The book A Programming Language was published by mathematician Kenneth +E. Iverson in 1962. He wanted a formal language that would look like +what mathematicians write on chalkboards. The then-unnamed language +would later take its name from the first letters of the words in the +bookā€™s title. It was little-known until 1964, when a formal description +of the just-announced IBM System/360 in the IBM Systems Journal used +APL notation. (Around the same time, Iversonā€™s associate Adin Falkoff +gave a talk on APL to a New York Association for Computing Machinery +chapter, with an excited 14-year-old Brian Harvey in the audience.) But +it wasnā€™t until 1966 that the first public implementation of the +language for the System/360 was published by IBM. (It was called +ā€œAPL\360ā€ because the normal slash character / represents the ā€œreduceā€ +operator in APL, while backslash is ā€œexpand.ā€)

+ +

The crucial idea behind APL is that mathematicians think about +collections of numbers, one-dimensional vectors and two-dimensional +matrices, as valid objects in themselves, what computer scientists +later learned to call ā€œfirst class data.ā€ A mathematician who wants to +add two vectors writes v~1~ + v~2~, not ā€œfor i = 1 to +length(v1), result[i]=v1[i]+v2[i].ā€ Same for a programmer using +APL.

+ +

There are three kinds of function in APL: scalar functions, mixed +functions, and operators. A scalar function is one whose natural +domain is individual numbers or text characters. A mixed function is +one whose domain includes arrays (vectors, matrices, or +higher-dimensional collections). In Snap!, scalar functions are +generally found in the green Operators palette, while mixed functions +are in the red Lists palette. The third category, confusingly for +Snap! users, is called operators in APL, but corresponds to what we +call higher order functions: functions whose domain includes functions.

+ +

Snap! hyperblocks are scalar functions that behave like APL scalar +functions: they can be called with arrays as inputs, and the underlying +function is applied to each number in the arrays. (If the function is +monadic, meaning that it takes one input, then thereā€™s no complexity +to this idea. Take the square root of an array, and you are taking the +square root of each number in the array. If the function is dyadic, +taking two inputs, then the two arrays must have the same shape. Snap! +is more forgiving than APL; if the arrays donā€™t agree in number of +dimensions, called the rank of the array, the lower-rank array is +matched repeatedly with subsets of the higher-rank one; if they donā€™t +agree in length along one dimension, the result has the shorter length +and some of the numbers in the longer-length array are ignored. An +exception in both languages is that if one of the two inputs is a +scalar, then it is matched with every number in the other array input.)

+ +

As explained in Section I.G, this termwise extension of scalar functions +is the main APL-like feature built into Snap! itself. We also include +an extension of the item block to address multiple dimensions, an +extension to the length block with five list functions from APL, and a +new primitive reshape block. The APL library extends the implementation +of APL features to include a few missing scalar functions and several +missing mixed functions and operators.

+ +

Programming in APL really is very different in style from programming +in other languages, even Snap!. This appendix canā€™t hope to be a +complete reference for APL, let alone a tutorial. If youā€™re interested, +find one of those in a library or a (probably used) bookstore, read it, +and do the exercises. Sorry to sound like a teacher, but the notation +is sufficiently weird as to take a lot of practice before you start to +think in APL.

+ +

A note on versions: There is a widely standardized APL2, several +idiosyncratic extensions, and a successor language named J. The latter +uses plain ASCII characters, unlike the ones with APL in their names, +which use the mathematicianā€™s character set, with Greek letters, +typestyles (boldface and/or italics in books; underlined, upper case, or +lower case in APL) as loose type declarations, and symbols not part of +anyoneā€™s alphabet, such as āŒŠ for floor and āŒˆ for ceiling. To use the +original APL, you needed expensive special computer terminals. (This was +before you could download fonts in software. Today the more unusual APL +characters are in Unicode at U+2336 to U+2395.) The character set was +probably the main reason APL didnā€™t take over the world. APL2 has a lot +to recommend it for Snap! users, mainly because it moves from the +original APL idea that all arrays must be uniform in dimension, and the +elements of arrays must be numbers or single text characters, to our +idea that a list can be an element of another list, and that such +elements donā€™t all have to have the same dimensions. Nevertheless, its +mechanism for allowing both old-style APL arrays and more general +ā€œnested arraysā€ is complicated and hard for an APL beginner (probably +all but two or three Snap! users) to understand. So we are starting +with plain APL. If it turns out to be wildly popular, we may decide +later to include APL2 features.

+ +

Here are some of the guiding ideas in the design of the APL library:

+ +

{width=ā€427pxā€ +height=ā€50pxā€}Goal:Ā  Enable interested Snap! users +to learn the feel and style of APL programming. Itā€™s really worth the +effort. For example, we didnā€™t hyperize the = block because Snap! +users expect it to give a single yes-or-no answer about the equality of +two complete structures, whatever their types and shapes. In APL, = is a +scalar function; it compares two numbers or two characters. How could +APL users live without the ability to ask if two structures are equal? +Because in APL you can say āˆ§/,a=b to get that answer. Reading from +right to left, a=b reports an array of Booleans (represented in APL as 0 +for False, 1 for True); the comma operator turns the shape of the array +into a simple vector; and āˆ§/ means ā€œreduce with andā€; ā€œreduceā€ is +our combine function. That six-character program is much less effort +than the equivalent

+ +

{width=ā€95pxā€ +height=ā€20pxā€}in Snap!. Note in passing that if you +wanted to know how many corresponding elements of the two arrays are +equal, youā€™d just use +/ instead of āˆ§/. Note also that our APLish +blocks are a little verbose, because they include up to three notations +for the function: the usual Snap! name (e.g., flatten), the name APL +programmers use when talking about it (ravel), and, in yellow type, the +symbol used in actual APL code (,). Weā€™re not consistent about it; seems +self-documenting. And LCM (and) is different even though it has two +names; it turns out that if you represent Boolean values as 0 and 1, +then the algorithm to compute the least common multiple of two integers +computes the and function if the two inputs happen to be Boolean. +Including the APL symbols serves two purposes: the two or three Snap! +users whoā€™ve actually programmed in APL will be sure what function +theyā€™re using, but more importantly, the ones who are reading an APL +tutorial while building programs in Snap! will find the block that +matches the APL theyā€™re reading.
+
+Goal:Ā  Bring the best and most general APL ideas into ā€œmainstreamā€ +Snap! programming style. Media computation, in particular, becomes +much simpler when scalar functions can be applied to an entire picture +or sound. Yes, map provides essentially the same capability, but the +notation gets complicated if you want to map over columns rather than +rows. Also, Snap! lists are fundamentally one-dimensional, but real +data often have more dimensions. A Snap! programmer has to be thinking +all the time about the convention that we represent a matrix as a list +of rows, each of which is a list of individual cells. That is, row 23 of +a spreadsheet is item 23 of spreadsheet, but column 23 is map (item 23 +of _) over spreadsheet. APL treats rows and columns more +symmetrically.
+
+Non-goal:Ā  Allow programs written originally in APL to run in +Snap! essentially unchanged.Ā  For example, in APL the atomic text +unit is a single character, and strings of characters are lists. We +treat a text string as scalar, and that isnā€™t going to change. Because +APL programmers rarely use conditionals, instead computing functions +involving arrays of Boolean values to achieve the same effect, the +notation they do have for conditionals is primitive (in the sense of +Paleolithic, not in the sense of built in). Weā€™re not changing ours.
+
+Non-goal:Ā  Emulate the terse APL syntax. Itā€™s too bad, in a way; as +noted above, the terseness of expressing a computation affects APL +programmersā€™ sense of whatā€™s difficult and what isnā€™t. But you canā€™t say +ā€œterseā€ and ā€œblock languageā€ in the same sentence. Our whole raison +dā€™ĆŖtre is to make it possible to build a program without having to +memorize the syntax or the names of functions, and to allow those names +to be long enough to be self-documenting. And APLā€™s syntax has its own +issues, of which the biggest is that itā€™s hard to use functions with +more than two inputs; because most mathematical dyadic functions use +infix notation (the function symbol between the two inputs), the notion +of ā€œleft argumentā€ and ā€œright argumentā€ is universal in APL +documentation. The thing people most complain about, that there is no +operator precedence (like the multiplication-before-addition rule in +normal arithmetic notation), really doesnā€™t turn out to be a problem. +Function grouping is strictly right to left, so 2Ɨ3+4 means two times +seven, not six plus four. That takes some getting used to, but it really +doesnā€™t take long if you immerse yourself in APL. The reason is that +there are too many infix operators for people to memorize a precedence +table. But in any case, block notation eliminates the problem, +especially with Snap!ā€™s zebra coloring. You can see and control the +grouping by which block is inside which other blockā€™s input slot. +Another problem with APLā€™s syntax is that it bends over backward not to +have reserved words, as opposed to Fortran, its main competition back +then. So the dyadic ā—‹ ā€œcircular functionsā€ function uses the left +argument to select a trig function. 1ā—‹x is sin(x), 2ā—‹x is +cos(x), and so on. ā€¾1ā—‹x is arcsin(x). Whatā€™s 0ā—‹x? Glad you +asked; itā€™s$\ \sqrt{1 - x^{2}}$.

+ +

Boolean values

+ +

Snap! uses distinct Boolean values true and false that are different +from other data types. APL uses 1 and 0, respectively. The APL style of +programming depends heavily on doing arithmetic on Booleans, although +their conditionals insist on only 0 or 1 in a Boolean input slot, not +other numbers. Snap! arithmetic functions treat false as 0 and true +as 1, so our APL library tries to report Snap! Boolean values from +predicate functions.

+ +

{width=ā€550pxā€ height=ā€106pxā€}Scalar functions

+ +

{width=ā€246pxā€ +height=ā€21pxā€}These are the scalar functions in the APL +library. Most of them are straightforward to figure out. The scalar = +block provides an APL-style version of = (and other exceptions) as a +hyperblock that extends termwise to arrays. Join, the only non-predicate +non-hyper scalar primitive, has its own scalar join block. 7 deal 52 +reports a random vector of seven numbers from 1 to 52 with no +repetitions, as in dealing a hand of cards. Signum of a number reports 1 +if the number is positive, 0 if itā€™s zero, or -1 if itā€™s negative. Roll +6 reports a random roll of a six-sided die. To roll 8 dice, use , which +would look much more pleasant as ?8ā“6. But perhaps our version is more +instantly readable by someone who didnā€™t grow up with APL. All the +library functions have help messages available.

+ +

Mixed functions

+ +

Mixed functions include lists in their natural domain or range. That is, +one or both of its inputs must be a list, or it always reports a list. +Sometimes both inputs are naturally lists; sometimes one input of a +dyadic mixed function is naturally a scalar, and the function treats a +list in that input slot as an implicit map, as for scalar functions. +This means you have to learn the rule for each mixed function +individually.

+ +

{width=ā€410pxā€ +height=ā€106pxā€}{width=ā€102pxā€ +height=ā€18pxā€}The shape of function takes any input and +reports a vector of the maximum size of the structure along each +dimension. For a vector, it returns a list of length 1 containing the +length of the input. For a matrix, it returns a two-item list of the +number of rows and number of columns of the input. And so on for higher +dimensions. If the input isnā€™t a list at all, then it has zero +dimensions, and shape of reports an empty vector.

+ +

Equivalent to the dimensions of primitive, as of 6.6.

+ +

{width=ā€100pxā€ +height=ā€18pxā€}{width=ā€195pxā€ +height=ā€18pxā€}Rank of isnā€™t an actual APL primitive, +but the composition ā“ā“ (shape of shape of a structure), which reports +the number of dimensions of the structure (the length of its shape +vector), is too useful to omit. (Itā€™s very easy to type the same +character twice on the APL keyboard, but less easy to drag blocks +together.) Equivalent to the rank of primitive, as of 6.6.

+ +

{width=ā€703pxā€ +height=ā€80pxā€}Reshape takes a shape vector (such as +shape might report) on the left and any structure on the right. It +ignores the shape of the right input, stringing the atomic elements into +a vector in row-major order (that is, all of the first row left to +right, then all of the second row, etc.). (The primitive reshape takes +the inputs in the other order.) It then reports an array with the shape +specified by the first input containing the items of the second:

+ +

{width=ā€631pxā€ +height=ā€100pxā€}If the right input has more atomic +elements than are required by the left-input shape vector, the excess +are ignored without reporting an error. If the right input has too few +atomic elements, the process of filling the reported array starts again +from the first element. This is most useful in the specific case of an +atomic right input, which produces an array of any desired shape all of +whose atomic elements are equal. But other cases are sometimes useful +too:

+ +

{width=ā€529pxā€ +height=ā€120pxā€}
+{width=ā€138pxā€ +height=ā€18pxā€}Flatten takes an arbitrary structure as +input and reports a vector of its atomic elements in row-major order. +Lispians call this flattening the structure, but APLers call it ā€œravelā€ +because of the metaphor of pulling on a ball of yarn, so what they +really mean is ā€œunravel.ā€ (But the snarky sound of that is uncalled-for, +because a more advanced version that we might implement someday is more +like raveling.) One APL idiom is to apply this to a scalar in order to +turn it into a one-element vector, but we canā€™t use it that way because +you canā€™t type a scalar value into the List-type input slot. Equivalent +to the primitive flatten of block.

+ +

{width=ā€323pxā€ +height=ā€24pxā€}

+ +

{width=ā€692pxā€ +height=ā€56pxā€}Catenate is like our primitive append, +with two differences: First, if either input is a scalar, it is treated +like a one-item vector. Second, if the two inputs are of different rank, +the catenate function is recursively mapped over the higher-rank input:

+ +

{width=ā€51pxā€ +height=ā€24pxā€}Catenate vertically is similar, but it adds new rows +instead of adding new columns.

+ +

{width=ā€609pxā€ +height=ā€100pxā€}Integers (I think thatā€™s what it stands +for, although APLers just say ā€œiotaā€) takes a positive integer input and +reports a vector of the integers from 1 to the input. This is an example +of a function classed as ā€œmixedā€ not because of its domain but because +of its range. The difference between this block and the primitive +numbers from block is in its treatment of lists as inputs. Numbers from +is a hyperblock, applying itself to each item of its input list:

+ +

{width=ā€578pxā€ +height=ā€80pxā€}Iota has a special meaning for list +inputs: The input must be a shape vector; the result is an array with +that shape in which each item is a list of the indices of the cell along +each dimension. A picture is worth 10^3^ words, but Snap! isnā€™t so +good at displaying arrays with more than two dimensions, so here we +reduce each cellā€™s index list to a string:

+ +

{width=ā€142pxā€ +height=ā€24pxā€}

+ +

{width=ā€571pxā€ +height=ā€106pxā€}Dyadic iota is like the index of primitive except for its +handling of multi-dimensional arrays. It looks only for atomic elements, +so a vector in the second input doesnā€™t mean to search for that vector +as a row of a matrix, which is what it means to index of, but rather to +look separately for each item of the vector, and report a list of the +locations of each item. If the first input is a multi-dimensional array, +then the location of an item is a vector with the indices along each +row.

+ +

In this example, the 4 is in the second row, second column. (This is +actually an extension of APL iota, which is more like a hyperized index +of.) Generalizing, if the rank of the second input is less than the rank +of the first input by two or more, then iota looks for the entire second +input in the first input. The reported position is a vector +{width=ā€561pxā€ +height=ā€34pxā€}whose length is equal to the difference between the two +ranks. If the rank of the second input is one less than the rank of the +first, the reported value is a scalar, the index of the entire second +input in the first.

+ +

{width=ā€517pxā€ +height=ā€106pxā€}

+ +

{width=ā€516pxā€ +height=ā€311pxā€}Why the strange design decision to report +length+1 when something isnā€™t found, instead of a more obvious flag +value such as 0 or false? Hereā€™s why:

+ +

{width=ā€209pxā€ +height=ā€22pxā€}Note that code has 27 items, not 26. The asterisk at +the end is the ciphertext is the translation of all non-alphabet +characters (spaces and the apostrophe in ā€œdoesnā€™tā€). This is a silly +example, because it makes up a random cipher every time itā€™s called, and +it doesnā€™t report the cipher, so the recipient canā€™t decipher the +message. And you wouldnā€™t want to make the spaces in the message so +obvious. But despite being silly, the example shows the benefit of +reporting length+1 as the position of items not found.

+ +

{width=ā€719pxā€ +height=ā€63pxā€}The contained in block is like a hyperized +contains with the input order reversed. It reports an array of Booleans +the same shape as the left input. The shape of the right input doesnā€™t +matter; the block looks only for atomic elements.

+ +

{width=ā€256pxā€ +height=ā€30pxā€}The blocks grade up and grade down are +used for sorting data. Given an array as input, it reports a vector of +the indices in which the items (the rows, if a matrix) should be +rearranged in order to be sorted. This will be +{width=ā€719pxā€ +height=ā€173pxā€}clearer with an example:

+ +

The result from grade up tells us that item 3 of foo comes first in +sorted order, then item 4, then 2, then 1. When we actually select items +of foo based on this ordering, we get the desired sorted version. +The result reported by grade down is almost the reverse of that from +grade up, but not quite, if there are equal items in the list. (The sort +is stable, so if there are equal items, then whichever comes first in +the input list will also be first in the sorted list.)

+ +

Why this two-step process? Why not just have a sort primitive in APL? +One answer is that in a database application you might want to sort one +array based on the order of another array:

+ +

This is the list of employees of a small company. (Taken from Structure +and Interpretation of Computer Programs by Abelson and Sussman. +Creative Commons licensed.) Each of the smaller lists contains a +person's name, job title, and yearly salary. +{width=ā€526pxā€ +height=ā€211pxā€}We would like to sort the employeesā€™ names in +big-to-small order of salary. First we extract column 3 of the database, +the salaries:

+ +

{width=ā€342pxā€ +height=ā€190pxā€}
+Then we use grade down to get the reordering indices:

+ +

{width=ā€512pxā€ +height=ā€228pxā€}{width=ā€478pxā€ +height=ā€214pxā€}At this point we could use the index +vector to sort the salaries:

+ +

{width=ā€537pxā€ +height=ā€221pxā€}But what we actually want is a list of names, sorted by +salary:

+ +

{width=ā€222pxā€ +height=ā€26pxā€}{width=ā€280pxā€ +height=ā€31pxā€}By taking the index vector from grade down of column 3 +and telling item to apply it to column 1, we get what we set out to +find. As usual the code is more elegant in APL: +database[ā’database[;3];1].

+ +

{width=ā€283pxā€ +height=ā€22pxā€}In case youā€™ve forgotten, or would select +the third row of the database; we need the list 3 in the second input +slot of the outer list to select by columns rather than by rows.

+ +

Select (if take) or select all but (if drop) the first (if n>0) or +last (if n<0) |n| items from a vector, or rows from a matrix. +Alternatively, if the left input is a two-item vector, select rows with +the first item and columns with the second.

+ +

The compress block selects a subset of its right input based on the +Boolean values in its left input, which must be a vector of Booleans +whose length equals the length of the array (the number of rows, for a +matrix) in the right input. The block reports an array of the same rank +as the right input, but containing only those rows whose corresponding +Boolean value is true. The columns version āŒæ is the same but +selecting columns rather than selecting rows.

+ +

{width=ā€619pxā€ +height=ā€24pxā€}A word about the possibly confusing names of these +blocks: There are two ways to think about what they do. Take the +standard / version, to avoid talking about both at once. One way to +think about it is that it selects some of the rows. The other way is +that it shortens the columns. For Lispians, which includes you since +youā€™ve learned about keep, the natural way to think about / is that it +keeps some of the rows. Since we represent a matrix as a list of rows, +that also fits with how this function is implemented. (Read the code; +youā€™ll find a keep inside.) But APL people think about it the other way, +so when you read APL documentation, / is described as operating on the +last dimension (the columns), while āŒæ is described as operating on +rows. We were more than a month into this project before I understood +all this. You get long block names so it wonā€™t take you a month!

+ +

{width=ā€305pxā€ +height=ā€18pxā€}{width=ā€287pxā€ +height=ā€22pxā€}{width=ā€107pxā€ +height=ā€22pxā€}Donā€™t confuse this block with the reduce +block, whose APL symbol is also a slash. In that block, what comes to +the left of the slash is a dyadic combining function; itā€™s the APL +equivalent of combine. This block is more nearly equivalent to keep. But +keep takes a predicate function as input, and calls the function for +each item of the second input. With compress, the predicate function, if +any, has already been called on all the items of the right input in +parallel, resulting in a vector of Boolean values. This is a typical APL +move; since hyperblocks are equivalent to an implicit map, itā€™s easy to +make the vector of Booleans, because any scalar function, including +predicates, can be applied to a list instead of to a scalar. The reason +both blocks use the / character is that both of them reduce the size of +the input array, although in different ways.

+ +

{width=ā€564pxā€ +height=ā€287pxā€}The reverse row order, reverse column +order, and transpose blocks form a group: the group of reflections of a +matrix. The APL symbols are all a circle with a line through it; the +lines are the different axes of reflection. So the reverse row order +block reverses which row is where; the reverse column order block +reverses which column is where; and the transpose block turns rows into +columns and vice versa:

+ +

Except for reverse row order, these work only on full arrays, not +ragged-right lists of lists, because the result of the other two would +be an array in which some rows had ā€œholesā€: items 1 and 3 exist, but not +item 2. We donā€™t have a representation for that. (In APL, all arrays are +full, so itā€™s even more restrictive.)

+ +

Higher order functions

+ +

The final category of function is operatorsā€”APL higher order +functions. APL has no explicit map function, because the hyperblock +capability serves much the same need. But APL2 did add an explicit map, +which we might get around to adding to the library next time around. Its +symbol is ĀØ (diaeresis or umlaut).

+ +

The APL equivalent of keep is compress, but itā€™s not a higher order +function. You create a vector of Booleans (0s and 1s, in APL) before +applying the function to the array you want to compress.

+ +

{width=ā€409pxā€ +height=ā€59pxā€}But APL does have a higher order version +of combine:

+ +

{width=ā€642pxā€ +height=ā€100pxā€}The reduce block works just like combine, +taking a dyadic function and a list. The / version translates each row +to a single value; the āŒæ version translates each column to a single +value. Thatā€™s the only way to think about it from the perspective of +combining individual elements: you are adding up, or whatever the +function is, the numbers in a single row (/) or in a single column +(āŒæ). But APLers think of a matrix as made up of vectors, either row +vectors or column vectors. And if you think of what these blocks do as +adding vectors, rather than adding individual numbers, itā€™s clear that +in

+ +

{width=ā€560pxā€ +height=ā€106pxā€}

+ +

{width=ā€462pxā€ +height=ā€106pxā€}the vector (10, 26, 42) is the sum of column vectors +(1, 5, 9)+(2, 6, 10)+(3, 7, 11)+(4, 8, 12). In pre-6.0 Snap!, weā€™d get +the same result this way:

+ +

mapping over the rows of the matrix, applying combine to each row. +Combining rows, reducing column vectors.
+The outer product block takes two arrays (vectors, typically) and a +dyadic scalar function as inputs. It reports an array whose rank is the +sum of the ranks of the inputs (so, typically a matrix), in which each +item is the result of applying the function to an atomic element of each +array. The third element of the second row of the result is the value +reported by the function with the second element of the left input and +the third element of the right input. (The APL symbol ā—¦. is pronounced +ā€œjot dot.ā€) The way to think about this block is ā€œmultiplication tableā€ +from elementary school:

+ +

{width=ā€695pxā€ height=ā€146pxā€}

+ +

{width=ā€208pxā€ +height=ā€23pxā€}

+ +

{width=ā€251pxā€ +height=ā€23pxā€}

+ +

{width=ā€705pxā€ +height=ā€97pxā€}The inner product block takes two matrices +and two operations as input. The number of columns in the left matrix +must equal the number of rows in the right matrix. When the two +operations are + and Ɨ, this is the matrix multiplication familiar to +mathematicians:

+ +

But other operations can be used. One common inner product is āˆØ.āˆ§ (ā€œor +dot andā€) applied to Boolean matrices, to find rows and columns that +have corresponding items in common.

+ +

{width=ā€92pxā€ +height=ā€18pxā€}The printable block isnā€™t an APL +function; itā€™s an aid to exploring APL-in-Snap!. It transforms arrays +to a compact representation that still makes the structure clear:

+ +

{width=ā€576pxā€ +height=ā€32pxā€}Experts will recognize this as the Lisp +representation of list structure,

+ +

Index

+ +

! block Ā· 32.csv file Ā· 134.json file Ā· 134.txt file Ā· 134# variable Ā· +25#1 Ā· 69+ block Ā· 22Ɨ block Ā· 22ā‰  block Ā· 20ā‰¤ block Ā· 20ā‰„ block Ā· 20āš” +(lightning bolt) Ā· 123Aa new clone of block Ā· 77A Programming Language +Ā· 148Abelson, Hal Ā· 4About option Ā· 107add comment option Ā· 124, 125Add +sceneā€¦ option Ā· 111additive mixing Ā· 144Advanced Placement Computer +Science Principles Ā· 110AGPL Ā· 107all but first blocks Ā· 27all but first +of block Ā· 49all but first of stream block Ā· 26all but last blocks Ā· +27all of block Ā· 28Alonzo Ā· 9, 55anchor Ā· 10anchor (in my block) Ā· +78animate block Ā· 33animation Ā· 12animation library Ā· 33anonymous list Ā· +46Any (unevaluated) type Ā· 72any of block Ā· 28Any type Ā· 60APL Ā· 4, 58, +148APL character set Ā· 149APL library Ā· 35, 148APL2 Ā· 149APL\360 Ā· +148Arduino Ā· 92arithmetic Ā· 11array, dynamic Ā· 49arrow, upward-pointing +Ā· 63arrowheads Ā· 46, 63, 69ask and wait block Ā· 24ask block Ā· 86assoc +block Ā· 25association list Ā· 88associative function Ā· 51at block Ā· +19atan2 block Ā· 20atomic data Ā· 57attribute Ā· 76attributes, list of Ā· +78audio comp library Ā· 34Bbackground blocks Ā· 19Backgroundsā€¦ option Ā· +112backspace key (keyboard editor) Ā· 131Ball, Michael Ā· 4bar chart block +Ā· 28bar charts library Ā· 28base case Ā· 44BIGNUMS block Ā· 32binary tree Ā· +47bitmap Ā· 79, 112bitwise library Ā· 36bjc.edc.org Ā· 137Black Hole +problem Ā· 139block Ā· 6; command Ā· 6; C-shaped Ā· 7; hat Ā· 6; predicate Ā· +12; reporter Ā· 10; sprite-local Ā· 75Block Editor Ā· 41, 42, 59block label +Ā· 102block library Ā· 45, 110block picture option Ā· 124block shapes Ā· 40, +60block variable Ā· 43block with no name Ā· 32blockify option Ā· 134blocks, +color of Ā· 40Boole, George Ā· 12Boolean Ā· 12Boolean (unevaluated) type Ā· +72Boolean constant Ā· 12box of ten crayons Ā· 139box of twenty crayons Ā· +139break command Ā· 99breakpoint Ā· 17, 118Briggs, David Ā· 145broadcast +and wait block Ā· 125broadcast and wait block Ā· 9broadcast block Ā· 21, +23, 73, 125brown dot Ā· 9Build Your Own Blocks Ā· 40Burns, Scott Ā· +145button: pause Ā· 17; recover Ā· 39; visible stepping Ā· 18CC programming +language Ā· 68call block Ā· 65, 68call w/continuation block Ā· 97camera +icon Ā· 126Cancel button Ā· 129carriage return character Ā· 20cascade +blocks Ā· 26case-independent comparisons block Ā· 33cases block Ā· 28catch +block Ā· 26, 99catch errors library Ā· 31catenate block Ā· 152catenate +vertically block Ā· 152center of the stage Ā· 22center x (in my block) Ā· +78center y (in my block) Ā· 78Chandra, Kartik Ā· 4change background block +Ā· 22Change passwordā€¦ option Ā· 113change pen block Ā· 24, 29, 117, +140child class Ā· 87children (in my block) Ā· 78Church, Alonzo Ā· 9class Ā· +85class/instance Ā· 76clean up option Ā· 125clear button Ā· 129clicking on +a script Ā· 122Clicking sound option Ā· 116clone: permanent Ā· 74; +temporary Ā· 74clone of block Ā· 89clones (in my block) Ā· 78cloud (startup +option) Ā· 136Cloud button Ā· 37, 108cloud icon Ā· 113cloud storage Ā· 37CMY +Ā· 138CMYK Ā· 138codification support option Ā· 117color at weight block Ā· +145color block Ā· 140color chart Ā· 147color from block Ā· 29, 140color +nerds Ā· 145color numbers Ā· 29, 138, 139color of blocks Ā· 40color palette +Ā· 128color picker Ā· 143color scales Ā· 141color space Ā· 138color theory Ā· +138Colors and Crayons library Ā· 138colors library Ā· 29columns of block Ā· +57combine block Ā· 50combine block (APL) Ā· 157command block Ā· 6comment +box Ā· 125compile menu option Ā· 123compose block Ā· 26compress block Ā· +156Computer Science Principles Ā· 110cond in Lisp Ā· 28conditional +library: multiple-branch Ā· 28constant functions Ā· 71constructors Ā· +47contained in block Ā· 153context menu Ā· 119context menu for the palette +background Ā· 120context menus for palette blocks Ā· 119continuation Ā· +93continuation passing style Ā· 94Control palette Ā· 7controls in the +Costumes tab Ā· 126controls in the Sounds tab Ā· 130controls on the stage +Ā· 132control-shift-enter (keyboard editor) Ā· 132copy of a list Ā· 50CORS +Ā· 92cors proxies Ā· 92costume Ā· 6, 8costume from text block Ā· 31costume +with background block Ā· 31costumes (in my block) Ā· 78Costumes tab Ā· 9, +126costumes, first class Ā· 79Costumesā€¦ option Ā· 112counter class Ā· +85CPS Ā· 96crayon library Ā· 31crayons Ā· 29, 138, 139create var block Ā· +32create variables library Ā· 32Cross-Origin Resource Sharing Ā· +92crossproduct Ā· 70cs10.org Ā· 137C-shaped block Ā· 7, 67C-shaped slot Ā· +72CSV (comma-separated values) Ā· 54CSV format Ā· 20csv of block Ā· +57current block Ā· 92current date or time Ā· 92current location block Ā· +34current sprite Ā· 122custom block in a script Ā· 124custom? of block +block Ā· 102cyan Ā· 142Ddangling rotation Ā· 10dangling? (in my block) Ā· +78dark candy apple red Ā· 141data hiding Ā· 73data structure Ā· 47data +table Ā· 88data type Ā· 19, 59database library Ā· 34date Ā· 92Dave, Achal Ā· +4deal block Ā· 150debugging Ā· 118Debugging Ā· 17deep copy of a list Ā· +50default value Ā· 63define block Ā· 102define of recursive procedure Ā· +104definition (of block) Ā· 102definition of block Ā· 101delegation Ā· +87Delete a variable Ā· 14delete block definitionā€¦ option Ā· 120delete +option Ā· 124, 128, 133delete var block Ā· 32denim Ā· 139design principle Ā· +46, 77devices Ā· 91, 92dialog, input name Ā· 42dimensions of block Ā· +57Dinsmore, Nathan Ā· 4direction to block Ā· 22Disable click-to-run option +Ā· 117dispatch procedure Ā· 85, 86, 88distance to block Ā· 22dl (startup +option) Ā· 136do in parallel block Ā· 31does var exist block Ā· 32down +arrow (keyboard editor) Ā· 131Download source option Ā· 108drag from +prototype Ā· 43draggable checkbox Ā· 122, 132dragging onto the arrowheads +Ā· 69drop block Ā· 155duplicate block definitionā€¦ option Ā· 120duplicate +option Ā· 124, 128, 132dynamic array Ā· 49Eeasing block Ā· 33easing +function Ā· 33edge color Ā· 129edit option Ā· 128, 133, 135editā€¦ option Ā· +120editMode (startup option) Ā· 137effect block Ā· 19ellipse tool Ā· 128, +129ellipsis Ā· 63else block Ā· 28else if block Ā· 28empty input slots, +filling Ā· 66, 68, 70enter key (keyboard editor) Ā· 131equality of +complete structures Ā· 149eraser tool Ā· 128error block Ā· 31error catching +library Ā· 31escape key (keyboard editor) Ā· 130Examples button Ā· +108Execute on slider change option Ā· 115export block definitionā€¦ +option Ā· 120Export blocksā€¦ option Ā· 110export option Ā· 128, 133Export +projectā€¦ option Ā· 110exportā€¦ option Ā· 134, 136expression Ā· +11Extension blocks option Ā· 115extract option Ā· 124eyedropper tool Ā· +128, 129Ffactorial Ā· 44, 71factorial Ā· 32Fade blocksā€¦ option Ā· 114fair +HSL Ā· 145fair hue Ā· 29, 141, 143, 146fair hue table Ā· 146fair saturation +Ā· 146fair value Ā· 146Falkoff, Adin Ā· 148false block Ā· 19file icon menu Ā· +108fill color Ā· 129Finch Ā· 92find blocksā€¦ option Ā· 120find first Ā· +50first class data Ā· 148first class data type Ā· 46ļ¬rst class procedures +Ā· 65ļ¬rst class sprites Ā· 73first word block Ā· 27flag, green Ā· 6Flat +design option Ā· 116flat line ends option Ā· 117flatten block Ā· 152flatten +of block Ā· 57floodfill tool, Ā· 128focus (keyboard editor) Ā· 131footprint +button Ā· 117for block Ā· 13, 19, 26, 64, 65for each block Ā· 20for each +item block Ā· 25For this sprite only Ā· 15formal parameters Ā· 69frequency +distribution analysis library Ā· 34from color block Ā· 29, 140, +142function, associative Ā· 51function, higher order Ā· 49, 148function, +mixed Ā· 148, 151function, scalar Ā· 55, 148functional programming style Ā· +48
+Ggeneric hat block Ā· 6generic when Ā· 6get blocks option Ā· 128getter Ā· +76getter/setter library Ā· 32glide block Ā· 115global variable Ā· 14, 15go +to block Ā· 22grade down block Ā· 154grade up block Ā· 154graphics effect Ā· +19gray Ā· 139, 141green flag Ā· 6green flag button Ā· 118green halo Ā· +123GuillĆ©n i Pelegay, Joan Ā· 4Hhalo Ā· 11, 123; red Ā· 69hat block Ā· 6, +41; generic Ā· 6helpā€¦ option Ā· 119, 123helpā€¦ option for custom block +Ā· 119hexagonal blocks Ā· 41, 60hexagonal shape Ā· 12hide and show +primitives Ā· 17hide blocks option Ā· 120Hide blocksā€¦ option Ā· 111hide +var block Ā· 32hide variable block Ā· 17hideControls (startup option) Ā· +137higher order function Ā· 49, 70, 148, 157higher order procedure Ā· +66histogram Ā· 34Hotchkiss. Kyle Ā· 4HSL Ā· 138, 143HSL color Ā· 29HSL pen +color model option Ā· 117HSV Ā· 138, 142HTML (HyperText Markup Language) Ā· +91HTTP Ā· 92HTTPS Ā· 92, 126Hudson, Connor Ā· 4hue Ā· 141Huegle, Jadga Ā· +4Hummingbird Ā· 92hyperblocks Ā· 148Hyperblocks Ā· 55Hz for block Ā· 34IIBM +System/360 Ā· 148ice cream Ā· 109icons in title text Ā· 64id block Ā· 71id +option Ā· 22identical to Ā· 20identity function Ā· 71if block Ā· 12if do and +pause all block Ā· 26if else block Ā· 71if else reporter block Ā· 19ignore +block Ā· 26imperative programming style Ā· 48importā€¦ option Ā· +134Importā€¦ option Ā· 110in front of block Ā· 49in front of stream block +Ā· 26index of block (APL) Ā· 152index variable Ā· 19indigo Ā· 141infinite +precision integer library Ā· 32Ingalls, Dan Ā· 4inherit block Ā· +77inheritance Ā· 73, 87inner product block Ā· 158input Ā· 6input list Ā· 68, +69input name Ā· 69input name dialog Ā· 42, 59Input sliders option Ā· +115input-type shapes Ā· 59instance Ā· 85integers block Ā· 152interaction Ā· +15internal variable Ā· 63iota block Ā· 152is _ a _ ? block Ā· 19is flag +block Ā· 20is identical to Ā· 20item 1 of block Ā· 49item 1 of stream block +Ā· 26item block Ā· 148item of block Ā· 56iteration library Ā· 26Iverson, +Kenneth E. Ā· 4, 148Jjaggies Ā· 79Java programming language Ā· 68JavaScript +Ā· 19, 143JavaScript extensions option Ā· 115JavaScript function block Ā· +115jigsaw-piece blocks Ā· 40, 60join block Ā· 102JSON (JavaScript Object +Notation) file Ā· 54JSON format Ā· 20json of block Ā· 57jukebox Ā· 9KKay, +Alan Ā· 4key:value: block Ā· 34keyboard editing button Ā· 123keyboard +editor Ā· 130keyboard shortcuts Ā· 108key-value pair Ā· 88LL*a*b* Ā· +143L*u*v* Ā· 143label, block Ā· 102lambda Ā· 67lang= (startup option) Ā· +137Languageā€¦ option Ā· 114large option Ā· 134last blocks Ā· 27layout, +window Ā· 5Leap Motion Ā· 92left arrow (keyboard editor) Ā· 131Lego NXT Ā· +92length block Ā· 148length of block Ā· 57length of text block Ā· 22letter +(1) of (world) block Ā· 27lexical scope Ā· 85lg option Ā· 22Librariesā€¦ +option Ā· 25, 111library: block Ā· 45license Ā· 107Lieberman, Henry Ā· +77Lifelong Kindergarten Group Ā· 4lightness Ā· 143lightness option Ā· +117lightning bolt symbol Ā· 25, 123line break in block Ā· 64line drawing +tool Ā· 128lines of block Ā· 57linked list Ā· 49Lisp Ā· 58list āž” sentence +block Ā· 27list āž” word block Ā· 27list block Ā· 46list comprehension +library Ā· 35list copy Ā· 50list library Ā· 25list of procedures Ā· 70List +type Ā· 60list view Ā· 51list, linked Ā· 49list, multi-dimensional Ā· +55listify block Ā· 34lists of lists Ā· 47little people Ā· 44, 96loading +saved projects Ā· 38local state Ā· 73local variables Ā· 19location-pin Ā· +15Loginā€¦ option Ā· 113Logo tradition Ā· 27Logout option Ā· 113Long form +input dialog option Ā· 116long input name dialog Ā· 59Mmacros Ā· 105magenta +Ā· 141, 142Make a block Ā· 40Make a block button Ā· 119make a blockā€¦ +option Ā· 126Make a list Ā· 46Make a variable Ā· 14make internal variable +visible Ā· 63Maloney, John Ā· 4map block Ā· 50, 65map library Ā· 35map over +stream block Ā· 26map to code block Ā· 117map-pin symbol Ā· 75maroon Ā· +141Massachusetts Institute of Technology Ā· 4mathematicians Ā· 148matrices +Ā· 148matrix multiplication Ā· 158max block Ā· 20McCarthy, John Ā· 4media +computation Ā· 55, 149Media Lab Ā· 4memory Ā· 16menus library Ā· 36message Ā· +73message passing Ā· 73, 86method Ā· 73, 75, 86methods table Ā· +88microphone Ā· 82microphone block Ā· 82middle option Ā· 127min block Ā· +20mirror sites Ā· 137MIT Artificial Intelligence Lab Ā· 4MIT Media Lab Ā· +4mix block Ā· 140mix colors block Ā· 29mixed function Ā· 148, 151mixing +paints Ā· 144Modrow, Eckart Ā· 121monadic negation operator Ā· 22Morphic Ā· +4Motyashov, Ivan Ā· 4mouse position block Ā· 21move option Ā· 133MQTT +library Ā· 36multiline block Ā· 33multimap block Ā· 25multiple input Ā· +63multiple-branch conditional library Ā· 28multiplication table Ā· +158multiplication, matrix Ā· 158mutation Ā· 48mutators Ā· 47my block Ā· 73, +76my blocks block Ā· 102my categories block Ā· 102Nname (in my block) Ā· +78name box Ā· 122name, input Ā· 69nearest color number Ā· 142neg option Ā· +22negation operator Ā· 22neighbors (in my block) Ā· 78nested calls Ā· +70Nesting Sprites Ā· 10New categoryā€¦ option Ā· 111new costume block Ā· +80new line character Ā· 64New option Ā· 108New scene option Ā· 111new sound +block Ā· 84new sprite button Ā· 8newline character Ā· 20Nintendo Ā· +92noExitWarning (startup option) Ā· 137nonlocal exit Ā· 99normal option Ā· +134normal people Ā· 145noRun (startup option) Ā· 137Number type Ā· +60numbers from block Ā· 20Oobject block Ā· 73Object Logo Ā· 77object +oriented programming Ā· 73, 85Object type Ā· 60objects, building +explicitly Ā· 85of block (operators) Ā· 22of block (sensing) Ā· 24, 106of +costume block Ā· 79open (startup option) Ā· 136Open in Community Site +option Ā· 113Openā€¦ option Ā· 108operator (APL) Ā· 148, 157orange oval Ā· +13other clones (in my block) Ā· 78other sprites (in my block) Ā· 78outer +product block Ā· 158outlined ellipse tool Ā· 128outlined rectangle tool Ā· +128oval blocks Ā· 40, 60Ppaint brush icon Ā· 126Paint Editor Ā· 126Paint +Editor window Ā· 128paintbrush tool Ā· 128paints Ā· 144Paleolithic Ā· +150palette Ā· 6palette area Ā· 119palette background Ā· 120Parallax S2 Ā· +92parallelism Ā· 8, 48parallelization library Ā· 31parent (in my block) Ā· +78parent attribute Ā· 77parent class Ā· 87parentā€¦ option Ā· 136Parsons +problems Ā· 117parts (in my block) Ā· 78parts (of nested sprite) Ā· +10pause all block Ā· 17, 118pause button Ā· 17, 118pen block Ā· 24, 29, +117, 140pen down? block Ā· 19pen trails block Ā· 18pen trails option Ā· +135pen vectors block Ā· 18permanent clone Ā· 74, 136physical devices Ā· +91picā€¦ option Ā· 135, 136picture of script Ā· 124picture with speech +balloon Ā· 124picture, smart Ā· 124pink Ā· 141pivot option Ā· 133pixel Ā· +79pixel, screen Ā· 19pixels library Ā· 27Plain prototype labels option Ā· +116play block Ā· 34play sound block Ā· 9playing sounds Ā· 9plot bar chart +block Ā· 28plot sound block Ā· 34point towards block Ā· 22points as inputs +Ā· 22polymorphism Ā· 75position block Ā· 21, 33Predicate block Ā· +12preloading a project Ā· 136present (startup option) Ā· 136presentation +mode button Ā· 118primitive block within a script Ā· 123printable block Ā· +27, 158procedure Ā· 12, 66Procedure type Ā· 72procedures as data Ā· +9product block Ā· 22, 28project control buttons Ā· 118Project notes option +Ā· 108Prolog Ā· 58prototype Ā· 41prototyping Ā· 76, 88pulldown input Ā· +61pumpkin Ā· 139purple Ā· 142Rrainbow Ā· 141rank Ā· 148rank of block Ā· 57, +151ravel block Ā· 149raw dataā€¦ option Ā· 134ray length block Ā· +22read-only pulldown input Ā· 61receiversā€¦ option Ā· 125recover button Ā· +39rectangle tool Ā· 128recursion Ā· 43recursive call Ā· 68recursive +operator Ā· 71recursive procedure using define Ā· 104red halo Ā· 68, 69, +123redo button Ā· 123redrop option Ā· 125reduce block Ā· 156, 157Reference +manual option Ā· 108reflectance graph Ā· 144relabel option Ā· 20relabelā€¦ +option Ā· 123, 124release option Ā· 136Remove a categoryā€¦ option Ā· +111remove duplicates from block Ā· 25rename option Ā· 128renaming +variables Ā· 15repeat block Ā· 7, 67repeat blocks Ā· 26repeat until +block Ā· 12report block Ā· 44Reporter block Ā· 10reporter if block Ā· +12reporter if else block Ā· 19reporters, recursive Ā· 44Reset Passwordā€¦ +option Ā· 113reshape block Ā· 56, 148, 151Restore unsaved project option Ā· +39result picā€¦ option Ā· 124, 125reverse block Ā· 156reverse columns +block Ā· 156Reynolds, Ian Ā· 4RGB Ā· 138RGBA option Ā· 19right arrow +(keyboard editor) Ā· 131ring, gray Ā· 49, 66, 68ringify Ā· 66ringify option +Ā· 124Roberts, Eric Ā· 44robots Ā· 91, 92rods and cones Ā· 141roll block Ā· +150Romagosa, Bernat Ā· 4rotation buttons Ā· 122rotation point tool Ā· 128, +129rotation x (in my block) Ā· 78rotation y (in my block) Ā· 78run +(startup option) Ā· 136run block Ā· 65, 68run w/continuation Ā· 99Ssafely +try block Ā· 31sample Ā· 82saturation Ā· 143Save asā€¦ option Ā· 110Save +option Ā· 110save your project in the cloud Ā· 37scalar = block Ā· +150scalar function Ā· 55, 148, 150scalar join block Ā· 150scenes Ā· 111, +136Scenesā€¦ option Ā· 111Scheme Ā· 4Scheme number block Ā· 32SciSnap! Ā· +121SciSnap! library Ā· 36scope: lexical Ā· 85Scratch Ā· 5, 9, 40, 46, 47, +48, 59Scratch Team Ā· 4screen pixel Ā· 19script Ā· 5script pic Ā· 43script +picā€¦ option Ā· 124script variables block Ā· 15, 19, 86scripting area +Ā· 6, 122scripting area background context menu Ā· 125scripts picā€¦ +option Ā· 126search bar Ā· 109search button Ā· 119secrets Ā· 107select block +Ā· 156selectors Ā· 47self (in my block) Ā· 78sendersā€¦ option Ā· 125sensors +Ā· 91sentence āž” list block Ā· 27sentence block Ā· 25sentence library Ā· +27sentenceāž”list block Ā· 25separator: menu Ā· 62sepia Ā· 139serial-ports +library Ā· 33Servilla, Deborah Ā· 4set _ of block _ to _ block Ā· 102set +background block Ā· 22set block Ā· 15set flag block Ā· 20, 32set pen +block Ā· 24, 29, 117, 139, 140set pen to crayon block Ā· 30, 139set value +block Ā· 32set var block Ā· 32setter Ā· 76setting block Ā· 32settings icon Ā· +114shade Ā· 141shallow copy of a list Ā· 50shape of block Ā· 151shapes of +blocks Ā· 40shift-arrow keys (keyboard editor) Ā· 131Shift-click (keyboard +editor) Ā· 130shift-click on block Ā· 124shift-clicking Ā· 107shift-enter +(keyboard editor) Ā· 130Shift-tab (keyboard editor) Ā· 130shortcut Ā· 126, +135shortcuts: keyboard Ā· 108show all option Ā· 135Show buttons option Ā· +117Show categories option Ā· 117show option Ā· 136show primitives option Ā· +121show stream block Ā· 26show var block Ā· 32show variable block Ā· +17shown? block Ā· 19shrink/grow button Ā· 118sieve block Ā· 26sign option Ā· +22Signada library Ā· 36signum block Ā· 150Signupā€¦ option Ā· 113simulation +Ā· 73sine wave Ā· 83Single palette option Ā· 117single stepping Ā· 18slider: +stepping speed Ā· 18slider maxā€¦ option Ā· 134slider minā€¦ option Ā· +134slider option Ā· 134Smalltalk Ā· 58smart picture Ā· 124snap block Ā· +27snap option Ā· 22Snap! logo menu Ā· 107Snap! manual Ā· 124Snap! +program Ā· 5Snap! website option Ā· 108snap.berkeley.edu Ā· 108solid +ellipse tool Ā· 128solid rectangle tool Ā· 128sophistication Ā· 72sort +block Ā· 25sound Ā· 82sound manipulation library Ā· 34sounds (in my block) +Ā· 78sounds, first class Ā· 79Soundsā€¦ option Ā· 113source files for +Snap! Ā· 108space key (keyboard editor) Ā· 131speak block Ā· 31special +form Ā· 72spectral colors Ā· 141speech balloon Ā· 124speech synthesis +library Ā· 31split block Ā· 20, 91split by blocks block Ā· 101split by line +block Ā· 57spreadsheet Ā· 149sprite Ā· 6, 73sprite appearance and behavior +controls Ā· 122sprite corral Ā· 8, 135sprite creation buttons Ā· 135sprite +nesting Ā· 10sprite-local block Ā· 75sprite-local variable Ā· 14, 15square +stop sign Ā· 6squiral Ā· 13stack of blocks Ā· 6stage Ā· 6, 73stage (in my +block) Ā· 78stage blocks Ā· 19Stage resizing buttons Ā· 118Stage sizeā€¦ +option Ā· 114Stanford Artificial Intelligence Lab Ā· 4starting Snap! Ā· +136Steele, Guy Ā· 4stop all block Ā· 118stop block Ā· 22stop block block Ā· +44stop button Ā· 118stop script block Ā· 44stop sign Ā· 8stop sign, square +Ā· 6Stream block Ā· 26stream library Ā· 26Stream with numbers from block Ā· +26stretch block Ā· 80string processing library Ā· 33Structure and +Interpretation of Computer Programs Ā· 4submenu Ā· 62substring block Ā· +33subtractive mixing Ā· 144sum block Ā· 22, 28Super-Awesome Sylvia Ā· +92Sussman, Gerald J. Ā· 4Sussman, Julie Ā· 4svgā€¦ option Ā· 135switch in C +Ā· 28symbols in title text Ā· 64synchronous rotation Ā· 10system +getter/setter library Ā· 32Ttab character Ā· 20tab key (keyboard editor) Ā· +130table Ā· 158table view Ā· 51take block Ā· 155teal Ā· 142temporary clone Ā· +74, 133Terms of Service Ā· 38termwise extension Ā· 148text costume library +Ā· 31text input Ā· 9Text type Ā· 60text-based language Ā· 117text-to-speech +library Ā· 31Thinking Recursively Ā· 44thread Ā· 100thread block Ā· +100Thread safe scripts option Ā· 116throw block Ā· 26thumbnail Ā· 122time Ā· +92tint Ā· 141tip option Ā· 127title text Ā· 42to block Ā· 22tool bar Ā· 6tool +bar features Ā· 107touching block Ā· 22transient variable Ā· 16translation +Ā· 114translations option Ā· 43transparency Ā· 30, 79, 140transparent paint +Ā· 129transpose block Ā· 156true block Ā· 19TuneScope library Ā· 36Turbo +mode option Ā· 115turtle costume Ā· 126Turtle costume Ā· 9turtleā€™s rotation +point Ā· 127two-item (x,y) lists Ā· 22type Ā· 19UUndefined! blocks Ā· +120Undelete spritesā€¦ option Ā· 113undo button Ā· 123, 129undrop option Ā· +125unevaluated procedure types Ā· 61unevaluated type Ā· 72Unicode Ā· +149Uniform Resource Locator Ā· 91unringify Ā· 66, 86unringify option Ā· +124Unused blocksā€¦ option Ā· 111up arrow (keyboard editor) Ā· 131upvar Ā· +64upward-pointing arrow Ā· 63url block Ā· 34, 91USE BIGNUMS block Ā· 32use +case-independent comparisons block Ā· 33user interface elements Ā· 107user +name Ā· 37Vvalue Ā· 143value at key block Ā· 34var block Ā· 32variable Ā· 13, +76; block Ā· 43; global Ā· 14; renaming Ā· 15; script-local Ā· 15; +sprite-local Ā· 14, 15; transient Ā· 16variable watcher Ā· 14variable-input +slot Ā· 68variables in ring slots Ā· 66variables library Ā· 32variables, +local Ā· 19variadic Ā· 22variadic input Ā· 46, 63variadic library Ā· +28vector Ā· 112vector editor Ā· 129vectors Ā· 148video block Ā· 22video on +block Ā· 80violet Ā· 142visible stepping Ā· 45, 117visible stepping button +Ā· 18visible stepping option Ā· 115visual representation of a sentence Ā· +27Wwardrobe Ā· 9warp block Ā· 19, 123watcher Ā· 15Water Color Bot Ā· 92web +services library Ā· 34when I am block Ā· 23when I am stopped script Ā· +23when I receive block Ā· 23when, generic Ā· 6white Ā· 142white background +Ā· 141whitespace Ā· 20Wiimote Ā· 92window layout Ā· 5with inputs Ā· 66word āž” +list block Ā· 27word and sentence library Ā· 27world map library Ā· 35World +Wide Web Ā· 91write block Ā· 18writeable pulldown inputs Ā· 61XX position Ā· +11X11/W3C color names Ā· 29Xerox PARC Ā· 4YY position Ā· 11yield block Ā· +100Yuan, Yuan Ā· 4Zzebra coloring Ā· 11Zoom blocks... option Ā· 114

+ +
+
    +
  1. +

    One of the hat blocks, the generic ā€œwhen anythingā€ block , is +subtly different from the others. When the stop sign is clicked, or +when a project or sprite is loaded, this block doesnā€™t test whether +the condition in its hexagonal input slot is true, so the script +beneath it will not run, until some other script in the project +runs (because, for example, you click the green flag). When generic +when blocks are disabled, the stop sign will be square instead of +octagonal.Ā 

    +
  2. +
  3. +

    The hide variable and show variable blocks can also be used to +hide and show primitives in the palette. The pulldown menu doesnā€™t +include primitive blocks, but thereā€™s a generally useful technique +to give a block input values it wasnā€™t expecting using run or +call:{width=ā€378pxā€ +height=ā€37pxā€}

    + +

    In order to use a block as an input this way, you must explicitly +put a ring around it, by right-clicking on it and choosing ringify. +More about rings in Chapter VI.Ā 

    +
  4. +
  5. +

    This use of the word ā€œprototypeā€ is unrelated to the prototyping +object oriented programming discussed later.Ā 

    +
  6. +
  7. +

    Note to users of earlier versions: From the beginning, there has +been a tension in our work between the desire to provide tools such +as for (used in this example) and the higher order functions +introduced on the next page as primitives, to be used as easily as +other primitives, and the desire to show how readily such tools can +be implemented in Snap! itself. This is one instance of our +general pedagogic understanding that learners should both use +abstractions and be permitted to see beneath the abstraction +barrier. Until version 5.0, we used the uneasy compromise of a +library of tools written in Snap! and easily, but not easily +enough, loaded into a project. By not loading the tools, users or +teachers could explore how to program them. In 5.0 we made them true +primitives, partly because thatā€™s what some of us wanted all along +and partly because of the increasing importance of fast performance +as we explore ā€œbig dataā€ and media computation. But this is not the +end of the story for us. In a later version, after we get the design +firmed up, we intend to introduce ā€œhybridā€ primitives, implemented +in high speed Javascript but with an ā€œEditā€ option that will open, +not the primitive implementation, but the version written in +Snap!. The trick is to ensure that this can be done without +dramatically slowing usersā€™ projects.Ā 

    +
  8. +
  9. +

    In Scratch, every block that takes a Text-type input has a default +value that makes the rectangles for text wider than tall. The blocks +that arenā€™t specifically about text either are of Number type or +have no default value, so those rectangles are taller than wide. At +ļ¬rst some of us (bh) thought that Text was a separate type that +always had a wide input slot; it turns out that this isnā€™t true in +Scratch (delete the default text and the rectangle narrows), but we +thought it a good idea anyway, so we allow Text-shaped boxes even +for empty input slots. (This is why Text comes just above Any in the +input type selection box.)Ā 

    +
  10. +
  11. +

    There is a primitive id function in the menu of the sqrt of block, +but we think seeing its (very simple) implementation will make this +example easier to understand.Ā 

    +
  12. +
  13. +

    Some languages popular in the ā€œreal worldā€ today, such as +JavaScript, claim to use prototyping, but their object system is +much more complicated than what we are describing (weā€™re guessing +itā€™s because they were designed by people too familiar with +class/instance programming); that has, in some circles, given +prototyping a bad name. Our prototyping design comes from Object +Logo, and before that, from Henry Lieberman. [Lieberman, H., Using +Prototypical Objects to Implement Shared Behavior in Object-Oriented +Systems, First Conference on Object-Oriented Programming Languages, +Systems, and Applications [OOPSLA-86], ACM SigCHI, Portland, OR, +September, 1986. Also in Object-Oriented Computing, Gerald +Peterson, Ed., IEEE Computer Society Press, 1987.]Ā 

    +
  14. +
  15. +

    Neighbors are all other sprites whose bounding boxes intersect +the doubled dimensions of the requesting sprite's bounds.Ā 

    +
  16. +
+
+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a1/bf183cde58ba42dfd07be3be46e6f372f83302361b1711fc071d82ab9c73b4 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a1/bf183cde58ba42dfd07be3be46e6f372f83302361b1711fc071d82ab9c73b4 new file mode 100644 index 0000000..8c824a2 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a1/bf183cde58ba42dfd07be3be46e6f372f83302361b1711fc071d82ab9c73b4 @@ -0,0 +1,2 @@ +I",

I. Blocks, Scripts, and Sprites

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a6/a8f2706298ee1fecbcf1dab5ea521999edb301acb81a170bf19dd71167a7f3 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a6/a8f2706298ee1fecbcf1dab5ea521999edb301acb81a170bf19dd71167a7f3 new file mode 100644 index 0000000..8bdd6a4 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/a6/a8f2706298ee1fecbcf1dab5ea521999edb301acb81a170bf19dd71167a7f3 @@ -0,0 +1,8255 @@ +I"8

{width=ā€1.0inā€ height=ā€0.5492596237970254inā€}

+ +

Build Your Own Blocks

+ +

{#section .TOCHeading}

+ +

{width=ā€5.477777777777778inā€ height=ā€4.501388888888889inā€} Table of Contents {#table-of-contents .TOCHeading}

+ +

I. Blocks, Scripts, and Sprites 5

+ +

Hat Blocks and Command Blocks 6

+ +

A. Sprites and Parallelism 8

+ +

Costumes and Sounds 8

+ +

Inter-Sprite Communication with Broadcast 9

+ +

B. Nesting Sprites: Anchors and Parts 10

+ +

C. Reporter Blocks and Expressions 10

+ +

D. Predicates and Conditional Evaluation 12

+ +

E. Variables 13

+ +

Global Variables 14

+ +

Script Variables 15

+ +

Renaming variables 15

+ +

Transient variables 16

+ +

F. Debugging 17

+ +

The pause button 17

+ +

Breakpoints: the pause all block 17

+ +

Visible stepping 18

+ +

G. Etcetera 18

+ +

H. Libraries 25

+ +

II. Saving and Loading Projects and Media 37

+ +

A. Local Storage 37

+ +

B. Creating a Cloud Account 37

+ +

C. Saving to the Cloud 38

+ +

D. Loading Saved Projects 38

+ +

E. If you lose your project, do this first! 39

+ +

F. Private and Public Projects 39

+ +

III. Building a Block 40

+ +

A. Simple Blocks 40

+ +

Custom Blocks with Inputs 42

+ +

Editing Block Properties 43

+ +

B. Recursion 43

+ +

C. Block Libraries 44

+ +

D. Custom blocks and Visible Stepping 45

+ +

IV. First class lists 46

+ +

A. The list Block 46

+ +

B. Lists of Lists 47

+ +

C. Functional and Imperative List Programming 48

+ +

D. Higher Order List Operations and Rings 49

+ +

E. Table View vs. List View 51

+ +

Comma-Separated Values 54

+ +

Multi-dimensional lists and JSON 54

+ +

F. Hyperblocks 55

+ +

V. Typed Inputs 59

+ +

A. Scratchā€™s Type Notation 59

+ +

B. The Snap! Input Type Dialog 59

+ +

Procedure Types 60

+ +

Pulldown inputs 61

+ +

Input variants 63

+ +

Prototype Hints 64

+ +

Title Text and Symbols 64

+ +

VI. Procedures as Data 65

+ +

A. Call and Run 65

+ +

Call/Run with inputs 65

+ +

Variables in Ring Slots 66

+ +

B. Writing Higher Order Procedures 66

+ +

Recursive Calls to Multiple-Input Blocks 68

+ +

C. Formal Parameters 69

+ +

D. Procedures as Data 70

+ +

E. Special Forms 71

+ +

Special Forms in Scratch 72

+ +

VII. Object Oriented Programming with Sprites 73

+ +

A. First Class Sprites 73

+ +

B. Permanent and Temporary Clones 74

+ +

C. Sending Messages to Sprites 74

+ +

Polymorphism 75

+ +

D. Local State in Sprites: Variables and Attributes 76

+ +

E. Prototyping: Parents and Children 76

+ +

F. Inheritance by Delegation 77

+ +

G. List of attributes 78

+ +

H. First Class Costumes and Sounds 79

+ +

Media Computation with Costumes 79

+ +

Media Computation with Sounds 82

+ +

VIII. OOP with Procedures 85

+ +

A. Local State with Script Variables 85

+ +

B. Messages and Dispatch Procedures 86

+ +

C. Inheritance via Delegation 87

+ +

D. An Implementation of Prototyping OOP 88

+ +

IX. The Outside World 91

+ +

A. The World Wide Web 91

+ +

B. Hardware Devices 92

+ +

C. Date and Time 92

+ +

X. Continuations 93

+ +

A. Continuation Passing Style 94

+ +

B. Call/Run w/Continuation 97

+ +

Nonlocal exit 99

+ +

XI. Metaprogramming 101

+ +

A. Reading a block 101

+ +

B. Writing a block 102

+ +

C. Macros 105

+ +

XII. User Interface Elements 107

+ +

A. Tool Bar Features 107

+ +

The Snap! Logo Menu 107

+ +

The File Menu 108

+ +

The Cloud Menu 113

+ +

The Settings Menu 114

+ +

Visible Stepping Controls 117

+ +

Stage Resizing Buttons 118

+ +

Project Control Buttons 118

+ +

B. The Palette Area 119

+ +

Buttons in the Palette 119

+ +

Context Menus for Palette Blocks 119

+ +

Context Menu for the Palette Background 120

+ +

C. The Scripting Area 122

+ +

Sprite Appearance and Behavior Controls 122

+ +

Scripting Area Tabs 122

+ +

Scripts and Blocks Within Scripts 122

+ +

Controls in the Costumes Tab 126

+ +

The Paint Editor 128

+ +

Controls in the Sounds Tab 130

+ +

D. Keyboard Editing 130

+ +

Starting and stopping the keyboard editor 130

+ +

Navigating in the keyboard editor 130

+ +

Editing a script 131

+ +

Running the selected script 132

+ +

E. Controls on the Stage 132

+ +

Sprites 132

+ +

Variable watchers 134

+ +

The stage itself 135

+ +

F. The Sprite Corral and Sprite Creation Buttons 135

+ +

G. Preloading a Project when Starting Snap! 136

+ +

H. Mirror Sites 137

+ +

Appendix A. Snap! color library 138

+ +

Introduction to Color 138

+ +

Crayons and Color Numbers 139

+ +

Perceptual Spaces: HSV and HSL 142

+ +

Mixing Colors 144

+ +

tl;dr 145

+ +

Subappendix: Geeky details on fair hue 145

+ +

Subappendix: Geeky details on color numbers 146

+ +

Appendix B. APL features 148

+ +

Boolean values 150

+ +

Scalar functions 150

+ +

Mixed functions 151

+ +

Higher order functions 157

+ +

Index ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦. 159

+ +

Copyright Ā© 2020 Jens Mƶnig and Brian Harvey.

+ +

Macintosh
+HD:Users:bh:Desktop:cc.png{width=ā€0.6111111111111112inā€ height=ā€0.2152777777777778inā€} This work is licensed under a Creative +Commons Attribution-NonCommercial-ShareAlike 4.0 International +License.

+ +

Acknowledgements {#acknowledgements .TOCHeading}

+ +

[W]{.smallcaps}e have been extremely lucky in our mentors. Jens cut +his teeth in the company of the Smalltalk pioneers: Alan Kay, Dan +Ingalls, and the rest of the gang who invented personal computing and +object oriented programming in the great days of Xerox PARC. He worked +with John Maloney, of the MIT Scratch Team, who developed the Morphic +graphics framework thatā€™s still at the heart of Snap!.

+ +

The brilliant design of Scratch, from the Lifelong Kindergarten Group +at the MIT Media Lab, is crucial to Snap!. Our earlier version, BYOB, +was a direct modification of the Scratch source code. Snap! is a +complete rewrite, but its code structure and its user interface remain +deeply indebted to Scratch. And the Scratch Team, who could have seen us +as rivals, have been entirely supportive and welcoming to us.

+ +

Brian grew up at the MIT and Stanford Artificial Intelligence Labs, +learning from Lisp inventor John McCarthy, Scheme inventors Gerald J. +Sussman and Guy Steele, and the authors of the worldā€™s best computer +science book, Structure and Interpretation of Computer Programs, Hal +Abelson and Gerald J. Sussman with Julie Sussman, among many other +heroes of computer science. (Brian was also lucky enough, while in high +school, to meet Kenneth Iverson, the inventor of APL.)

+ +

In the glory days of the MIT Logo Lab, we used to say, ā€œLogo is Lisp +disguised as BASIC.ā€ Now, with its first class procedures, lexical +scope, and first class continuations, Snap! is Scheme disguised as +Scratch.

+ +

Four people have made such massive contributions to the implementation +of Snap! that we have officially declared them members of the team: +Michael Ball and Bernat Romagosa, in addition to contributions +throughout the project, have primary responsibility for the web site and +cloud storage. Joan GuillĆ©n i Pelegay has contributed very careful and +wise analysis of outstanding issues, including help in taming the +management of translations to non-English languages. Jadga HĆ¼gle, has +energetically contributed to online mini-courses about Snap! and +leading workshops for kids and for adults. Jens, Jadga, and Bernat are +paid to work on Snap! by SAP, which also supports our computing needs.

+ +

We have been fortunate to get to know an amazing group of brilliant +middle school(!) and high school students through the Scratch Advanced +Topics forum, several of whom (since grown up) have contributed code to +Snap!: Kartik Chandra, Nathan Dinsmore, Connor Hudson, Ian Reynolds, +and Deborah Servilla. Many more have contributed ideas and alpha-testing +bug reports. UC Berkeley students whoā€™ve contributed code include Achal +Dave. Kyle Hotchkiss, Ivan Motyashov, and Yuan Yuan. Contributors of +translations are too numerous to list here, but theyā€™re in the +ā€œAboutā€¦ā€ box in Snap! itself.

+ +

This material is based upon work supported in part by the National +Science Foundation under Grants No[.]{.smallcaps} 1138596, 1143566, and +1441075; and in part by MioSoft, Arduino.org, SAP, and YC Research. Any +opinions, findings, and conclusions or recommendations expressed in this +material are those of the author(s) and do not necessarily reflect the +views of the National Science Foundation or other funders.

+ +

[
+]{.smallcaps}[Snap! Reference Manual]{.underline}

+ +

Version 8.0

+ +

Snap! (formerly BYOB) is an extended reimplementation of Scratch +([http://scratch.mit.edu]{.underline}) that allows you to Build Your Own +Blocks. It also features ļ¬rst class lists, ļ¬rst class procedures, first +class sprites, first class costumes, first class sounds, and first class +continuations. These added capabilities make it suitable for a serious +introduction to computer science for high school or college students.

+ +

In this manual we sometimes make reference to Scratch, e.g., to explain +how some Snap! feature extends something familiar in Scratch. Itā€™s +very helpful to have some experience with Scratch before reading this +manual, but not essential.

+ +

To run Snap![,]{.smallcaps} open a browser window and connect to +http://snap.berkeley.edu/run. The Snap! community web site at +http://snap.berkeley.edu is not part of this manualā€™s scope.

+ +

Blocks, Scripts, and Sprites

+ +

This chapter describes the Snap! features inherited from Scratch; +experienced Scratch users can skip to SectionĀ B.

+ +

Snap! is a programming languageā€”a notation in which you can tell a +computer what you want it to do. Unlike most programming languages, +though, Snap! is a visual language; instead of writing a program +using the keyboard, the Snap! programmer uses the same drag-and-drop +interface familiar to computer users.

+ +

{width=ā€4.326388888888889inā€ +height=ā€2.689583333333333inā€}Start Snap![.]{.smallcaps} You should see +the following arrangement of regions in the window:

+ +

(The proportions of these areas may be different, depending on the size +and shape of your browser window.)

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.3541666666666667inā€}A Snap! program consists of one or more +scripts, each of which is made of blocks. Hereā€™s a typical script:

+ +

{width=ā€2.2465277777777777inā€ +height=ā€1.4694444444444446inā€}{width=ā€2.2083333333333335inā€ +height=ā€1.1388888888888888inā€}The five blocks that make up this script +have three different colors, corresponding to three of the eight +palettes in which blocks can be found. The palette area at the left +edge of the window shows one palette at a time, chosen with the eight +buttons just above the palette area. In this script, the gold blocks are +from the Control palette; the green block is from the Pen palette; and +the blue blocks are from the Motion palette. A script is assembled by +dragging blocks from a palette into the scripting area in the middle +part of the window. Blocks snap together (hence the name Snap! for the +language) when you drag a block so that its indentation is near the tab +of the one above it:

+ +

The white horizontal line is a signal that if you let go of the green +block it will snap into the tab of the gold one.

+ +

Hat Blocks and Command Blocks {#hat-blocks-and-command-blocks .ListParagraph}

+ +

At the top of the script is a hat block, which indicates when the +script should be carried out. Hat block names typically start with the +word ā€œwhenā€; in the square-drawing example on page 5, the script should +be run when the green flag near the right end of the Snap! tool bar is +clicked. (The Snap! tool bar is part of the Snap! window, not the +same as the browserā€™s or operating systemā€™s menu bar.) A script isnā€™t +required to have a hat block, but if not, then the script will be run +only if the user clicks on the script itself. A script canā€™t have more +than one hat block, and the hat block can be used only at the top of the +script; its distinctive shape is meant to remind you of that.1

+ +

{width=ā€1.1666666666666667inā€ +height=ā€0.25inā€}The other blocks in our example script are command +blocks. Each command block corresponds to an action that Snap! already +knows how to carry out. For example, the block tells the sprite (the +arrowhead shape on the stage at the right end of the window) to move +ten steps (a step is a very small unit of distance) in the direction in +which the arrowhead is pointing. Weā€™ll see shortly that there can be +more than one sprite, and that each sprite has its own scripts. Also, a +sprite doesnā€™t have to look like an arrowhead, but can have any picture +as a costume. The shape of the move block is meant to remind you of a +Legoā„¢ brick; a script is a stack of blocks. (The word ā€œblockā€ denotes +both the graphical shape on the screen and the procedure, the action, +that the block carries out.)

+ +

{width=ā€1.0972222222222223inā€ +height=ā€0.3541666666666667inā€}The number 10 in the move block above is +called an input to the block. By clicking on the white oval, you can +type any number in place of the 10. The sample script on the previous +page uses 100 as the input value. Weā€™ll see later that inputs can have +non-oval shapes that accept values other than numbers. Weā€™ll also see +that you can compute input values, instead of typing a particular value +into the oval. A block can have more than one input slot. For example, +the glide block located about halfway down the Motion palette has three +inputs.

+ +

Most command blocks have that brick shape, but some, like the repeat +block in the sample script, are Cā€‘shaped. Most C-shaped blocks are +found in the Control palette. The slot inside the C shape is a special +kind of input slot that accepts a script as the input.

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.3541666666666667inā€}

+ +

{width=ā€1.40625inā€ +height=ā€0.4895833333333333inā€}In the sample script

+ +

{width=ā€5.697916666666667inā€ +height=ā€1.445138888888889inā€}C-shaped blocks can be put in a script in +two ways. If you see a white line and let go, the block will be inserted +into the script like any command block:

+ +

{width=ā€5.501388888888889inā€ +height=ā€1.2777777777777777inā€}But if you see an orange halo and let go, +the block will wrap around the haloed blocks:

+ +

{width=ā€5.800694444444445inā€ +height=ā€1.2916666666666667inā€}The halo will always extend from the +cursor position to the bottom of the script:

+ +

If you want only some of those blocks, after wrapping you can grab the +first block you donā€™t want wrapped, pull it down, and snap it under the +C-shaped block.

+ +

{width=ā€2.311111111111111inā€ +height=ā€1.3666666666666667inā€}For ā€œE-shapedā€ blocks with more than one +C-shaped slot, only the first slot will wrap around existing blocks in a +script, and only if that C-shaped slot is empty before wrapping. (You +can fill the other slots by dragging blocks into the desired slot.)

+ +

{width=ā€0.3402777777777778inā€ height=ā€0.24305555555555555inā€}Sprites and Parallelism

+ +

Just below the stage is the ā€œnew spriteā€ button . Click the button to +add a new sprite to the stage. The new sprite will appear in a random +position on the stage, with a random color, but always facing to the +right.

+ +

Each sprite has its own scripts. To see the scripts for a particular +sprite in the scripting area, click on the picture of that sprite in the +sprite corral in the bottom right corner of the window. Try putting +one of the following scripts in each spriteā€™s scripting area:

+ +
+

{width=ā€1.5506944444444444inā€ +height=ā€0.99375inā€} +{width=ā€1.5416666666666667inā€ +height=ā€1.1666666666666667inā€}

+
+ +

When you click the green flag, you should see one sprite rotate while +the other moves back and forth. This experiment illustrates the way +different scripts can run in parallel. The turning and the moving happen +together. Parallelism can be seen with multiple scripts of a single +sprite also. Try this example:

+ +
+

{width=ā€1.7291666666666667inā€ +height=ā€0.875inā€} +{width=ā€1.7291666666666667inā€ +height=ā€0.8958333333333334inā€}

+
+ +

When you press the space key, the sprite should move forever in a +circle, because the move and turn blocks are run in parallel. (To stop +the program, click the red stop sign at the right end of the tool bar.)

+ +

Costumes and Sounds

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.2152777777777778inā€}{width=ā€1.7666666666666666inā€ +height=ā€1.875inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}To change the appearance of a sprite, +paint or import a new costume for it. To paint a costume, click on the +Costumes tab above the scripting area, and click the paint button . The +Paint Editor that appears is explained on page 128. There are three +ways to import a costume. First select the desired sprite in the sprite +corral. Then, one way is to click on the file icon in the tool bar , +then choose the ā€œCostumesā€¦ā€œmenu item. You will see a list of costumes +from the public media library, and can choose one. The second way, for a +costume stored on your own computer, is to click on the file icon and +choose the ā€œImportā€¦ā€ menu item. You can then select a file in any +picture format (PNG, JPEG, etc.) supported by your browser. The third +way is quicker if the file you want is visible on the desktop: Just drag +the file onto the Snap! window. In any of these cases, the scripting +area will be replaced by something like this:

+ +

Just above this part of the window is a set of three tabs: Scripts, +Costumes, and Sounds. Youā€™ll see that the Costumes tab is now selected. +In this view, the spriteā€™s wardrobe, you can choose whether the sprite +should wear its Turtle costume or its Alonzo costume. (Alonzo, the +Snap! mascot, is named after Alonzo Church, a mathematician who +invented the idea of procedures as data, the most important way in which +Snap! is different from Scratch.) You can give a sprite as many +costumes as you like, and then choose which it will wear either by +clicking in its wardrobe or by using the or block in a script. (Every +costume has a number as well as a name. The next costume block selects +the next costume by number; after the highest-numbered costume it +switches to costume 1. The Turtle, costume 0, is never chosen by next +costume.) The Turtle costume is the only one that changes color to match +a change in the spriteā€™s pen color. Protip: switches to the previous +costume, wrapping like next costume.

+ +

{width=ā€1.8055555555555556inā€ +height=ā€0.2777777777777778inā€}{width=ā€2.9493055555555556inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.8958333333333333inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.2395833333333333inā€ +height=ā€0.2604166666666667inā€}In addition to its costumes, a sprite can +have sounds; the equivalent for sounds of the spriteā€™s wardrobe is +called its jukebox. Sound files can be imported in any format (WAV, +OGG, MP3, etc.) supported by your browser. Two blocks accomplish the +task of playing sounds. If you would like a script to continue running +while the sound is playing, use the block . In contrast, you can use the +block to wait for the sound's completion before continuing the rest of +the script.

+ +

Inter-Sprite Communication with Broadcast

+ +

Earlier we saw an example of two sprites moving at the same time. In a +more interesting program, though, the sprites on stage will interact +to tell a story, play a game, etc. Often one sprite will have to tell +another sprite to run a script. Hereā€™s a simple example:

+ +

{width=ā€1.71875inā€ +height=ā€0.24938648293963256inā€}{width=ā€0.5694444444444444inā€ +height=ā€1.1111111111111112inā€} +{width=ā€2.78417760279965inā€ +height=ā€1.5104166666666667inā€} +{width=ā€1.2430555555555556inā€ +height=ā€0.8611111111111112inā€} +{width=ā€1.5208333333333333inā€ +height=ā€0.6041666666666666inā€}

+ +

{width=ā€1.7895833333333333inā€ +height=ā€0.2inā€}{width=ā€1.8inā€ +height=ā€0.19166666666666668inā€}In the block, the word ā€œbarkā€ is just an +arbitrary name I made up. When you click on the downward arrowhead in +that input slot, one of the choices (the only choice, the first time) is +ā€œnew,ā€ which then prompts you to enter a name for the new broadcast. +When this block is run, the chosen message is sent to every sprite, +which is why the block is called ā€œbroadcast.ā€ (But if you click the +right arrow after the message name, the block becomes , and you can +change it to Ā to send the message just to one sprite.) In this program, +though, only one sprite has a script to run when that broadcast is sent, +namely the dog. Because the boyā€™s script uses broadcast and wait rather +than just broadcast, the boy doesnā€™t go on to his next say block until +the dogā€™s script finishes. Thatā€™s why the two sprites take turns +talking, instead of both talking at once. In Chapter VII, +ā€œObject-Oriented Programming with Sprites,ā€ youā€™ll see a more flexible +way to send a message to a specific sprite using the tell and ask +blocks.

+ +

Notice, by the way, that the say blockā€™s first input slot is rectangular +rather than oval. This means the input can be any text string, not only +a number. In text input slots, a space character is shown as a brown +dot, so that you can count the number of spaces between words, and in +particular you can tell the difference between an empty slot and one +containing spaces. The brown dots are not shown on the stage if the +text is displayed.

+ +

The stage has its own scripting area. It can be selected by clicking on +the Stage icon at the left of the sprite corral. Unlike a sprite, +though, the stage canā€™t move. Instead of costumes, it has backgrounds: +pictures that fill the entire stage area. The sprites appear in front of +the current background. In a complicated project, itā€™s often convenient +to use a script in the stageā€™s scripting area as the overall director of +the action.

+ +

Nesting Sprites: Anchors and Parts

+ +

Sometimes itā€™s desirable to make a sort of ā€œsuper-spriteā€ composed of +pieces that can move together but can also be separately articulated. +The classic example is a personā€™s body made up of a torso, limbs, and a +head. Snap! allows one sprite to be designated as the anchor of the +combined shape, with other sprites as its parts. To set up sprite +nesting, drag the sprite corral icon of a part sprite onto the stage +display (not the sprite corral icon!) of the desired anchor sprite. +The precise place where you let go of the mouse button will be the +attachment point of the part on the anchor.

+ +

{width=ā€1.6305555555555555inā€ +height=ā€0.9652777777777778inā€}Sprite nesting is shown in the sprite +corral icons of both anchors and parts:

+ +

{width=ā€4.875694444444444inā€ +height=ā€0.9472222222222222inā€}{width=ā€1.4444444444444444inā€ +height=ā€1.5625inā€}{width=ā€5.405555555555556inā€ +height=ā€0.8333333333333334inā€}In this illustration, it is desired to +animate Alonzoā€™s arm. (The arm has been colored green in this picture to +make the relationship of the two sprites clearer, but in a real project +theyā€™d be the same color, probably.) Sprite, representing Alonzoā€™s body, +is the anchor; Sprite(2) is the arm. The icon for the anchor shows small +images of up to three attached parts at the bottom. The icon for each +part shows a small image of the anchor in its top left corner, and a +synchronous/dangling rotation flag in the top right corner. In its +initial, synchronous setting, as shown above, it means that the when the +anchor sprite rotates, the part sprite also rotates as well as revolving +around the anchor. When clicked, it changes from a circular arrow to a +straight arrow, and indicates that when the anchor sprite rotates, the +part sprite revolves around it, but does not rotate, keeping its +original orientation. (The part can also be rotated separately, using +its turn blocks.) Any change in the position or size of the anchor is +always extended to its parts. Also, cloning the anchor (see Section VII. +B) will also clone all its parts.

+ +

Top: turning the part: the green arm. Bottom: turning the anchor, with +the arm synchronous (left) and dangling (right).

+ +

Reporter Blocks and Expressions

+ +

{width=ā€1.47inā€ +height=ā€0.52inā€}{width=ā€0.7291666666666666inā€ +height=ā€0.15625inā€}So far, weā€™ve used two kinds of blocks: hat blocks +and command blocks. Another kind is the reporter block, which has an +oval shape: . Itā€™s called a ā€œreporterā€ because when itā€™s run, instead of +carrying out an action, it reports a value that can be used as an input +to another block. If you drag a reporter into the scripting area by +itself and click on it, the value it reports will appear in a speech +balloon next to the block:

+ +

{width=ā€5.312752624671916inā€ +height=ā€0.9583333333333334inā€}When you drag a reporter block over +another blockā€™s input slot, a white ā€œhaloā€ appears around that input +slot, analogous to the white line that appears when snapping command +blocks together:

+ +

{width=ā€2.111111111111111inā€ +height=ā€0.6180555555555556inā€}Donā€™t drop the input over a red halo:

+ +

Thatā€™s used for a purpose explained on page 68.

+ +

Hereā€™s a simple script that uses a reporter block:

+ +

{width=ā€5.319444444444445inā€ +height=ā€1.3645833333333333inā€}Here the x position reporter provides the +first input to the say block. (The spriteā€™s X position is its horizontal +position, how far left (negative values) or right (positive values) it +is compared to the center of the stage. Similarly, the Y position is +measured vertically, in steps above (positive) or below (negative) the +center.)

+ +

You can do arithmetic using reporters in the Operators palette:

+ +

{width=ā€6.263888888888889inā€ +height=ā€1.4479166666666667inā€}The round block rounds 35.3905ā€¦ to 35, +and the + block adds 100 to that. (By the way, the round block is in the +Operators palette, just like +, but in this script itā€™s a lighter color +with black lettering because Snap! alternates light and dark versions +of the palette colors when a block is nested inside another block from +the same palette:

+ +

{width=ā€4.854166666666667inā€ +height=ā€1.90625inā€}

+ +

{width=ā€1.9166666666666667inā€ +height=ā€0.23958333333333334inā€}This aid to readability is called zebra +coloring.) A reporter block with its inputs, maybe including other +reporter blocks, such as , is called an expression.

+ +

Predicates and Conditional Evaluation

+ +

{width=ā€0.6666666666666666inā€ +height=ā€0.1875inā€}{width=ā€1.2083333333333333inā€ +height=ā€0.1875inā€}Most reporters report either a number, like , or a +text string, like . A predicate is a special kind of reporter that +always reports true or false. Predicates have a hexagonal shape:

+ +

{width=ā€1.9479166666666667inā€ +height=ā€0.2604166666666667inā€}{width=ā€1.0729166666666667inā€ +height=ā€0.15625inā€}The special shape is a reminder that predicates donā€™t +generally make sense in an input slot of blocks that are expecting a +number or text. You wouldnā€™t say , although (as you can see from the +picture) Snap! lets you do it if you really want. Instead, you +normally use predicates in special hexagonal input slots like this one:

+ +

{width=ā€0.6666666666666666inā€ +height=ā€0.5694444444444444inā€}The C-shaped if block runs its input +script if (and only if) the expression in its hexagonal input reports +true.

+ +

{width=ā€1.59375inā€ +height=ā€0.6145833333333334inā€}A really useful block in animations runs +its input script repeatedly until a predicate is satisfied:

+ +

{width=ā€2.2819444444444446inā€ +height=ā€1.46875inā€}{width=ā€2.2916666666666665inā€ +height=ā€0.84375inā€}If, while working on a project, you want to omit +temporarily some commands in a script, but you donā€™t want to forget +where they belong, you can say

+ +

Sometimes you want to take the same action whether some condition is +true or false, but with a different input value. For this purpose you +can use the reporter if block:

+ +

{width=ā€4.208333333333333inā€ +height=ā€0.3854166666666667inā€}The technical term for a true or false +value is a ā€œBooleanā€ value; it has a capital B because itā€™s named after +a person, George Boole, who developed the mathematical theory of Boolean +values. Donā€™t get confused; a hexagonal block is a predicate, but the +value it reports is a Boolean.

+ +

Another quibble about vocabulary: Many programming languages reserve the +name ā€œprocedureā€ for Commands (that carry out an action) and use the +name ā€œfunctionā€ for Reporters and Predicates. In this manual, a +procedure is any computational capability, including those that report +values and those that donā€™t. Commands, Reporters, and Predicates are all +procedures. The words ā€œa Procedure typeā€ are shorthand for ā€œCommand +type, Reporter type, or Predicate type.ā€

+ +

{width=ā€1.375inā€ +height=ā€0.24305555555555555inā€}{width=ā€1.375inā€ +height=ā€0.24305555555555555inā€}If you want to put a constant Boolean +value in a hexagonal slot instead of a predicate-based expression, hover +the mouse over the block and click on the control that appears:

+ +

Variables

+ +

{width=ā€1.5833333333333333inā€ +height=ā€1.4166666666666667inā€}Try this script:

+ +

{width=ā€1.8854166666666667inā€ +height=ā€1.4375inā€}The input to the move block is an orange oval. To get +it there, drag the orange oval thatā€™s part of the for block:

+ +

The orange oval is a variable: a symbol that represents a value. (I +took this screenshot before changing the second number input to the for +block from the default 10 to 200, and before dragging in a turn block.) +For runs its script input repeatedly, just like repeat, but before each +repetition it sets the variable i to a number starting with its first +numeric input, adding 1 for each repetition, until it reaches the second +numeric input. In this case, there will be 200 repetitions, first with +i=1, then with i=2, then 3, and so on until i=200 for the final +repetition. The result is that each move draws a longer and longer line +segment, and thatā€™s why the picture you see is a kind of spiral. (If you +try again with a turn of 90 degrees instead of 92, youā€™ll see why this +picture is called a ā€œsquiral.ā€)

+ +

{width=ā€3.1875inā€ +height=ā€1.5inā€}The variable i is created by the for block, and it can +only be used in the script inside the blockā€™s C-slot. (By the way, if +you donā€™t like the name i, you can change it by clicking on the orange +oval without dragging it, which will pop up a dialog window in which you +can enter a different name:

+ +

ā€œIā€ isnā€™t a very descriptive name; you might prefer ā€œlengthā€ to indicate +its purpose in the script. ā€œIā€ is traditional because mathematicians +tend to use letters between i and n to represent integer values, but in +programming languages we donā€™t have to restrict ourselves to +single-letter variable names.)

+ +

Global Variables

+ +

You can create variables ā€œby handā€ that arenā€™t limited to being used +within a single block. At the top of the Variables palette, click the +ā€œMake a variableā€ button:

+ +

{width=ā€3.1875inā€ +height=ā€1.84375inā€}{width=ā€2.0520833333333335inā€ +height=ā€2.2708333333333335inā€}This will bring up a dialog window in +which you can give your variable a name:

+ +

The dialog also gives you a choice to make the variable available to all +sprites (which is almost always what you want) or to make it visible +only in the current sprite. Youā€™d do that if youā€™re going to give +several sprites individual variables with the same name, so that you +can share a script between sprites (by dragging it from the current +spriteā€™s scripting area to the picture of another sprite in the sprite +corral), and the different sprites will do slightly different things +when running that script because each has a different value for that +variable name.

+ +

{width=ā€1.6583333333333334inā€ +height=ā€2.2916666666666665inā€}If you give your variable the name ā€œnameā€ +then the Variables palette will look like this:

+ +

{width=ā€1.0416666666666667inā€ +height=ā€0.40625inā€}Thereā€™s now a ā€œDelete a variableā€ button, and thereā€™s +an orange oval with the variable name in it, just like the orange oval +in the for block. You can drag the variable into any script in the +scripting area. Next to the oval is a checkbox, initially checked. When +itā€™s checked, youā€™ll also see a variable watcher on the stage:

+ +

When you give the variable a value, the orange box in its watcher will +display the value.

+ +

{width=ā€1.9270833333333333inā€ +height=ā€0.4791666666666667inā€}How do you give it a value? You use the +set block:

+ +

Note that you donā€™t drag the variableā€™s oval into the set block! You +click on the downarrow in the first input slot, and you get a menu of +all the available variable names.

+ +

If you do choose ā€œFor this sprite onlyā€ when creating a variable, its +block in the palette looks like this:

+ +

Macintosh
+HD:Users:bh:Desktop:local-var.png{width=ā€0.6583333333333333inā€ +height=ā€0.14166666666666666inā€} The location-pin icon is a bit of a +pun on a sprite-local variable. Itā€™s shown only in the palette.

+ +

Script Variables

+ +

{width=ā€5.503472222222222inā€ +height=ā€2.3125inā€}In the name example above, our project is going to +carry on an interaction with the user, and we want to remember their +name throughout the project. Thatā€™s a good example of a situation in +which a global variable (the kind you make with the ā€œMake a variableā€ +button) is appropriate. Another common example is a variable called +ā€œscoreā€ in a game project. But sometimes you only need a variable +temporarily, during the running of a particular script. In that case you +can use the script variables block to make the variable:

+ +

As in the for block, you can click on an orange oval in the script +variables block without dragging to change its name. You can also make +more than one temporary variable by clicking on the right arrow at the +end of the block to add another variable oval:

+ +

{width=ā€2.0833333333333335inā€ height=ā€0.3020833333333333inā€}Renaming variables

+ +

There are several reasons why you might want to change the name of a +variable:

+ +
    +
  1. +

    It has a default name, such as the ā€œaā€ in script variables or the +ā€œiā€ in for.

    +
  2. +
  3. +

    It conflicts with another name, such as a global variable, that you +want to use in the same script.

    +
  4. +
  5. +

    You just decide a different name would be more self-documenting.

    +
  6. +
+ +

In the first and third case, you probably want to change the name +everywhere it appears in that script, or even in all scripts. In the +second case, if youā€™ve already used both variables in the script before +realizing that they have the same name, youā€™ll want to look at each +instance separately to decide which ones to rename. Both of these +operations are possible by right-clicking or control-clicking on a +variable oval.

+ +

{width=ā€1.613888888888889inā€ +height=ā€1.507638888888889inā€}{width=ā€2.826388888888889inā€ +height=ā€1.2569444444444444inā€}{width=ā€1.3819444444444444inā€ +height=ā€0.7430555555555556inā€}If you right-click on an orange oval in a +context in which the variable is used, then you are able to rename +just that one orange oval:

+ +

{width=ā€1.7083333333333333inā€ +height=ā€0.8333333333333334inā€}{width=ā€1.4930555555555556inā€ +height=ā€0.7430555555555556inā€}If you right-click on the place where the +variable is defined (a script variables block, the orange oval for a +global variable in the Variables palette, or an orange oval thatā€™s built +into a block such as the ā€œiā€ in for), then you are given two renaming +options, ā€œrenameā€ and ā€œrename all.ā€ If you choose ā€œrename,ā€ then the +name is changed only in that one orange oval, as in the previous case:

+ +

{width=ā€1.4930555555555556inā€ +height=ā€0.7430555555555556inā€}{width=ā€1.7083333333333333inā€ +height=ā€0.8333333333333334inā€}But if you choose ā€œrename all,ā€ then the +name will be changed throughout the scope of the variable (the script +for a script variable, or everywhere for a global variable):

+ +

Transient variables

+ +

{width=ā€1.2916666666666667inā€ +height=ā€1.0555555555555556inā€}So far weā€™ve talked about variables with +numeric values, or with short text strings such as someoneā€™s name. But +thereā€™s no limit to the amount of information you can put in a variable; +in Chapter IV youā€™ll see how to use lists to collect many values in +one data structure, and in Chapter VIII youā€™ll see how to read +information from web sites. When you use these capabilities, your +project may take up a lot of memory in the computer. If you get close to +the amount of memory available to Snap!, then it may become impossible +to save your project. (Extra space is needed temporarily to convert from +Snap! ā€˜s internal representation to the form in which projects are +exported or saved.) If your program reads a lot of data from the outside +world that will still be available when you use it next, you might want +to have values containing a lot of data removed from memory before +saving the project. To do this, right-click or control-click on the +orange oval in the Variables palette, to see this menu:

+ +

You already know about the rename options, and helpā€¦ displays a help +screen about variables in general. Here weā€™re interested in the check +box next to transient. If you check it, this variableā€™s value will not +be saved when you save your project. Of course, youā€™ll have to ensure +that when your project is loaded, it recreates the needed value and sets +the variable to it.

+ +

Debugging

+ +

Snap! provides several tools to help you debug a program. They center +around the idea of pausing the running of a script partway through, so +that you can examine the values of variables.

+ +

The pause button

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The simplest way to pause a program is +manually, by clicking the pause button in the top right corner of the +window. While the program is paused, you can run other scripts by +clicking on them, show variables on stage with the checkbox next to the +variable in the Variables palette or with the show variable block, and +do all the other things you can generally do, including modifying the +paused scripts by adding or removing blocks. The button changes shape to +and clicking it again resumes the paused scripts.

+ +

Breakpoints: the pause all block

+ +

{width=ā€0.8194444444444444inā€ +height=ā€0.2152777777777778inā€}The pause button is great if your program +seems to be in an infinite loop, but more often youā€™ll want to set a +breakpoint, a particular point in a script at which you want to pause. +The block, near the bottom of the Control palette, can be inserted in a +script to pause when it is run. So, for example, if your program is +getting an error message in a particular block, you could use pause all +just before that block to look at the values of variables just before +the error happens.

+ +

{width=ā€1.8833333333333333inā€ +height=ā€0.9111111111111111inā€}The pause all block turns bright cyan +while paused. Also, during the pause, you can right-click on a running +script and the menu that appears will give you the option to show +watchers for temporary variables of the script:

+ +

But what if the block with the error is run many times in a loop, and it +only errors when a particular condition is trueā€”say, the value of some +variable is negative, which shouldnā€™t ever happen. In the iteration +library (see page 25 for more about how to use libraries) is a +breakpoint block that lets you set a conditional breakpoint, and +automatically display the relevant variables before pausing. Hereā€™s a +sample use of it:

+ +

{width=ā€1.1944444444444444inā€ +height=ā€1.3333333333333333inā€}(In this contrived example, variable zot +comes from outside the script but is relevant to its behavior.) When you +continue (with the pause button), the temporary variable watchers are +removed by this breakpoint block before resuming the script. The +breakpoint block isnā€™t magic; you could alternatively just put a pause +all inside an if.2

+ +

Visible stepping

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.5456342957130359inā€ +height=ā€0.1527777777777778inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Sometimes youā€™re not exactly sure where +the error is, or you donā€™t understand how the program got there. To +understand better, youā€™d like to watch the program as it runs, at human +speed rather than at computer speed. You can do this by clicking the +visible stepping button ( ), before running a script or while the +script is paused. The button will light up ( ) and a speed control +slider will appear in the toolbar. When you start or continue the +script, its blocks and input slots will light up cyan one at a time:

+ +

{width=ā€7.498611111111111inā€ +height=ā€1.15inā€}In this simple example, the inputs to the blocks are +constant values, but if an input were a more complicated expression +involving several reporter blocks, each of those would light up as they +are called. Note that the input to a block is evaluated before the block +itself is called, so, for example, the 100 lights up before the move.

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The speed of stepping is controlled by +the slider. If you move the slider all the way to the left, the speed is +zero, the pause button turns into a step button , and the script takes a +single step each time you push it. The name for this is single +stepping.

+ +

If several scripts that are visible in the scripting area are running at +the same time, all of them are stepped in parallel. However, consider +the case of two repeat loops with different numbers of blocks. While not +stepping, each script goes through a complete cycle of its loop in each +display cycle, despite the difference in the length of a cycle. In order +to ensure that the visible result of a program on the stage is the same +when stepped as when not stepped, the shorter script will wait at the +bottom of its loop for the longer script to catch up.

+ +

When we talk about custom blocks in Chapter III, weā€™ll have more to say +about visible stepping as it affects those blocks.

+ +

Etcetera

+ +

This manual doesnā€™t explain every block in detail. There are many more +motion blocks, sound blocks, costume and graphics effects blocks, and so +on. You can learn what they all do by experimentation, and also by +reading the ā€œhelp screensā€ that you can get by right-clicking or +control-clicking a block and selecting ā€œhelpā€¦ā€ from the menu that +appears. If you forget what palette (color) a block is, but you remember +at least part of its name, type control-F and enter the name in the text +block that appears in the palette area.

+ +

Here are the primitive blocks that donā€™t exist in Scratch:

+ +

{width=ā€1.25inā€ +height=ā€0.22916666666666666inā€}{width=ā€1.0520833333333333inā€ +height=ā€0.22916666666666666inā€} reports a new costume consisting of +everything thatā€™s drawn on the stage by any sprite. Right-clicking the +block in the scripting area gives the option to change it to if vector +logging is enabled. See page 116.

+ +

{width=ā€2.0833333333333335inā€ +height=ā€0.375inā€}Print characters in the given point size on the stage, +at the spriteā€™s position and in its direction. The sprite moves to the +end of the text. (Thatā€™s not always what you want, but you can save the +spriteā€™s position before using it, and sometimes you need to know how +big the text turned out to be, in turtle steps.) If the pen is down, the +text will be underlined.

+ +

{width=ā€1.2006944444444445inā€ +height=ā€0.5138888888888888inā€}Takes a sprite as input. Like stamp except +that the costume is stamped onto the selected sprite instead of onto the +stage. (Does nothing if the current sprite doesnā€™t overlap the chosen +sprite.)

+ +

{width=ā€1.1916666666666667inā€ +height=ā€0.3388888888888889inā€}Takes a sprite as input. Erases from that +spriteā€™s costume the area that overlaps with the current spriteā€™s +costume. (Does not affect the costume in the chosen spriteā€™s wardrobe, +only the copy currently visible.)

+ +

{width=ā€0.5298611111111111inā€ +height=ā€0.5inā€}{width=ā€0.9895833333333334inā€ +height=ā€0.25972222222222224inā€}Icon Description automatically
+generated{width=ā€1.3298611111111112inā€ +height=ā€0.42986111111111114inā€} See page 6. See page 17.

+ +

{width=ā€1.71inā€ +height=ā€0.23inā€}Reporter version of the if/else primitive command block. +Only one of the two branches is evaluated, depending on the value of the +first input.

+ +

{width=ā€1.83inā€ +height=ā€0.61inā€}Looping block like repeat but with an index variable.

+ +

{width=ā€1.3798611111111112inā€ +height=ā€0.28958333333333336inā€}Declare local variables in a script.

+ +

{width=ā€0.86inā€ +height=ā€0.19inā€}{width=ā€0.72inā€ +height=ā€0.2inā€}{width=ā€1.17inā€ +height=ā€0.18inā€} See page 91.

+ +

{width=ā€2.738611111111111inā€ +height=ā€0.2116819772528434inā€}Constant true or false value. See page 12.

+ +

{width=ā€2.13inā€ height=ā€0.18inā€} +Create a primitive using JavaScript. (This block is disabled by default; +the user must check ā€œJavascript extensionsā€ in the setting menu each +time a project is loaded.)

+ +

{width=ā€1.6305555555555555inā€ +height=ā€1.5756944444444445inā€}The at block lets you examine the screen +pixel directly behind the rotation center of a sprite, the mouse, or an +arbitrary (x,y) coordinate pair dropped onto the second menu slot. The +first five items of the left menu let you examine the color visible at +the position. (The ā€œRGBAā€ option reports a list.) The ā€œspritesā€ option +reports a list of all sprites, including this one, any point of which +overlaps this spriteā€™s rotation center (behind or in front). This is a +hyperblock with respect to its second input.

+ +

{width=ā€1.6862992125984253inā€ +height=ā€1.852853237095363inā€}{width=ā€2.4458333333333333inā€ +height=ā€1.3263888888888888inā€}{width=ā€2.3555555555555556inā€ +height=ā€0.3888888888888889inā€} Checks the data type of a value.

+ +

{width=ā€3.398297244094488inā€ +height=ā€1.065152012248469inā€}

+ +

{width=ā€2.504166666666667inā€ +height=ā€2.23125inā€}Turn the text into a list, using the second input as +the delimiter between items. The default delimiter, indicated by the +brown dot in the input slot, is a single space character. ā€œLetterā€ puts +each character of the text in its own list item. ā€œWordā€ puts each word +in an item. (Words are separated by any number of consecutive space, +tab, carriage return, or newline characters.) ā€œLineā€ is a newline +character (0xa); ā€œtabā€ is a tab character (0x9); ā€œcrā€ is a carriage +return (0xd). ā€œCsvā€ and ā€œjsonā€ split formatted text into lists of lists; +see page 54. ā€œBlocksā€ takes a script as the first input, reporting a +list structure representing the structure of the script. See Chapter XI.

+ +

{width=ā€1.479861111111111inā€ +height=ā€0.18958333333333333inā€}For lists, reports true only if its two +input values are the very same list, so changing an item in one of them +is visible in the other. (For =, lists that look the same are the same.) +For text strings, uses case-sensitive comparison, unlike =, which is +case-independent.

+ +

{width=ā€2.867929790026247inā€ +height=ā€0.18958333333333333inā€}These hidden blocks can be found with +the relabel option of any dyadic arithmetic block. Theyā€™re hidden partly +because writing them in Snap! is a good, pretty easy programming +exercise. Note: the two inputs to atan2 are Ī”x and Ī”y in that order, +because we measure angles clockwise from north. Max and min are +variadic; by clicking the arrowhead, you can provide additional +inputs.

+ +

Logo Description automatically generated with medium
+confidence{width=ā€0.63inā€ +height=ā€0.19inā€} A picture containing text, monitor, screenshot
+Description automatically
+generated{width=ā€0.63inā€ +height=ā€0.19inā€} Logo Description automatically
+generated{width=ā€0.63inā€ +height=ā€0.19inā€} Similarly, these hidden predicates can be found by +relabeling the relational predicates.

+ +

{width=ā€5.449558180227472inā€ +height=ā€0.6166666666666667inā€}Metaprogramming (see Chapter XI. , +page 101)

+ +

These blocks support metaprogramming, which means manipulating blocks +and scripts as data. This is not the same as manipulating procedures +(see Chapter VI. ), which are what the blocks mean; in metaprogramming +the actual blocks, what you see on the screen, are the data. This +capability is new in version 8.0.

+ +

First class list blocks (see Chapter IV, page 46):

+ +

{width=ā€7.616666666666666inā€ +height=ā€2.183333333333333inā€}

+ +


+**{width=ā€0.83inā€ +height=ā€0.21inā€} {width=ā€1.43inā€ +height=ā€0.21inā€} **report the sprite or mouse position as a two-item +vector (x,y).

+ +

{width=ā€5.9944444444444445inā€ +height=ā€0.325inā€}First class procedure blocks (see Chapter VI, page +65):

+ +

{width=ā€5.330555555555556inā€ +height=ā€0.3451388888888889inā€}{width=ā€4.361111111111111inā€ +height=ā€0.325inā€}First class continuation blocks (see Chapter X, +page 93):

+ +

First class sprite, costume, and sound blocks (see Chapter VII, page +73):

+ +

{width=ā€5.88125inā€ +height=ā€2.1479166666666667inā€}

+ +

Scenes:

+ +

{width=ā€2.38inā€ +height=ā€1.32inā€}The major new feature of version 7.0 is scenes: A +project can include within it sub-projects, called scenes, each with its +own stage, sprites, scripts, and so on. This block makes another scene +active, replacing the current one.

+ +

Nothing is automatically shared between scenes: no sprites, no blocks, +no variables. But the old scene can send a message to the new one, to +start it running, with optional payload as in broadcast (page 23).

+ +

{width=ā€2.54inā€ +height=ā€0.31inā€}{width=ā€3.129861111111111inā€ +height=ā€0.5236111111111111inā€}In particular, you can say

+ +
+

if the new scene expects to be started with a green flag signal.

+
+ +


+These arenā€™t new blocks but they have a new feature:

+ +

These accept two-item (x,y) lists as input, and have extended menus +(also including other sprites):

+ +

{width=ā€7.483252405949257inā€ +height=ā€1.1298611111111112inā€}ā€Centerā€ means the center of the stage, +the point at (0,0). ā€œDirectionā€ is in the point in direction sense, the +direction that would leave this sprite pointing toward another sprite, +the mouse, or the center. ā€œRay lengthā€ is the distance from the center +of this sprite to the nearest point on the other sprite, in the current +direction.

+ +

{width=ā€2.571527777777778inā€ +height=ā€1.41875inā€}The stop block has two extra menu choices. Stop this +block is used inside the definition of a custom block to stop just this +invocation of this custom block and continue the script that called it. +Stop all but this script is good at the end of a game to stop all the +game pieces from moving around, but keep running this script to provide +the userā€™s final score. The last two menu choices add a tab at the +bottom of the block because the current script can continue after it.

+ +

{width=ā€2.4125inā€ +height=ā€1.0659722222222223inā€}The new ā€œpen trailsā€ option is true if the +sprite is touching any drawn or stamped ink on the stage. Also, touching +will not detect hidden sprites, but a hidden sprite can use it to detect +visible sprites.

+ +

{width=ā€1.0597222222222222inā€ +height=ā€0.2798611111111111inā€}{width=ā€2.433333333333333inā€ +height=ā€0.3inā€}The video block has a snap option that takes a snapshot +and reports it as a costume. It is hyperized with +{width=ā€1.0520833333333333inā€ +height=ā€0.28125inā€}respect to its second input.

+ +

{width=ā€1.4166666666666667inā€ +height=ā€3.3319444444444444inā€}The ā€œnegā€ option is a monadic negation +operator, equivalent to . ā€œlgā€ is log~2~. ā€œidā€ is the identity function, +which reports its input. ā€œsignā€ reports 1 for positive input, 0 for zero +input, or -1 for negative input.

+ +

{width=ā€3.286111111111111inā€ +height=ā€0.5513888888888889inā€}

+ +

{width=ā€3.7604166666666665inā€ +height=ā€1.214646762904637inā€}

+ +

{width=ā€2.213888888888889inā€ +height=ā€1.6604166666666667inā€}Extended mouse interaction events, sensing +clicking, dragging, hovering, etc. The ā€œstoppedā€ option triggers when +all scripts are stopped, as with the stop button; it is useful for +robots whose hardware interface must be told to turn off motors. A when +I am stopped script can run only for a limited time.

+ +

{width=ā€2.879861111111111inā€ +height=ā€1.717186132983377inā€}

+ +

Extended broadcast: Click the right arrowhead to direct the message to a +single sprite or the stage. Click again to add any value as a payload to +the message.

+ +

{width=ā€3.7784722222222222inā€ +height=ā€1.8090277777777777inā€}{width=ā€1.8194444444444444inā€ +height=ā€0.9597222222222223inā€}Extended when I receive: Click the right +arrowhead to expose a script variable (click on it to change its name, +like any script variable) that will be set to the data of a matching +broadcast. If the first input is set to ā€œany message,ā€ then the data +variable will be set to the message, if no payload is included with the +broadcast, or to a two-item list containing the message and the payload.

+ +

A picture containing text, clipart Description automatically
+generated{width=ā€1.68inā€ +height=ā€0.38inā€} If the input is set to ā€œany key,ā€ then a right +arrowhead appears:

+ +
+

{width=ā€2.25inā€ +height=ā€0.41944444444444445inā€}{width=ā€1.8194444444444444inā€ +height=ā€0.3798611111111111inā€}and if you click it, a script variable +key is created whose value is the key that was pressed. (If the key is +one thatā€™ represented in the input menu by a word or phrase, e.g., +ā€œenterā€ or ā€œup arrow,ā€ then the value of key will be that word or +phrase, except for the space character, which is represented as +itself in key.)
+{width=ā€3.0924245406824147inā€ +height=ā€0.6895833333333333inā€}

+
+ +

{width=ā€5.95inā€ +height=ā€0.8798611111111111inā€}{width=ā€5.569444444444445inā€ +height=ā€1.1inā€}{width=ā€6.3694444444444445inā€ +height=ā€2.9086690726159232inā€}

+ +

{width=ā€1.455618985126859inā€ +height=ā€2.327904636920385inā€}{width=ā€5.874242125984252inā€ +height=ā€1.0097222222222222inā€}These ask features and more in the Menus +library.

+ +

The of block has an extended menu of attributes of a sprite. Position +reports an (x,y) vector. Size reports the percentage of normal size, as +controlled by the set size block in the Looks category. Left, right, +etc. report the stage coordinates of the corresponding edge of the +spriteā€™s bounding box. Variables reports a list of the names of all +variables in scope (global, sprite-local, and script variables if the +right input is a script.

+ +

Libraries

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}{width=ā€7.401388888888889inā€ +height=ā€3.238888888888889inā€}There are several collections of useful +procedures that arenā€™t Snap! primitives, but are provided as +libraries. To include a library in your project, choose the Librariesā€¦ +option in the file ( ) menu.

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs.

+ +

The libraries and their contents may change, but as of this writing the +list library has these blocks:

+ +

{width=ā€1.8486111111111112inā€ +height=ā€2.4923611111111112inā€} (The lightning bolt before the name in +several of these blocks means that they use compiled HOFs or JavaScript +primitives to achieve optimal speed. They are officially considered +experimental.) Remove duplicates from reports a list in which no two +items are equal. The sort block takes a list and a two-input comparison +predicate, such as <, and reports a list with the items sorted +according to that comparison. The assoc block is for looking up a key in +an association list: a list of two-item lists. In each two-item list, +the first is a key and the second is a value. The inputs are a key +and an association list; the block reports the first key-value pair +whose key is equal to the input key.

+ +

For each item is a variant of the primitive version that provides a # +variable containing the position in the input list of the currently +considered item. Multimap is a version of map that allows multiple list +inputs, in which case the mapping function must take as many inputs as +there are lists; it will be called with all the first items, all the +second items, and so on. Zip takes any number of lists as inputs; it +reports a list of lists: all the first items, all the second items, and +so on. The no-name identity function reports its input.

+ +

Sentence and sentenceāž”list are borrowed from the word and sentence +library (page 27) to serve as a variant of append that accepts non-lists +as inputs. Printable takes a list structure of any depth as input and +reports a compact representation of the list as a text string.

+ +

The iteration, composition library has these blocks:

+ +

{width=ā€1.6888888888888889inā€ +height=ā€4.75inā€}Catch and throw provide a nonlocal exit facility. You +can drag the tag from a catch block to a throw inside its C-slot, and +the throw will then jump directly out to the matching catch without +doing anything in between.

+ +

If do and pause all is for setting a breakpoint while debugging code. +The idea is to put show variable blocks for local variables in the +C-slot; the watchers will be deleted when the user continues from the +pause.

+ +

Ignore is used when you need to call a reporter but you donā€™t care about +the value it reports. (For example, you are writing a script to time how +long the reporter takes.)

+ +

The cascade blocks take an initial value and call a function repeatedly +on that value, f(f(f(fā€¦(x)))).

+ +

The compose block takes two functions and reports the function +f(g(x)).

+ +

{width=ā€1.0444444444444445inā€ +height=ā€0.16111111111111112inā€}{width=ā€3.1527777777777777inā€ +height=ā€0.2986111111111111inā€}The first three repeat blocks are variants +of the primitive repeat until block, giving all four combinations of +whether the first test happens before or after the first repetition, and +whether the condition must be true or false to continue repeating. The +last repeat block is like the repeat primitive, but makes the number of +repetitions so far available to the repeated script. The next two blocks +are variations on for: the first allows an explicit step instead of +using Ā±1, and the second allows any values, not just numbers; inside the +script you say

+ +

{width=ā€3.4409722222222223inā€ +height=ā€1.3611111111111112inā€}{width=ā€3.709722222222222inā€ +height=ā€1.1715277777777777inā€}replacing the grey block in the picture +with an expression to give the next desired value for the loop index. +Pipe allows reordering a nested composition with a left-to-right one:

+ +

The stream library has these blocks:

+ +

{width=ā€3.161111111111111inā€ +height=ā€2.1534722222222222inā€}Streams are a special kind of list whose +items are not computed until they are needed. This makes certain +computations more efficient, and also allows the creation of lists with +infinitely many items, such as a list of all the positive integers. The +first five blocks are stream versions of the list blocks in front of, +item 1 of, all but first of, map, and keep. Show stream takes a stream +and a number as inputs, and reports an ordinary list of the first n +items of the stream. Stream is like the primitive list; it makes a +finite stream from explicit items. Sieve is an example block that takes +as input the stream of integers starting with 2 and reports the stream +of all the prime numbers. Stream with numbers from is like the numbers +from block for lists, except that there is no endpoint; it reports an +infinite stream of numbers.

+ +

The word and sentence library has these blocks:

+ +

{width=ā€1.679861111111111inā€ +height=ā€3.6430555555555557inā€}This library has the goal of recreating +the Logo approach to handling text: A text isnā€™t best viewed as a string +of characters, but rather as a sentence, made of words, each of +which is a string of letters. With a few specialized exceptions, this +is why people put text into computers: The text is sentences of natural +(i.e., human) language, and the emphasis is on words as constitutive of +sentences. You barely notice the letters of the words, and you donā€™t +notice the spaces between them at all, unless youā€™re proof-reading. +(Even then: Proofreading is diffciult, because you see what you expect +to see, what will make the snetence make sense, rather than the +misspelling in front of of your eyes.) Internally, Logo stores a +sentence as a list of words, and a word as a string of letters.

+ +

Inexplicably, the designers of Scratch chose to abandon that tradition, +and to focus on the representation of text as a string of characters. +The one vestige of the Logo tradition from which Scratch developed is +the block named letter (1) of (world), rather than character (1) of +(world). Snap! inherits its text handling from Scratch.

+ +

In Logo, the visual representation of a sentence (a list of words) looks +like a natural language sentence: a string of words with spaces between +them. In Snap!, the visual representation of a list looks nothing at +all like natural language. On the other hand, representing a sentence as +a string means that the program must continually re-parse the text on +every operation, looking for spaces, treating multiple consecutive +spaces as one, and so on. Also, itā€™s more convenient to treat a sentence +as a list of words rather than a string of words because in the former +case you can use the higher order functions map, keep, and combine on +them. This library attempts to be agnostic as to the internal +representation of sentences. The sentence selectors accept any +combination of lists and strings; there are two sentence constructors, +one to make a string (join words) and one to make a list (sentence).

+ +

The selector names come from Logo, and should be self-explanatory. +However, because in a block language you donā€™t have to type the block +name, instead of the terse butfirst or the cryptic bf we spell out ā€œall +but first ofā€ and include ā€œwordā€ or ā€œsentenceā€ to indicate the intended +domain. Thereā€™s no first letter of block because letter 1 of serves that +need. Join words (the sentence-as-string constructor) is like the +primitive join except that it puts a space in the reported value between +each of the inputs. Sentence (the List-colored sentence-as-list +constructor) accepts any number of inputs, which can be words, +sentences-as-lists, or sentences-as-strings. (If inputs are lists of +lists, only one level of flattening is done.) Sentence reports a list of +words; there will be no empty words or words containing spaces. The four +blocks with right-arrows in their names convert back and forth between +text strings (words or sentences) and lists. (Splitting a word into a +list of letters is unusual unless youā€™re a linguist investigating +orthography.) Printable takes a list (including a deep list) of words as +input and reports a text string in which parentheses are used to show +the structure, as in Lisp/Scheme.

+ +

The pixels library has one block:

+ +

{width=ā€0.7791666666666667inā€ +height=ā€0.6298611111111111inā€}Costumes are first class data in Snap!. +Most of the processing of costume data is done by primitive blocks in +the Looks category. (See page 79.) This library provides snap, which +takes a picture using your computerā€™s camera and reports it as a +costume.

+ +

The bar charts library has these blocks:

+ +

{width=ā€3.4305555555555554inā€ +height=ā€1.9166666666666667inā€}Bar chart takes a table (typically from a +CSV data set) as input and reports a summary of the table grouped by the +field in the specified column number. The remaining three inputs are +used only if the field values are numbers, in which case they can be +grouped into buckets (e.g., decades, centuries, etc.). Those inputs +specify the smallest and largest values of interest and, most +importantly, the width of a bucket (10 for decades, 100 for centuries). +If the field isn't numeric, leave these three inputs empty or set them +to zero. Each string value of the field is its own bucket, and they +appear sorted alphabetically.

+ +

Bar chart reports a new table with three columns. The first column +contains the bucket name or smallest number. The second column contains +a nonnegative integer that says how many records in the input table fall +into this bucket. The third column is a subtable containing the actual +records from the original table that fall into the bucket. Plot bar +chart takes the table reported by bar chart and graphs it on the stage, +with axes labelled appropriately. The remaining blocks are helpers for +those.

+ +

If your buckets aren't of constant width, or you want to group by some +function of more than one field, load the "Frequency Distribution +Analysis" library instead.

+ +

The multi-branched conditional library has these blocks:

+ +

{width=ā€1.85inā€ +height=ā€2.479861111111111inā€}The catch and throw blocks duplicate ones +in the iteration library, and are included because they are used to +implement the others. The cases block sets up a multi-branch +conditional, similar to cond in Lisp or switch in C-family languages. +The first branch is built into the cases block; it consists of a Boolean +test in the first hexagonal slot and an action script, in the C-slot, to +be run if the test reports true. The remaining branches go in the +variadic hexagonal input at the end; each branch consists of an else if +block, which includes the Boolean test and the corresponding action +script, except possibly for the last branch, which can use the +unconditional else block. As in other languages, once a branch succeeds, +no other branches are tested.

+ +

###

+ +

The variadic library has these blocks:

+ +

{width=ā€1.1965277777777779inā€ +height=ā€0.4166666666666667inā€}These are versions of the associative +operators and, and or that take any number of inputs instead of exactly +two inputs. As with any variadic input, you can also drop a list of +values onto the arrowheads instead of providing the inputs one at a time +As of version 8.0, the arithmetic operators sum, product, minimum, and +maximum are no longer included, because the primitive operators +. Ɨ, +min, and max are themselves variadic.

+ +

{width=ā€7.277083333333334inā€ +height=ā€1.1027777777777779inā€}The colors and crayons library has these +blocks:

+ +

It is intended as a more powerful replacement for the primitive set pen +block, including first class color support; HSL color specification as +a better alternative to the HSV that Snap! inherits from JavaScript; a +ā€œfair hueā€ scale that compensates for the eyeā€™s grouping a wide range of +light frequencies as green while labelling mere slivers as orange or +yellow; the X11/W3C standard color names; RGB in hexadecimal; a linear +color scale (as in the old days, but better) based on fair hues and +including shades (darker colors) and grayscale. Another linear scale is +a curated set of 100 ā€œcrayons,ā€ explained further on the next page.

+ +

{width=ā€3.0590277777777777inā€ +height=ā€2.283333333333333inā€}{width=ā€1.1333333333333333inā€ +height=ā€0.23333333333333334inā€}{width=ā€0.95inā€ +height=ā€0.225inā€}Colors are created by the block (for direct user +selection), the color from block to specify a color numerically, or by , +which reports the color currently in use by the pen. The from color +block reports names or numbers associated with a color:

+ +

{width=ā€4.833333333333333inā€ +height=ā€0.4305555555555556inā€}Colors can be created from other colors:

+ +

The three blocks with pen in their names are improved versions of +primitive Pen blocks. In principle set pen, for example, could be +implemented using a (hypothetical) set pen to color composed with the +color from block, but in fact set pen benefits from knowing how the pen +color was set in its previous invocation, so itā€™s implemented separately +from color from. Details in Appendix A.

+ +

{width=ā€7.5inā€ +height=ā€0.25inā€}The recommended way to choose a color is from one of two +linear scales: the continuous color numbers and the discrete +crayons:

+ +

{width=ā€7.5inā€ height=ā€0.25inā€}

+ +

{width=ā€4.0inā€ +height=ā€0.20833333333333334inā€}Color numbers are based on fair hues, a +modification of the spectrum (rainbow) hue scale that devotes less space +to green and more to orange and yellow, as well as promoting brown to a +real color. Here is the normal hue scale, for reference:

+ +

{width=ā€4.0inā€ +height=ā€0.20833333333333334inā€}Here is the fair hue scale:

+ +

{width=ā€5.0inā€ +height=ā€0.20833333333333334inā€}Here is the color number scale:

+ +

(The picture is wider so that pure spectral colors line up with the fair +hue scale.)

+ +

{width=ā€5.0inā€ +height=ā€0.20833333333333334inā€}And here are the 100 crayons:

+ +

The color from block, for example, provides different pulldown menus +depending on which scale you choose:

+ +

{width=ā€2.4166666666666665inā€ +height=ā€0.34444444444444444inā€}{width=ā€7.070138888888889inā€ +height=ā€2.8673611111111112inā€}You can also type the crayon name: There +are many scales:

+ +

{width=ā€4.291666666666667inā€ +height=ā€1.9097222222222223inā€}

+ +

{width=ā€6.1506944444444445inā€ +height=ā€0.5347222222222222inā€} The white slot at the end of some of the +blocks has two purposes. It can be used to add a transparency to a color +(0=opaque, 100=transparent):

+ +

{width=ā€7.029861111111111inā€ +height=ā€0.4305555555555556inā€}or it can be expanded to enter three or +four numbers for a vector directly into the block, so these are +equivalent:

+ +

{width=ā€7.493055555555555inā€ +height=ā€0.4305555555555556inā€}But note that a transparency number in a +four-number RGBA vector is on the scale 255=opaque, 0=transparent, so +the following are not equivalent:

+ +

Set pen crayon to provides the equivalent of a box of 100 crayons. They +are divided into color groups, so the menu in the set pen crayon to +input slot has submenus. The colors are chosen so that starting +{width=ā€4.365277777777778inā€ +height=ā€0.5152777777777777inā€}from crayon 0, change pen crayon by 10 +rotates through an interesting, basic set of ten colors:

+ +

{width=ā€4.355555555555555inā€ +height=ā€0.28194444444444444inā€}Using change pen crayon by 5 instead +gives ten more colors, for a total of 20:

+ +

(Why didnā€™t we use the colors of the 100-crayon Crayolaā„¢ box? A few +reasons, one of which is that some Crayola colors arenā€™t representable +on RGB screens. Some year when you have nothing else to do, look up +ā€œcolor spaceā€ on Wikipedia. Also ā€œcrayon.ā€ Oh, itā€™s deliberate that +change pen crayon by 5 doesnā€™t include white, since thatā€™s the usual +stage background color. White is crayon 14.) Note that crayon 43 is +ā€œVariablesā€; all the standard block colors are included.

+ +

See Appendix A (page 139) for more information.

+ +

{width=ā€1.51inā€ +height=ā€0.9inā€}The crayon library has only the crayon features, +without the rest of the colors package.

+ +

The catch errors library has these blocks:

+ +

{width=ā€0.4305555555555556inā€ +height=ā€0.1527777777777778inā€}{width=ā€3.0416666666666665inā€ +height=ā€1.3958333333333333inā€}The safely try block allows you to handle +errors that happen when your program is run within the program, instead +of stopping the script with a red halo and an obscure error message. The +block runs the script in its first C-slot. If it finishes without an +error, nothing else happens. But if an error happens, the code in the +second C-slot is run. While that second script is running, the variable +contains the text of the error message that would have been displayed if +you werenā€™t catching the error. The error block is sort of the opposite: +it lets your program generate an error message, which will be +displayed with a red halo unless it is caught by safely try. Safely try +reporting is the reporter version of safely try.

+ +

The text costumes library has only two blocks:

+ +

{width=ā€0.5347222222222222inā€ +height=ā€0.20833333333333334inā€}{width=ā€1.92inā€ +height=ā€0.4507830271216098inā€}Costume from text reports a costume that +can be used with the switch to +{width=ā€3.2597222222222224inā€ +height=ā€0.18958333333333333inā€}costume block to make a button:

+ +

Costume with background reports a costume made from another costume by +coloring its background, taking a color input like the set pen color to +RGB(A) block and a number of turtle steps of padding around the original +costume. These two blocks work together to make even better buttons:

+ +

{width=ā€5.51inā€ height=ā€0.68inā€}

+ +

The text to speech library has these blocks:

+ +

{width=ā€2.275inā€ +height=ā€0.8inā€}This library interfaces with a capability in up-to-date +browsers, so it might not work for you. It works best if the accent +matches the text!

+ +

The parallelization library contains these blocks:

+ +

{width=ā€1.179861111111111inā€ +height=ā€1.2597222222222222inā€}The two do in parallel blocks take any +number of scripts as inputs. Those scripts will be run in parallel, like +ordinary independent scripts in the scripting area. The and wait version +waits until all of those scripts have finished before continuing the +script below the block.

+ +

{width=ā€1.3777777777777778inā€ +height=ā€1.4833333333333334inā€}The create variables library has these +blocks:

+ +

These blocks allow a program to perform the same operation as the

+ +

button, making global, sprite local, or script variables, but allowing +the program to compute the variable name(s). It can also set and find +the values of these variables, show and hide their stage watchers, +delete them, and find out if they already exist.

+ +

The getters and setters library has these blocks:

+ +

{width=ā€1.875inā€ +height=ā€1.05inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The purpose of this library is to allow +program access to the settings controlled by user interface elements, +such as the settings menu. The setting block reports a setting; the set +flag block sets yes-or-no options that have checkboxes in the user +interface, while the set value block controls settings with numeric or +text values, such as project name.

+ +

Certain settings are ordinarily remembered on a per-user basis, such as +the ā€œzoom blocksā€ value. But when these settings are changed by this +library, the change is in effect only while the project using the +library is loaded. No permanent changes are made. Note: this library has +not been converted for version 7.0, so youā€™ll have to enable Javascript +extensions to use it.

+ +

The bignums, rationals, complex #s library has these blocks:

+ +

{width=ā€1.875inā€ +height=ā€1.55inā€}The USE BIGNUMS block takes a Boolean input, to turn the +infinite precision feature on or off. When on, all of the arithmetic +operators are redefined to accept and report integers of any number of +digits (limited only by the memory of your computer) and, in fact, the +entire Scheme numeric tower, with exact rationals and with complex +numbers. The Scheme number block has a list of functions applicable to +Scheme numbers, including subtype predicates such as rational? and +infinite?, and selectors such as numerator and real-part.

+ +

{width=ā€4.836805555555555inā€ +height=ā€0.4166666666666667inā€}The ! block computes the factorial +function, useful to test whether bignums are turned on. Without bignums:

+ +

With bignums:

+ +

{width=ā€7.527083333333334inā€ +height=ā€0.36041666666666666inā€}The 375-digit value of 200! isnā€™t +readable on this page, but if you right-click on the block and choose +ā€œresult pic,ā€ you can open the resulting picture in a browser window and +scroll through it. (These values end with a bunch of zero digits. Thatā€™s +not roundoff error; the prime factors of 100! and 200! include many +copies of 2 and 5.) The block with no name is a way to enter things like +3/4 and 4+7i into numeric input slots by converting the slot to Any +type.

+ +

The strings, multi-line input library provides these blocks:

+ +

{width=ā€3.9375inā€ +height=ā€2.0416666666666665inā€}All of these could be written in Snap! +itself, but these are implemented using the corresponding JavaScript +library functions directly, so they run fast. They can be used, for +example, in scraping data from a web site. The command use +case-independent comparisons applies only to this library. The multiline +block accepts and reports a text input that can include newline +characters.

+ +

The animation library has these blocks:

+ +

{width=ā€4.0125inā€ +height=ā€2.33125inā€}Despite the name, this isnā€™t only about graphics; you +can animate the values of a variable, or anything else thatā€™s expressed +numerically.

+ +

{width=ā€0.9652777777777778inā€ +height=ā€0.19444444444444445inā€}The central idea of this library is an +easing function, a reporter whose domain and range are real numbers +between 0 and 1 inclusive. The function represents what fraction of the +ā€œdistanceā€ (in quotes because it might be any numeric value, such as +temperature in a simulation of weather) from here to there should be +covered in what fraction of the time. A linear easing function means +steady progression. A quadratic easing function means starting slowly +and accelerating. (Note that, since itā€™s a requirement that f(0)=0 and +f(1)=1, there is only one linear easing function, f(x)=x, and +similarly for other categories.) The block reports some of the common +easing functions.

+ +

{width=ā€4.631944444444445inā€ +height=ā€0.6319444444444444inā€}The two Motion blocks in this library +animate a sprite. Glide always animates the spriteā€™s motion. Animateā€™s +first pulldown menu input allows you to animate horizontal or vertical +motion, but will also animate the spriteā€™s direction or size. The +animate block in Control lets you animate any numeric quantity with any +easing function. The getter and setter inputs are best explained by +example:

+ +

{width=ā€3.4097222222222223inā€ +height=ā€0.2569444444444444inā€}is equivalent to

+ +

The other blocks in the library are helpers for these four.

+ +

The serial ports library contains these blocks:

+ +

{width=ā€1.7326388888888888inā€ +height=ā€1.0347222222222223inā€}It is used to allow hardware developers to +control devices such as robots that are

+ +

connected to your computer via a serial port.

+ +

The frequency distribution analysis library has these blocks:

+ +

{width=ā€4.027083333333334inā€ +height=ā€2.3958333333333335inā€}

+ +

This is a collection of tools for analyzing large data sets and plotting +histograms of how often some value is found in some column of the table +holding the data.

+ +

For more information go here:

+ +

http://tinyurl.com/jens-data

+ +

The audio comp library includes these blocks:

+ +

{width=ā€3.5416666666666665inā€ +height=ā€2.98125inā€}This library takes a sound, one that you record or +one from our collection of sounds, and manipulates it by systematically +changing the intensity of the samples in the sound and by changing the +sampling rate at which the sound is reproduced. Many of the blocks are +helpers for the plot sound block, used to plot the waveform of a sound. +The play sound (primitive) block plays a sound. __ Hz for reports a +sine wave as a list of samples.

+ +

The web services library has these blocks:

+ +

{width=ā€3.4097222222222223inā€ +height=ā€1.1041666666666667inā€}The first block is a generalization of the +primitive url block, allowing more control over the various options in +web requests: GET, POST, PUT, and DELETE, and fine control over the +content of the message sent to the server. Current location reports your +latitude and longitude. Listify takes some text in JSON format (see page +54) and converts it to a structured list. Value at key looks up a +key-value pair in a (listified) JSON dictionary. The key:value: block is +just a constructor for an abstract data type used with the other blocks

+ +

The database library contains these blocks:

+ +

{width=ā€2.263888888888889inā€ +height=ā€1.2222222222222223inā€}It is used to keep data that persist from +one Snap! session to the next, if you use the same browser and the +same login.

+ +

The world map library has these blocks:

+ +

{width=ā€2.442361111111111inā€ +height=ā€3.4027777777777777inā€}Using any of the command blocks puts a map +on the screen, in a layer in front of the stageā€™s background but behind +the pen trails layer (which is in turn behind all the sprites). The +first block asks your browser for your current physical location, for +which you may be asked to give permission. The next two blocks get and +set the mapā€™s zoom amount; the default zoom of 10 ļ¬ts from San Francisco +not quite down to Palo Alto on the screen. A zoom of 1 ļ¬ts almost the +entire world. A zoom of 3 fits the United States; a zoom of 5 ļ¬ts +Germany. The zoom can be changed in half steps, i.e., 5.5 is different +from 5, but 5.25 isnā€™t.

+ +

The next five blocks convert between stage coordinates (pixels) and +Earth coordinates (latitude and longitude). The change by x: y: block +shifts the map relative to the stage. The distance to block measures the +map distance (in meters) between two sprites. The three reporters with +current in their names find your actual location, again supposing that +geolocation is enabled on your device. Update redraws the map; as +costume reports the visible section of the map as a costume. Set style +allows things like satellite pictures.

+ +

The APL primitives library contains these blocks:

+ +

{width=ā€5.733333333333333inā€ +height=ā€1.1133333333333333inā€}

+ +

{width=ā€6.453333333333333inā€ +height=ā€2.04inā€}

+ +

For more information about APL, see Appendix B (page 148).

+ +

The {width=ā€1.2inā€ +height=ā€0.4895833333333333inā€}list comprehension library has one +block, zip. Its first input is a function of two inputs. The two +Any-type inputs are deep lists (lists of lists ofā€¦) interpreted as +trees, and the function is called with every possible combination of a +leaf node of the first tree and a leaf node of the second tree. But +instead of taking atoms (non-lists) as the leaves, zip allows the leaves +of each tree to be vectors (one-dimensional lists), matrices +(two-dimensional lists), etc. The Number-type inputs specify the leaf +dimension for each tree, so the function input might be called with a +vector from the first tree and an atom from the second tree.

+ +

{width=ā€0.89inā€ +height=ā€1.51inā€}The bitwise library provides bitwise logic +functions; each bit of the reported value is the result of applying the +corresponding Boolean function to the corresponding bits of the +input(s). The Boolean functions are not for Ā¬, and for āˆ§, or for āˆØ, and +xor (exclusive or) for āŠ». The remaining functions shift their first +input left or right by the number of bits given by the second input. +<< is left shift, >> is arithmetic right shift (shifting in one bits +from the left), and >>> is logical right shift (shifting in zero bits +from the left). If you donā€™t already know what these mean, find a +tutorial online.

+ +

{width=ā€6.528977471566054inā€ +height=ā€1.6097222222222223inā€}

+ +

The MQTT library supports the Message Queuing Telemetry Transport +protocol, for connecting with IOT devices. See https://mqtt.org/ for +more information.

+ +

{width=ā€4.986805555555556inā€ +height=ā€2.8895833333333334inā€}The Signada library allows you to +control a microBit or similar device that works with the Signada +MicroBlocks project.

+ +

{width=ā€3.39inā€ height=ā€1.9inā€}

+ +

The menus library provides the ability to display hierarchical menus +on the stage, using the ask blockā€™s ability to take lists as inputs. See +page 24.

+ +

The SciSnap! library and the TuneScope library are too big to +discuss here and are documented separately at +http://emu-online.de/ProgrammingWithSciSnap.pdf and +https://maketolearn.org/creating-art-animations-and-music/ +respectively.

+ +

Saving and Loading Projects and Media

+ +

After youā€™ve created a project, youā€™ll want to save it, so that you can +have access to it the next time you use Snap!. There are two ways to +do that. You can save a project on your own computer, or you can save it +at the Snap! web site. The advantage of saving on the net is that you +have access to your project even if you are using a different computer, +or a mobile device such as a tablet or smartphone. The advantage of +saving on your computer is that you have access to the saved project +while on an airplane or otherwise not on the net. Also, cloud projects +are limited in size, but you can have all the costumes and sounds you +like if you save locally. This is why we have multiple ways to save.

+ +

{width=ā€3.548611111111111inā€ +height=ā€2.576388888888889inā€}In either case, if you choose ā€œSave asā€¦ā€ +from the File menu. Youā€™ll see something like this:

+ +

(If you are not logged in to your Snap! cloud account, Computer will +be the only usable option.) The text box at the bottom right of the Save +dialog allows you to enter project notes that are saved with the +project.

+ +

Local Storage

+ +

Click on Computer and Snap!ā€™s Save Project dialog window will be +replaced by your operating systemā€™s standard save window. If your +project has a name, that name will be the default filename if you donā€™t +give a different name. Another, equivalent way to save to disk is to +choose ā€œExport projectā€ from the File menu.

+ +

{width=ā€1.2340277777777777inā€ height=ā€2.329861111111111inā€}Creating a Cloud Account

+ +

{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The other possibility is to save your +project ā€œin the cloud,ā€ at the Snap! web site. In order to do this, +you need an account with us. Click on the Cloud button ( ) in the Tool +Bar. Choose the ā€œSignupā€¦ā€ option. This will show you a window that +looks like the picture at the right.

+ +

You must choose a user name that will identify you on the web site, such +as Jens or bh. If youā€™re a Scratch user, you can use your Scratch name +for Snap! too. If youā€™re a kid, donā€™t pick a user name that includes +your family name, but first names or initials are okay. Donā€™t pick +something youā€™d be embarrassed to have other users (or your parents) +see! If the name you want is already taken, youā€™ll have to choose +another one. You must also supply a password.

+ +

We ask for your month and year of birth; we use this information only to +decide whether to ask for your own email address or your parentā€™s email +address. (If youā€™re a kid, you shouldnā€™t sign up for anything on the +net, not even Snap!, without your parentā€™s knowledge.) We do not store +your birthdate information on our server; it is used on your own +computer only during this initial signup. We do not ask for your exact +birthdate, even for this one-time purpose, because thatā€™s an important +piece of personally identifiable information.

+ +

When you click OK, an email will be sent to the email address you gave, +asking you to verify (by clicking a link) that itā€™s really your email +address. We keep your email address on file so that, if you forget your +password, we can send you a password-reset link. We will also email you +if your account is suspended for violation of the Terms of Service. We +do not use your address for any other purpose. You will never receive +marketing emails of any kind through this site, neither from us nor from +third parties. If, nevertheless, you are worried about providing this +information, do a web search for ā€œtemporary email.ā€

+ +

Finally, you must read and agree to the Terms of Service. A quick +summary: Donā€™t interfere with anyone elseā€™s use of the web site, and +donā€™t put copyrighted media or personally identifiable information in +projects that you share with other users. And weā€™re not responsible if +something goes wrong. (Not that we expect anything to go wrong; since +Snap! runs in JavaScript in your browser, it is strongly isolated from +the rest of your computer. But the lawyers make us say this.)

+ +

Saving to the Cloud

+ +

Once youā€™ve created your account, you can log into it using the +ā€œLoginā€¦ā€ option from the Cloud menu:

+ +

{width=ā€1.6875inā€ +height=ā€2.0277777777777777inā€}Use the user name and password that you +set up earlier. If you check the ā€œStay signed inā€ box, then you will be +logged in automatically the next time you run Snap! from the same +browser on the same computer. Check the box if youā€™re using your own +computer and you donā€™t share it with siblings. Donā€™t check the box if +youā€™re using a public computer at the library, at school, etc.

+ +

Once logged in, you can choose the ā€œCloudā€ option in the ā€œSave Projectā€ +dialog shown on page 37. You enter a project name, and optionally +project notes; your project will be saved online and can be loaded from +anywhere with net access. The project notes will be visible to other +users if you publish your project.

+ +

Loading Saved Projects

+ +

Once youā€™ve saved a project, you want to be able to load it back into +Snap!. There are two ways to do this:

+ +

1. If you saved the project in your online Snap! account, choose the +ā€œOpenā€¦ā€ option from the File menu. Choose the ā€œCloudā€ button, then +select your project from the list in the big text box and click OK, or +choose the ā€œComputerā€ button to open an operating system open dialog. (A +third button, ā€œExamples,ā€ lets you choose from example projects that we +provide. You can see what each of these projects is about by clicking on +it and reading its project notes.)

+ +

2. If you saved the project as an XML file on your computer, choose +ā€œImportā€¦ā€ from the File menu. This will give you an ordinary browser +file-open window, in which you can navigate to the file as you would in +other software. Alternatively, find the XML file on your desktop, and +just drag it onto the Snap! window.

+ +

The second technique above also allows you to import media (costumes and +sounds) into a project. Just choose ā€œImportā€¦ā€ and then select a +picture or sound file instead of an XML file.

+ +

Snap! can also import projects created in BYOB 3.0 or 3.1, or (with +some effort; see our web site) in Scratch 1.4, 2.0 or 3.0. Almost all +such projects work correctly in Snap!, apart from a small number of +incompatible blocks.

+ +

If you saved projects in an earlier version of Snap! using the +ā€œBrowserā€ option, then a Browser button will be shown in the Open dialog +to allow you to retrieve those projects. But you can save them only with +the Computer and Cloud options.

+ +

If you lose your project, do this first!

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}If you are still in Snap! and +realize that youā€™ve loaded another project without saving the one you +were working on: Donā€™t edit the new project. From the File menu +choose the Restore unsaved project option.

+ +

Restore unsaved project will also work if you log out of Snap! and +later log back in, as long as you donā€™t edit another project meanwhile. +Snap! remembers only the most recent project that youā€™ve edited (not +just opened, but actually changed in the project editor).

+ +

If your project on the cloud is missing, empty, or otherwise broken and +isnā€™t the one you edited most recently, or if Restore unsaved project +fails: Donā€™t edit the broken project. In the Openā€¦ box, enter +your project name, then push the Recover button. Do this right away, +because we save only the version before the most recent, and the latest +before today. So donā€™t keep saving bad versions; Recover right away. The +Recover feature works only on a project version that you actually saved, +so Restore unsaved project is your first choice if you switch away from +a project without saving it.

+ +

To help you remember to save your projects, when youā€™ve edited the +project and havenā€™t yet saved it, Snap! displays a pencil icon to the +left of the project name on the toolbar at the top of the window:

+ +

{width=ā€6.29671697287839inā€ +height=ā€0.5138888888888888inā€}

+ +

Private and Public Projects

+ +

By default, a project you save in the cloud is private; only you can see +it. There are two ways to make a project available to others. If you +share a project, you can give your friends a project URL (in your +browserā€™s URL bar after you open the project) they can use to read it. +If you publish a project, it will appear on the Snap! web site, and +the whole world can see it. In any case, nobody other than you can ever +overwrite your project; if others ask to save it, they get their own +copy in their own account.

+ +

Building a Block

+ +

The first version of Snap! was called BYOB, for ā€œBuild Your Own +Blocks.ā€ This was the first and is still the most important capability +we added to Scratch. (The name was changed because a few teachers have +no sense of humor. ā˜¹ You pick your battles.) Scratch 2.0 and later also +has a partial custom block capability.

+ +

Simple Blocks

+ +

{width=ā€7.5inā€ +height=ā€2.7152777777777777inā€}In every palette, at or near the bottom, +is a button labeled ā€œMake a block.ā€ Also, floating near the top of the +palette is a plus sign. Also, the menu you get by right-clicking on the +background of the scripting area has a ā€œmake a blockā€ option.

+ +

{width=ā€2.2708333333333335inā€ +height=ā€2.3472222222222223inā€}Clicking any of these will display a +dialog window in which you choose the blockā€™s name, shape, and +palette/color. You also decide whether the block will be available to +all sprites, or only to the current sprite and its children.

+ +

In this dialog box, you can choose the block's palette, shape, and +name. With one exception, there is one color per palette, e.g., all +Motion blocks are blue. But the Variables palette includes the orange +variable-related blocks and the red list-related blocks. Both colors are +available, along with an ā€œOtherā€ option that makes grey blocks in the +Variables palette for blocks that donā€™t fit any category.

+ +

There are three block shapes, following a convention that should be +familiar to Scratch users: The jigsaw-puzzle-piece shaped blocks are +Commands, and donā€™t report a value. The oval blocks are Reporters, and +the hexagonal blocks are Predicates, which is the technical term for +reporters that report Boolean (true or false) values.

+ +

Suppose you want to make a block named ā€œsquareā€ that draws a square. You +would choose Motion, Command, and type ā€œsquareā€ into the name field. +When you click OK, you enter the Block Editor. This works just like +making a script in the spriteā€™s scripting area, except that the ā€œhatā€ +block at the top, instead of saying something like ā€œwhen I am clicked,ā€ +has a picture of the block youā€™re building. This hat block is called the +prototype of your custom block.3 You drag blocks under the hat to +program your custom block, then click OK:

+ +

{width=ā€4.210937226596675inā€ +height=ā€1.3364041994750657inā€}

+ +

{width=ā€4.615555555555556inā€ +height=ā€3.647777777777778inā€}

+ +

Your block appears at the bottom of the Motion palette. Hereā€™s the block +and the result of using it:

+ +

{width=ā€4.242361111111111inā€ +height=ā€1.4166666666666667inā€}

+ +

Custom Blocks with Inputs

+ +

But suppose you want to be able to draw squares of different sizes. +Control-click or right-click on the block, choose ā€œedit,ā€ and the Block +Editor will open. Notice the plus signs before and after the word square +in the prototype block. If you hover the mouse over one, it lights up:

+ +

{width=ā€3.4444444444444446inā€ +height=ā€2.7222222222222223inā€}

+ +

{width=ā€2.5833333333333335inā€ +height=ā€1.6041666666666667inā€}Click on the plus on the right. You will +then see the ā€œinput nameā€ dialog:

+ +

Type in the name ā€œsizeā€ and click OK. There are other options in this +dialog; you can choose ā€œtitle textā€ if you want to add words to the +block name, so it can have text after an input slot, like the ā€œmove ( ) +stepsā€ block. Or you can select a more extensive dialog with a lot of +options about your input name. But weā€™ll leave that for later. When you +click OK, the new input appears in the block prototype:

+ +

{width=ā€1.4791666666666667inā€ +height=ā€1.4895833333333333inā€}You can now drag the orange variable down +into the script, then click okay:

+ +

{width=ā€1.474724409448819inā€ +height=ā€1.495495406824147inā€}

+ +

{width=ā€0.6979166666666666inā€ +height=ā€0.25inā€}Your block now appears in the Motion palette with an +input box: You can draw any size square by entering the length of its +side in the box and running the block as usual, by clicking it or by +putting it in a script.

+ +

Editing Block Properties

+ +

{width=ā€0.9993055555555556inā€ +height=ā€0.7604166666666666inā€}What if you change your mind about a +blockā€™s color (palette) or shape (command, reporter, predicate)? If you +click in the hat block at the top that holds the prototype, but not in +the prototype itself, youā€™ll see a window in which you can change the +color, and sometimes the shape, namely, if the block is not used in +any script, whether in a scripting area or in another custom block. +(This includes a one-block script consisting of a copy of the new block +pulled out of the palette into the scripting area, seeing which made you +realize itā€™s the wrong category. Just delete that copy (drag it back to +the palette) and then change the category.)

+ +

If you right-click/control-click the hat block, you get this menu:

+ +

Script pic exports a picture of the script. (Many of the illustrations +in this manual were made that way.) Translations opens a window in which +you can specify how your block should be translated if the user chooses +a language other than the one in which you are programming. Block +variables lets you create a variant of script variables for this block: +A script variable is created when a block is called, and it disappears +when that call finishes. What if you want a variable thatā€™s local to +this block, as a script variable is, but doesnā€™t disappear between +invocations? Thatā€™s a block variable. If the definition of a block +includes a block variable, then every time that (custom) block is +dragged from the palette into a script, the block variable is created. +Every time that copy of the block is called, it uses the same block +variable, which preserves its value between calls. Other copies of the +block have their own block variables. The in palette checkbox determines +whether or not this block will be visible in the palette. Itā€™s normally +checked, but you may want to hide custom blocks if youā€™re a curriculum +writer creating a Parsons problem. To unhide blocks, choose ā€œHide +blocksā€ from the File menu and uncheck the checkboxes. Edit does the +same thing as regular clicking, as described earlier.

+ +

Recursion

+ +

{width=ā€2.9652777777777777inā€ +height=ā€2.3631944444444444inā€}{width=ā€1.9583333333333333inā€ +height=ā€2.3541666666666665inā€}{width=ā€1.4236111111111112inā€ +height=ā€0.9118055555555555inā€}Since the new custom block appears in its +palette as soon as you start editing it, you can write recursive +blocks (blocks that call themselves) by dragging the block into its own +definition:

+ +

(If you added inputs to the block since opening the editor, click Apply +before finding the block in the palette, or drag the block from the top +of the block editor rather than from the palette.)

+ +

If recursion is new to you, here are a few brief hints: Itā€™s crucial +that the recursion have a base case, that is, some small(est) case +that the block can handle without using recursion. In this example, itā€™s +the case depth=0, for which the block does nothing at all, because of +the enclosing if. Without a base case, the recursion would run forever, +calling itself over and over.

+ +

Donā€™t try to trace the exact sequence of steps that the computer follows +in a recursive program. Instead, imagine that inside the computer there +are many small people, and if Theresa is drawing a tree of size 100, +depth 6, she hires Tom to make a tree of size 70, depth 5, and later +hires Theo to make another tree of size 70, depthĀ 5. Tom in turn hires +Tammy and Tallulah, and so on. Each little person has his or her own +local variables size and depth, each with different values.

+ +

{width=ā€4.8380686789151355inā€ +height=ā€1.5833333333333333inā€}You can also write recursive reporters, +like this block to compute the factorial function:

+ +

Note the use of the report block. When a reporter block uses this block, +the reporter finishes its work and reports the value given; any further +blocks in the script are not evaluated. Thus, the if else block in the +script above could have been just an if, with the second report block +below it instead of inside it, and the result would be the same, because +when the ļ¬rst report is seen in the base case, that finishes the block +invocation, and the second report is ignored. There is also a stop this +block block that has a similar purpose, ending the block invocation +early, for command blocks. (By contrast, the stop this script block +stops not only the current block invocation, but also the entire +toplevel script that called it.)

+ +

{width=ā€4.291666666666667inā€ +height=ā€0.8645833333333334inā€}Hereā€™s a slightly more compact way to +write the factorial function:

+ +

For more on recursion, see Thinking Recursively by Eric Roberts. (The +original edition is ISBN 978ā€‘0471816522; a more recent Thinking +Recursively in Java is ISBN 978-0471701460.)

+ +

Block Libraries

+ +

When you save a project (see Chapter II above), any custom blocks youā€™ve +made are saved with it. But sometimes youā€™d like to save a collection of +blocks that you expect to be useful in more than one project. Perhaps +your blocks implement a particular data structure (a stack, or a +dictionary, etc.), or theyā€™re the framework for building a multilevel +game. Such a collection of blocks is called a block library.

+ +

*
+*To create a block library, choose ā€œExport blocksā€¦ā€ from the File +menu. You then see a window like this:

+ +

{width=ā€2.0215277777777776inā€ +height=ā€2.7222222222222223inā€}The window shows all of your global custom +blocks. You can uncheck some of the checkboxes to select exactly which +blocks you want to include in your library. (You can right-click or +control-click on the export window for a menu that lets you check or +uncheck all the boxes at once.) Then press OK. An XML file containing +the blocks will appear in your Downloads location.

+ +

To import a block library, use the ā€œImportā€¦ā€ command in the File menu, +or just drag the XML file into the Snap! window.

+ +

Several block libraries are included with Snap!; for details about +them, see page 25.

+ +

Custom blocks and Visible Stepping

+ +

Visible stepping normally treats a call to a custom block as a single +step. If you want to see stepping inside a custom block you must take +these steps in order:

+ +
    +
  1. +

    {width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Turn on Visible Stepping.

    +
  2. +
  3. +

    Select ā€œEditā€ in the context menu(s) of the block(s) you want to +examine.

    +
  4. +
  5. +

    Then start the program.

    +
  6. +
+ +

The Block Editor windows you open in step 2 do not have full editing +capability. You can tell because there is only one ā€œOKā€ button at the +bottom, not the usual three buttons. Use the button to close these +windows when done stepping.

+ +

First class lists

+ +

A data type is ļ¬rst class in a programming language if data of that +type can be

+ + + +

In Scratch, numbers and text strings are ļ¬rst class. You can put a +number in a variable, use one as the input to a block, call a reporter +that reports a number, or put a number into a list.

+ +

But Scratchā€™s lists are not ļ¬rst class. You create one using the ā€œMake a +listā€ button, which requires that you give the list a name. You canā€™t +put the list into a variable, into an input slot of a block, or into a +list itemā€”you canā€™t have lists of lists. None of the Scratch reporters +reports a list value. (You can use a reduction of the list into a text +string as input to other blocks, but this loses the list structure; the +input is just a text string, not a data aggregate.)

+ +

A fundamental design principle in Snap! is that [all data should be +ļ¬rst class]{.underline}. If itā€™s in the language, then we should be +able to use it fully and freely. We believe that this principle avoids +the need for many special-case tools, which can instead be written by +Snap! users themselves.

+ +

{width=ā€2.839583333333333inā€ +height=ā€0.41597222222222224inā€}Note that itā€™s a data type thatā€™s ļ¬rst +class, not an individual value. Donā€™t think, for example, that some +lists are ļ¬rst class, while others arenā€™t. In Snap!, lists are ļ¬rst +class, period.

+ +

The list Block

+ +

At the heart of providing first class lists is the ability to make an +ā€œanonymousā€ listā€”to make a list without simultaneously giving it a +name. The list reporter block does that.

+ +

{width=ā€4.2inā€ +height=ā€1.5694444444444444inā€}At the right end of the block are two +left-and-right arrowheads. Clicking on these changes the number of +inputs to list, i.e., the number of elements in the list you are +building. Shift-clicking changes by three at a time.

+ +

{width=ā€1.5034722222222223inā€ +height=ā€1.8125inā€}{width=ā€2.24375inā€ +height=ā€0.3215277777777778inā€}You can use this block as input to many +other blocks:

+ +

{width=ā€3.09375inā€ +height=ā€0.7708333333333334inā€}{width=ā€1.8229166666666667inā€ +height=ā€0.2916666666666667inā€}Snap! does not have a ā€œMake a listā€ +button like the one in Scratch. If you want a global ā€œnamed list,ā€ make +a global variable and use the set block to put a list into the variable.

+ +

Lists of Lists

+ +

{width=ā€5.888888888888889inā€ +height=ā€1.0486111111111112inā€}Lists can be inserted as elements in +larger lists. We can easily create ad hoc structures as needed:

+ +

Notice that this list is presented in a different format from the ā€œShe +Loves Youā€ list above. A two-dimensional list is called a table and is +by default shown in table view. Weā€™ll have more to say about this +later.

+ +

{width=ā€7.343055555555556inā€ +height=ā€2.78125inā€}We can also build any classic computer science data +structure out of lists of lists, by defining constructors (blocks to +make an instance of the structure), selectors (blocks to pull out a +piece of the structure), and mutators (blocks to change the contents +of the structure) as needed. Here we create binary trees with selectors +that check for input of the correct data type; only one selector is +shown but the ones for left and right children are analogous.

+ +

Functional and Imperative List Programming

+ +

{width=ā€2.1041666666666665inā€ +height=ā€1.09375inā€} There are two ways to create a list inside a +program. Scratch users will be familiar with the imperative +programming style, which is based on a set of command blocks that modify +a list:

+ +

As an example, here are two blocks that take a list of numbers as input, +and report a new list containing only the even numbers from the original +list:4

+ +

{width=ā€5.892361111111111inā€ +height=ā€2.28125inā€}

+ +

or

+ +

In this script, we first create a temporary variable, then put an empty +list in it, then go through the items of the input list using the add +ā€¦ to (result) block to modify the result list, adding one item at +a time, and finally report the result.

+ +

{width=ā€1.5625inā€ +height=ā€0.8104166666666667inā€}Functional programming is a different +approach that is becoming important in ā€œreal worldā€ programming because +of parallelism, i.e., the fact that different processors can be +manipulating the same data at the same time. This makes the use of +mutation (changing the value associated with a variable, or the items of +a list) problematic because with parallelism itā€™s impossible to know the +exact sequence of events, so the result of mutation may not be what the +programmer expected. Even without parallelism, though, functional +programming is sometimes a simpler and more effective technique, +especially when dealing with recursively defined data structures. It +uses reporter blocks, not command blocks, to build up a list value:

+ +

In a functional program, we often use recursion to construct a list, one +item at a time. The in front of block makes a list that has one item +added to the front of an existing list, without changing the value of +the original list. A nonempty list is processed by dividing it into its +first item (item 1 of) and all the rest of the items (all but first of), +which are handled through a recursive call:

+ +

{width=ā€4.75inā€ +height=ā€2.240972222222222inā€}Snap! uses two different internal +representations of lists, one (dynamic array) for imperative programming +and the other (linked list) for functional programming. Each +representation makes the corresponding built-in list blocks (commands or +reporters, respectively) most efficient. Itā€™s possible to mix styles in +the same program, but if the same list is used both ways, the program +will run more slowly because it converts from one representation to the +other repeatedly. (The item ( ) of [ ] block doesnā€™t change the +representation.) You donā€™t have to know the details of the internal +representations, but itā€™s worthwhile to use each list in a consistent +way.

+ +

{width=ā€5.864583333333333inā€ height=ā€1.0715277777777779inā€}Higher Order List Operations and Rings

+ +

Thereā€™s an even easier way to select the even numbers from a list:

+ +

{width=ā€2.375inā€ +height=ā€0.2777777777777778inā€}The keep block takes a Predicate +expression as its first input, and a list as its second input. It +reports a list containing those elements of the input list for which the +predicate returns true. Notice two things about the predicate input: +First, it has a grey ring around it. Second, the mod block has an empty +input. Keep puts each item of its input list, one at a time, into that +empty input before evaluating the predicate. (The empty input is +supposed to remind you of the ā€œboxā€ notation for variables in elementary +school: ā˜+3=7.) The grey ring is part of the keep block as it appears in +the palette:

+ +

{width=ā€4.1402777777777775inā€ +height=ā€0.6354166666666666inā€}What the ring means is that this input is +a block (a predicate block, in this case, because the interior of the +ring is a hexagon), rather than the value reported by that block. Hereā€™s +the difference:

+ +

Evaluating the = block without a ring reports true or false; evaluating +the block with a ring reports the block itself. This allows keep to +evaluate the = predicate repeatedly, once for each list item. A block +that takes another block as input is called a higher order block (or +higher order procedure, or higher order function).

+ +

{width=ā€2.39inā€ +height=ā€0.22inā€}{width=ā€1.6944444444444444inā€ +height=ā€0.9930555555555556inā€} Snap! provides four higher order +function blocks for operating on lists:

+ +

{width=ā€7.5inā€ +height=ā€1.7138888888888888inā€}Youā€™ve already seen keep. Find first is +similar, but it reports just the first item that satisfies the +predicate, not a list of all the matching items. Itā€™s equivalent to but +faster because it

+ +

stops looking as soon as it finds a match. If there are no matching +items, it returns an empty string.

+ +

{width=ā€7.589583333333334inā€ +height=ā€1.0791666666666666inā€}

+ +

{width=ā€7.486111111111111inā€ +height=ā€1.0020833333333334inā€}These examples use small lists, to fit the +page, but the higher order blocks work for any size list.

+ +

An empty gray ring represents the identity function, which just +reports its input. Leaving the ring in map empty is the most concise way +to make a shallow copy of a list (that is, in the case of a list of +lists, the result is a new toplevel list whose items are the same +(uncopied) lists that are items of the toplevel input list). To make a +deep copy of a list (that is, one in which all the sublists, sublists of +sublists, etc. are copied), use the list as input to the Macintosh
+HD:Users:bh:Desktop:id.png{width=ā€0.7430555555555556inā€ +height=ā€0.19444444444444445inā€} block (one of the variants of the sqrt +of block). This works because id of is a hyperblock (page 55).

+ +

{width=ā€5.5800503062117235inā€ +height=ā€0.4623108048993876inā€}The third higher order block, combine, +computes a single result from all the items of a list, using a +two-input reporter as its second input. In practice, there are only a +few blocks youā€™ll ever use with combine:

+ +

These blocks take the sum of the list items, take their product, string +them into one word, combine them into a sentence (with spaces between +items), see if all items of a list of Booleans are true, see if any of +the items is true, find the smallest, or find the largest.

+ +

{width=ā€6.279166666666667inā€ +height=ā€0.37569444444444444inā€}{width=ā€3.8680555555555554inā€ +height=ā€0.3451388888888889inā€}Why + but not āˆ’? It only makes sense to +combine list items using an associative function: one that doesnā€™t +care in what order the items are combined (left to right or right to +left). (2+3)+4 = 2+(3+4), but (2āˆ’3)āˆ’4 ā‰  2āˆ’(3āˆ’4).

+ +

{width=ā€5.808333333333334inā€ +height=ā€1.1909722222222223inā€}The functions map, keep, and find first +have an advanced mode with rarely-used features: If their function input +is given explicit input names (by clicking the arrowhead at the right +end of the gray ring; see page 69), then it will be called for each list +item with three inputs: the itemā€™s value (as usual), the itemā€™s +position in the input list (its index), and the entire input list. No +more than three input names can be used in this contex

+ +

{#section-2 .ListParagraph}

+ +

Table View vs. List View

+ +

{width=ā€3.0993055555555555inā€ +height=ā€2.513888888888889inā€}We mentioned earlier that there are two +ways of representing lists visually. For one-dimensional lists (lists +whose items are not themselves lists) the visual differences are small:

+ +

For one-dimensional lists, itā€™s not really the appearance thatā€™s +important. What matters is that the list view allows very versatile +direct manipulation of the list through the picture: you can edit the +individual items, you can delete items by clicking the tiny buttons next +to each item, and you can add new items at the end by clicking the tiny +plus sign in the lower left corner. (You can just barely see that the +item deletion buttons have minus signs in them.) Even if you have +several watchers for the same list, all of them will be updated when you +change anything. On the other hand, this versatility comes at an +efficiency cost; a list view watcher for a long list would be way too +slow. As a partial workaround, the list view can only contain 100 items +at a time; the downward-pointing arrowhead opens a menu in which you can +choose which 100 to display.

+ +

{width=ā€1.2555555555555555inā€ +height=ā€0.9125inā€}

+ +

By contrast, because it doesnā€™t allow direct editing, the table view +watcher can hold hundreds of thousands of items and still scroll through +them efficiently. The table view has flatter graphics for the items to +remind you that theyā€™re not clickable to edit the values.

+ +

Right-clicking on a list watcher (in either form) gives you the option +to switch to the other form. The right-click menu also offers an open in +dialogā€¦ option that opens an offstage table view watcher, because +the watchers can take up a lot of stage space that may make it hard to +see what your program is actually doing. Once the offstage dialog box is +open, you can close the stage watcher. Thereā€™s an OK button on the +offstage dialog to close it if you want. Or you can right-click it to +make another offstage watcher, which is useful if you want to watch +two parts of the list at once by having each watcher scrolled to a +different place.

+ +

{width=ā€5.888888888888889inā€ +height=ā€1.0486111111111112inā€}Table view is the default if the list has +more than 100 items, or if any of the first ten items of the list are +lists, in which case it makes a very different-looking two-dimensional +picture:

+ +

In this format, the column of red items has been replaced by a +spreadsheet-looking display. For short, wide lists, this display makes +the content of the list very clear. A vertical display, with much of the +space taken up by the ā€œmachineryā€ at the bottom of each sublist, would +make it hard to show all the text at once. (The pedagogic cost is that +the structure is no longer explicit; we canā€™t tell just by looking that +this is a list of row-lists, rather than a list of column-lists or a +primitive two-dimensional array type. But you can choose list view to +see the structure.)

+ +

Beyond such simple cases, in which every item of the main list is a list +of the same length, itā€™s important to keep in mind that the design of +table view has to satisfy two goals, not always in agreement: (1) a +visually compelling display of two-dimensional arrays, and (2) highly +efficient display generation, so that Snap! can handle very large +lists, since ā€œbig dataā€ is an important topic of study. To meet the +first goal perfectly in the case of ā€œragged rightā€ arrays in which +sublists can have different lengths, Snap! would scan the entire list +to find the maximum width before displaying anything, but that would +violate the second goal.

+ +

Snap! uses the simplest possible compromise between the two goals: It +examines only the first ten items of the list to decide on the format. +If none of those are lists, or theyā€™re all lists of one item, and the +overall length is no more than 100, list view is used. If the any of +first ten items is a list, then table view is used, and the number of +columns in the table is equal to the largest number of items among the +first ten items (sublists) of the main list.

+ +

Table views open with standard values for the width and height of a +cell, regardless of the actual data. You can change these values by +dragging the column letters or row numbers. Each column has its own +width, but changing the height of a row changes the height for all rows. +(This distinction is based not on the semantics of rows vs. columns, but +on the fact that a constant row height makes scrolling through a large +list more efficient.) Shift-dragging a column label will change the +width of that column.

+ +

If you tried out the adjustments in the previous paragraph, you may have +noticed that a column letter turns into a number when you hover over it. +Labeling rows and columns differently makes cell references such as +ā€œcell 4Bā€ unambiguous; you donā€™t have to have a convention about whether +to say the row first or the column first. (ā€œCell B4ā€ is the same as +ā€œcell 4B.ā€) On the other hand, to extract a value from column B in your +program, you have to say item 2 of, not item B of. So itā€™s useful to be +able to find out a column number by hovering over its letter.

+ +

{width=ā€3.817361111111111inā€ +height=ā€0.8111111111111111inā€}Any value that can appear in a program can +be displayed in a table cell:

+ +

{width=ā€4.336805555555555inā€ +height=ā€2.104861111111111inā€}This display shows that the standard cell +dimensions may not be enough for large value images. By expanding the +entire speech balloon and then the second column and all the rows, we +can make the result fit:

+ +

{width=ā€3.3409722222222222inā€ +height=ā€0.5770833333333333inā€}But we make an exception for cases in +which the value in a cell is a list (so that the entire table is +three-dimensional). Because lists are visually very big, we donā€™t try to +fit the entire value in a cell:

+ +

Even if you expand the size of the cells, Snap! will not display +sublists of sublists in table view. There are two ways to see these +inner sublists: You can switch to list view, or you can double-click on +a list icon in the table to open a dialog box showing just that +sub-sub-list in table view.

+ +

{width=ā€3.3541666666666665inā€ +height=ā€0.6944444444444444inā€}One last detail: If the first item of a +list is a list (so table view is used), but a later item isnā€™t a list, +that later item will be displayed on a red background, like an item of a +single-column list:

+ +

So, in particular, if only the first item is a list, the display will +look almost like a one-column display.

+ +

Comma-Separated Values

+ +

Spreadsheet and database programs generally offer the option to export +their data as CSV (comma-separated values lists. You can import these +files into Snap! and turn them into tables (lists of lists), and you +can export tables in CSV format. Snap! recognizes a CSV file by the +extension .csv in its filename.

+ +

A CSV file has one line per table row, with the fields separated by +commas within a row:

+ +

{width=ā€5.0inā€ +height=ā€2.6743055555555557inā€}John,Lennon,rhythm guitar

+ +

Paul,McCartney,bass guitar

+ +

George,Harrison,lead guitar

+ +

Ringo,Starr,drums

+ +

Hereā€™s what the corresponding table looks like:

+ +

Hereā€™s how to read a spreadsheet into Snap!:

+ +

{width=ā€1.2083333333333333inā€ +height=ā€0.2708333333333333inā€}1. Make a variable with a watcher on +stage:

+ +

2. Right-click on the watcher and choose the ā€œimportā€ option. (If the +variableā€™s value is already a list, be sure to click on the outside +border of the watcher; there is a different menu if you click on the +list itself.) Select the file with your csv data.

+ +

3. There is no 3; thatā€™s it! Snap! will notice that the name of the +file youā€™re importing is something.csv and will turn the text into a +list of lists automatically.

+ +

Or, even easier, just drag and drop the file from your desktop onto the +Snap! window, and Snap! will automatically create a variable named +after the file and import the data into it.

+ +

If you actually want to import the raw CSV data into a variable, either +change the file extension to .txt before loading it, or choose ā€œraw +dataā€ instead of ā€œimportā€ in the watcher menu.

+ +

If you want to export a list, put a variable watcher containing the list +on the stage, right-click its border, and choose ā€œExport.ā€ (Donā€™t +right-click an item instead of the border; that gives a different menu.)

+ +

Multi-dimensional lists and JSON

+ +

CSV format is easy to read, but works only for one- or two-dimensional +lists. If you have a list of lists of lists, Snap! will instead export +your list as a JSON (JavaScript Object Notation) file. I modified my +list:

+ +

{width=ā€6.333333333333333inā€ +height=ā€0.4479166666666667inā€}and then exported again, getting this +file:

+ +

[["John","Lennon","rhythm +guitar"],[["James","Paul"],"McCartney","bass +guitar"],["George","Harrison","lead +guitar"],["Ringo","Starr","drums"]]

+ +

You can also import lists, including tables, from a .json file. (And you +can import plain text from a .txt file.) Drag and drop works for these +formats also.

+ +

Hyperblocks

+ +

A scalar is anything other than a list. The name comes from +mathematics, where it means a magnitude without direction, as opposed to +a vector, which points toward somewhere. A scalar function is one whose +domain and range are scalars, so all the arithmetic operations are +scalar functions, but so are the text ones such as letter and the +Boolean ones such as not.

+ +

The major new feature in Snap! 6.0 is that the domain and range of +most scalar function blocks is extended to multi-dimensional lists, with +the underlying scalar function applied termwise:

+ +

{width=ā€2.5625inā€ +height=ā€0.9166666666666666inā€}Macintosh
+HD:Users:bh:Desktop:vector-vector.png{width=ā€3.3402777777777777inā€ +height=ā€0.9166666666666666inā€}

+ +

Macintosh
+HD:Users:bh:Desktop:matrix-matrix.png{width=ā€4.944444444444445inā€ +height=ā€0.6944444444444444inā€}

+ +

{width=ā€5.743055555555555inā€ +height=ā€0.6944444444444444inā€}Mathematicians, note in the last example +above that the result is just a termwise application of the underlying +function (7Ɨ3, 8Ɨ5, etc.), not matrix multiplication. See Appendix B +for that. For a dyadic (two-input) function, if the lengths donā€™t agree, +the length of the result (in each dimension) is the length of the +shorter input:

+ +

{width=ā€6.791666666666667inā€ +height=ā€0.8680555555555556inā€}However, if the number of dimensions +differs in the two inputs, then the number of dimensions in the result +agrees with the higher-dimensional input; the lower-dimensional one is +used repeatedly in the missing dimension(s):

+ +

(7Ɨ6. 8Ɨ10, 1Ɨ20, 40Ɨ6, 20Ɨ10, etc.). In particular, a scalar +input is paired with every scalar in the other input:

+ +

{width=ā€7.483333333333333inā€ +height=ā€0.63125inā€}{width=ā€5.506944444444445inā€ +height=ā€1.5180555555555555inā€}One important motivation for this feature +is how it simplifies and speeds up media computation, as in this +shifting of the Alonzo costume to be bluer:

+ +

{width=ā€1.6875inā€ +height=ā€1.0486111111111112inā€}{width=ā€5.194444444444445inā€ +height=ā€1.0486111111111112inā€}Each pixel of the result has Ā¾ of its +original red and green, and three times its original blue (with its +transparency unchanged). By putting some sliders on the stage, you can +play with colors dynamically:

+ +

{width=ā€1.0298611111111111inā€ +height=ā€0.18958333333333333inā€}{width=ā€0.8895833333333333inā€ +height=ā€0.2inā€}There are a few naturally scalar functions that have +already had specific meanings when applied to lists and therefore are +not hyperblocks: = and identical to (because they compare entire +structures, not just scalars, always reporting a single Boolean result), +and and or (because they donā€™t evaluate their second input at all if the +first input determines the result), join (because it converts non-scalar +(and other non-text) inputs to text string form), and is a (type) +(because it applies to its input as a whole). Blocks whose inputs are +ā€œnativelyā€ lists, such as and , are never hyperblocks.

+ +

{width=ā€5.239583333333333inā€ +height=ā€1.679861111111111inā€}{width=ā€5.401514654418198inā€ +height=ā€1.227273622047244inā€}{width=ā€2.0991666666666666inā€ +height=ā€0.2475inā€}The reshape block takes a list (of any depth) as its +first input, and then takes zero or more sizes along the dimensions of +an array. In the example it will report a table (a matrix) of four rows +and three columns. If no sizes are given, the result is an empty list. +Otherwise, the cells of the specified shape are filled with the atomic +values from the input list. If more values are needed than provided, the +block starts again at the head of the list, using values more than once. +If more values are provided than needed, the extras are ignored; this +isnā€™t an error.

+ +

Icon Description automatically
+generated{width=ā€1.34inā€ +height=ā€0.25inā€} The item of block has a special set of rules, designed +to preserve its pre-hyperblock meaning and also provide a useful +behavior when given a list as its first (index) input:

+ +
    +
  1. +

    If the index is a number, then item of reports the indicated +top-level item of the list input; that item may be a sublist, in +which case the entire sublist is reported (the original meaning of +item of):Macintosh
+HD:Users:bh:Desktop:item-scalar.png{width=ā€5.506944444444445inā€ +height=ā€0.9166666666666666inā€}

    +
  2. +
  3. +

    If the index is a list of numbers (no sublists), then item of +reports a list of the indicated top-level items (rows, in a matrix; +a straightforward hyperization): Macintosh
+HD:Users:bh:Desktop:item-vector.png{width=ā€6.006944444444445inā€ +height=ā€0.8680555555555556inā€}

    +
  4. +
  5. +

    If the index is a list of lists of numbers, then item of reports an +array of only those scalars whose position in the list input matches +the index input in all dimensions (changed in Snap! +6.6!):{width=ā€6.006944444444445inā€ +height=ā€0.6875inā€}

    +
  6. +
  7. +

    If a list of list of numbers includes an empty sublist, then all +items are chosen along that +dimension:{width=ā€6.006944444444445inā€ +height=ā€0.6875inā€}

    +
  8. +
+ +

{width=ā€6.604166666666667inā€ +height=ā€1.0486111111111112inā€}To get a column or columns of a +spreadsheet, use an empty list in the row selector (changed in Snap! +6.6!):

+ +

{width=ā€1.5263888888888888inā€ +height=ā€1.8583333333333334inā€}The length of block is extended to provide +various ways of looking at the shape and contents of a list. The options +other than length are mainly useful for lists of lists, to any depth. +These new options work well with hyperblocks and the APL library. +(Examples are on the next page.)

+ +

length: reports the number of (toplevel) items in the list, as always.

+ +

rank: reports the number of dimensions of the list, i.e., the maximum +depth of lists of lists of lists of lists. (That example would be rank +4.)

+ +

dimensions: reports a list of numbers, each of which is the maximum +length in one dimension, so a spreadsheet of 1000 records, each with 4 +fields, would report the list [1000 4].

+ +

flatten: reports a flat, one-dimensional list containing the atomic +(non-list) items anywhere in the input list.

+ +

columns: reports a list in which the rows and columns of the input list +are interchanged, so the shape of the transpose of a shape [1000 4] +list would be [4 1000]. This option works only for lists whose rank is +at most 2. The name reflects the fact that the toplevel items of the +reported table are the columns of the original table.

+ +

reverse: reports a list in which the (toplevel) items of the input list +are in reverse order.

+ +

The remaining three options report a (generally multi-line) text string. +The input list may not include any atomic (non-list) data other than +text or numbers. The lines option is intended for use with rank-one +lists of text strings; it reports a string in which each list item +becomes a line of text. You can think of it as the opposite of the split +by line block. The csv option (comma-separated values) is intended for +rank-two lists that represent a spreadsheet or other tabular data. Each +item of the input list should be a list of atoms; the block reports a +text string in which each item of the big list becomes a line of text in +which the items of that sublist are separated by commas. The json option +is for lists of any rank; it reports a text string in which the list +structure is explicitly represented using square brackets. These are the +opposites of split by csv and split by json.

+ +

{width=ā€6.3530304024496935inā€ +height=ā€6.733522528433946inā€}

+ +

The idea of extending the domain and range of scalar functions to +include arrays comes from the language APL. (All the great programming +languages are based on mathematical ideas. Our primary ancestors are +Smalltalk, based on models, and Lisp, based on lambda calculus. Prolog, +a great language not (so far) influencing Snap!, is based on logic. +And APL, now joining our family, is based on linear algebra, which +studies vectors and matrices. Those other programming languages are +based on the weaknesses of computer hardware.) Hyperblocks are not the +whole story about APL, which also has mixed-domain functions and higher +order functions. Some of whatā€™s missing is provided in the APL library. +(See Appendix B.)

+ +

Typed Inputs

+ +

Scratchā€™s Type Notation

+ +

{width=ā€1.375inā€ +height=ā€0.2125inā€}Prior to version 3, Scratch block inputs came in two +types: Text-or-number type and Number type. The former is indicated by a +rectangular box, the latter by a rounded box: . A third Scratch type, +Boolean (true/false), can be used in certain Control blocks with +hexagonal slots.

+ +

The Snap! types are an expanded collection including Procedure, List, +and Object types. Note that, with the exception of Procedure types, all +of the input type shapes are just reminders to the user of what the +block expects; they are not enforced by the language.

+ +

{width=ā€2.5833333333333335inā€ height=ā€1.6041666666666667inā€}The Snap! Input Type Dialog

+ +

In the Block Editor input name dialog, there is a right-facing arrowhead +after the ā€œInput nameā€ option:

+ +

Clicking that arrowhead opens the ā€œlongā€ input name dialog:

+ +

{width=ā€5.170833333333333inā€ +height=ā€4.135416666666667inā€}{width=ā€0.19791666666666666inā€ +height=ā€0.19791666666666666inā€}There are twelve input type shapes, plus +three mutually exclusive modifiers, listed in addition to the basic +choice between title text and an input name. The default type, the one +you get if you donā€™t choose anything else, is ā€œAny,ā€ meaning that this +input slot is meant to accept any value of any type. If the size input +in your block should be an oval-shaped numeric slot rather than a +generic rectangle, click ā€œNumber.ā€

+ +

{width=ā€6.822222222222222inā€ +height=ā€2.7569444444444446inā€}The arrangement of the input types is +systematic. As the pictures on this and the next page show, each row of +types is a category, and parts of each column form a category. +Understanding the arrangement will make it a little easier to find the +type you want.

+ +

{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}The second row of input types contains +the ones found in Scratch: Number, Any, and Boolean. (The reason these +are in the second row rather than the ļ¬rst will become clear when we +look at the column arrangement.) The ļ¬rst row contains the new Snap! +types other than procedures: Object, Text, and List. The last two rows +are the types related to procedures, discussed more fully below.

+ +

The List type is used for ļ¬rst class lists, discussed in Chapter IV +above. The red rectangles inside the input slot are meant to resemble +the appearance of lists as Snap! displays them on the stage: each +element in a red rectangle.

+ +

The Object type is for sprites, costumes, sounds, and similar data +types.

+ +

The Text type is really just a variant form of the Any type, using a +shape that suggests a text input.5

+ +

Procedure Types

+ +

Although the procedure types are discussed more fully later, they are +the key to understanding the column arrangement in the input types. Like +Scratch, Snap! has three block shapes: jigsaw-piece for command +blocks, oval for reporters, and hexagonal for predicates. (A predicate +is a reporter that always reports true or false.) In Snap! these +blocks are ļ¬rst class data; an input to a block can be of Command type, +Reporter type, or Predicate type. Each of these types is directly below +the type of value that that kind of block reports, except for Commands, +which donā€™t report a value at all. Thus, oval Reporters are related to +the Any type, while hexagonal Predicates are related to the Boolean +(true or false) type.

+ +

The unevaluated procedure types in the fourth row are explained in +Section VI.E below. In one handwavy sentence, they combine the meaning +of the procedure types with the appearance of the reported value types +two rows higher. (Of course, this isnā€™t quite right for the C-shaped +command input type, since commands donā€™t +{width=ā€3.6458333333333335inā€ +height=ā€3.113888888888889inā€}report values. But youā€™ll see later that +itā€™s true in spirit.)

+ +

{width=ā€0.13194444444444445inā€ height=ā€0.13194444444444445inā€}Pulldown inputs

+ +

{width=ā€1.6805555555555556inā€ +height=ā€0.9409722222222222inā€}Certain primitive blocks have pulldown +inputs, either read-only, like the input to the touching block:

+ +

{width=ā€1.9020833333333333inā€ +height=ā€1.3229166666666667inā€}(indicated by the input slot being the +same (cyan, in this case) color as the body of the block), or +writeable, like the input to the point in direction block:

+ +

(indicated by the white input slot), which means that the user can type +in an arbitrary input instead of using the pulldown menu.

+ +

{width=ā€0.8326388888888889inā€ +height=ā€0.6527777777777778inā€}{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}Custom blocks can also have such inputs. +To make a pulldown input, open the long form input dialog, choose a text +type (Any, Text, or Number) and click the icon in the bottom right +corner, or control/right-click in the dialog. You will see this menu:

+ +

{width=ā€3.076388888888889inā€ +height=ā€1.875inā€}Click the read-only checkbox if you want a read-only +pulldown input. Then from the same menu, choose optionsā€¦ to get this +dialog box:

+ +

Each line in the text box represents one menu item. If the line does not +contain any of the characters =~{} then the text is both whatā€™s shown +in the menu and the value of the input if that entry is chosen.

+ +

If the line contains an equal sign =, then the text to the left of the +equal sign is shown in the menu, and the text to the right is what +appears in the input slot if that entry is chosen, and is also the value +of the input as seen by the procedure.

+ +

If the line consists of a tilde ~, then it represents a separator (a +horizontal line) in the menu, used to divide long menus into visible +categories. There should be nothing else on the line. This separator is +not choosable, so there is no input value corresponding to it.

+ +

{width=ā€7.5inā€ +height=ā€3.2416666666666667inā€}If the line ends with the two characters +equal sign and open brace ={, then it represents a submenu. The text +before the equal sign is a name for the submenu, and will be displayed +in the menu with an arrowhead ā–ŗ at the end of the line. This line is not +clickable, but hovering the mouse over it displays the submenu next to +the original menu. A line containing a close brace } ends the submenu; +nothing else should be on that line. Submenus may be nested to arbitrary +depth.

+ +

###

+ +

Alternatively, instead of giving a menu listing as described above, you +can put a JavaScript function that returns the desired menu in the +textbox. This is an experimental feature and requires that JavaScript be +enabled in the Settings menu.
+It is also possible to get the special menus used in some primitive +blocks, by choosing from the menu submenu: broadcast messages, sprites +and stage, costumes, sounds, variables that can be set in this scope, +the play note piano keyboard, or the point in direction 360Ā° dial. +Finally, you can make the input box accept more than one line of text +(that is, text including a newline character) from the special submenu, +either ā€œmulti-lineā€ for regular +{width=ā€0.6041666666666666inā€ +height=ā€0.3194444444444444inā€}text or ā€œcodeā€ for monospace-font computer +code.

+ +

{width=ā€0.13055555555555556inā€ +height=ā€0.1375inā€}{width=ā€1.6805555555555556inā€ +height=ā€0.2569444444444444inā€}If the input type is something other than +text, then clicking the button will instead show this menu:

+ +

{width=ā€7.5inā€ +height=ā€2.6277777777777778inā€}As an example, we want to make this block: +The second input must be a read-only object menu:

+ +

{width=ā€1.6388888888888888inā€ +height=ā€0.5208333333333334inā€}

+ +

{width=ā€1.7638888888888888inā€ +height=ā€0.9305555555555556inā€}{width=ā€3.5694444444444446inā€ +height=ā€1.2944444444444445inā€}The ā€œMultiple inputsā€ option: The list +block introduced earlier accepts any number of inputs to specify the +items of the new list. To allow this, Snap! introduces the arrowhead +notation () that expands and contracts the block, adding and removing +input slots. (Shift-clicking on an arrowhead adds or removes three input +slots at once.) Custom blocks made by the Snap! user have that +capability, too. If you choose the ā€œMultiple inputsā€ button, then +arrowheads will appear after the input slot in the block. More or fewer +slots (as few as zero) may be used. When the block runs, all of the +values in all of the slots for this input name are collected into a +list, and the value of the input as seen inside the script is that list +of values:

+ +

The ellipsis (ā€¦) in the orange input slot name box in the prototype +indicates a multiple or variadic input.

+ +

The third category, ā€œUpvar - make internal variable visible to caller,ā€ +isnā€™t really an input at all, but rather a sort of output from the block +to its user. It appears as an orange variable oval in the block, rather +than as an input slot. Hereā€™s an example; the uparrow (ā†‘) in the +prototype indicates this kind of internal variable name:

+ +

{width=ā€5.901388888888889inā€ +height=ā€0.53125inā€}

+ +

The variable i (in the block on the right above) can be dragged from the +for block into the blocks used in its C-shaped command slot. Also, by +clicking on the orange i, the user can change the name of the variable +as seen in the calling script (although the name hasnā€™t changed inside +the blockā€™s definition). This kind of variable is called an upvar for +short, because it is passed upward from the custom block to the script +that uses it.

+ +

Note about the example: for is a primitive block, but it doesnā€™t need to +be. Youā€™re about to see (next chapter) how it can be written in Snap!. +Just give it a different name to avoid confusion, such as my for as +above.

+ +

Prototype Hints

+ +

We have mentioned three notations that can appear in an input slot in +the prototype to remind you of what kind of input this is. Here is the +complete list of such notations:

+ +

{width=ā€0.7347222222222223inā€ +height=ā€6.118055555555555inā€}= default value ā€¦ multiple input ā†‘ upvar +# number

+ +

{width=ā€0.16319444444444445inā€ +height=ā€0.13541666666666666inā€}Ī» procedure types ā«¶ list ? Boolean object +Ā¶ multi-line text

+ +

Title Text and Symbols

+ +

{width=ā€1.21875inā€ +height=ā€0.23472222222222222inā€}Some primitive blocks have symbols as +part of the block name: . Custom blocks can use symbols too. In the +Block Editor, click the plus sign in the prototype at the point where +you want to insert the symbol. Then click the title text picture below +the text box thatā€™s expecting an input slot name. The dialog will then +change to look like this:

+ +

{width=ā€1.2444444444444445inā€ +height=ā€0.26666666666666666inā€}{width=ā€2.0347222222222223inā€ +height=ā€1.2638888888888888inā€}The important part to notice is the +arrowhead that has appeared at the right end of the text box. Click it +to see the menu shown here at the left.

+ +

Choose one of the symbols. The result will have the symbol you want: The +available symbols are, pretty much, the ones that are used in Snap! +icons.

+ +

{width=ā€2.0347222222222223inā€ +height=ā€1.2638888888888888inā€}But Iā€™d like the arrow symbol bigger, and +yellow, so I edit its name:

+ +

{width=ā€1.1979166666666667inā€ +height=ā€0.2708333333333333inā€}This makes the symbol 1.5 times as big as +the letters in the block text, using a color with red-green-blue values +of 255-255-150 (each between 0 and 255). Hereā€™s the result:

+ +

The size and color controls can also be used with text: +$foo-8-255-120-0 will make a huge orange ā€œfoo.ā€

+ +

Note the last entry in the symbol menu: ā€œnew line.ā€ This can be used in +a block with many inputs to control where the text continues on another +line, instead of letting Snap! choose the line break itself.

+ +

Procedures as Data

+ +

Call and Run

+ +

{width=ā€3.6729166666666666inā€ +height=ā€1.5833333333333333inā€}In the for block example above, the input +named action has been declared as type ā€œCommand (C-shaped)ā€; thatā€™s why +the finished block is C-shaped. But how does the block actually tell +Snap! to carry out the commands inside the C-slot? Here is a simple +version of the block script:

+ +

This is simplified because it assumes, without checking, that the ending +value is greater than the starting value; if not, the block should +(depending on the designerā€™s purposes) either not run at all, or change +the variable by āˆ’1 for each repetition instead of by 1.

+ +

{width=ā€0.5inā€ +height=ā€0.15625inā€}The important part of this script is the run block +near the end. This is a Snap! built-in command block that takes a +Command-type value (a script) as its input, and carries out its +instructions. (In this example, the value of the input is the script +that the user puts in the C-slot of the my for block.) There is a +similar call reporter block for invoking a Reporter or Predicate block. +The call and run blocks are at the heart of Snap!ā€™s ļ¬rst class +procedure feature; they allow scripts and blocks to be used as dataā€”in +this example, as an input to a blockā€”and eventually carried out under +control of the userā€™s program.

+ +

{width=ā€7.065972222222222inā€ +height=ā€1.65625inā€}Hereā€™s another example, this time using a +Reporter-type input in a map block (see page 50):

+ +

Here we are calling the Reporter ā€œmultiply by 10ā€ three times, once with +each item of the given list as its input, and collecting the results as +a list. (The reported list will always be the same length as the input +list.) Note that the multiplication block has two inputs, but here we +have specified a particular value for one of them (10), so the call +block knows to use the input value given to it just to fill the other +(empty) input slot in the multiplication block. In the my map +definition, the input function is declared to be type Reporter, and data +is of type List.

+ +

Call/Run with inputs

+ +

{width=ā€1.8125inā€ +height=ā€0.20833333333333334inā€}The call block (like the run block) has a +right arrowhead at the end; clicking on it adds the phrase ā€œwith inputsā€ +and then a slot into which an input can be inserted:

+ +

If the left arrowhead is used to remove the last input slot, the ā€œwith +inputsā€ disappears also. The right arrowhead can be clicked as many +times as needed for the number of inputs required by the reporter block +being called.

+ +

{width=ā€2.7291666666666665inā€ +height=ā€0.31805555555555554inā€}If the number of inputs given to call +(not counting the Reporter-type input that comes first) is the same as +the number of empty input slots, then the empty slots are filled from +left to right with the given input values. If call is given exactly one +input, then every empty input slot of the called block is filled with +the same value:

+ +

If the number of inputs provided is neither one nor the number of empty +slots, then there is no automatic filling of empty slots. (Instead you +must use explicit parameters in the ring, as discussed in Section C +below.)

+ +

{width=ā€6.990277777777778inā€ +height=ā€0.6979166666666666inā€}An even more important thing to notice +about these examples is the ring around the Reporter-type input slots +in call and map above. This notation indicates that the block itself, +not the number or other value that the block would report when called, +is the input. If you want to use a block itself in a non-Reporter-type +(e.g., Any-type) input slot, you can enclose it explicitly in a ring, +found at the top of the Operators palette.

+ +

As a shortcut, if you right-click or control-click on a block (such as +the + block in this example), one of the choices in the menu that +appears is ā€œringifyā€ and/or ā€œunringify.ā€ The ring indicating a +Reporter-type or Predicate-type input slot is essentially the same idea +for reporters as the C-shaped input slot with which youā€™re already +familiar; with a C-shaped slot, itā€™s the script you put in the slot +that becomes the input to the C-shaped block.

+ +

There are three ring shapes. All are oval on the outside, indicating +that the ring reports a value, the block or script inside it, but the +inside shapes are command, reporter, or predicate, indicating what kind +of block or script is expected. Sometimes you want to put something more +complicated than a single reporter inside a reporter ring; if so, you +can use a script, but the script must report a value, as in a custom +reporter definition.

+ +

Variables in Ring Slots

+ +

Note that the run block in the definition of the my for block (page 65) +doesnā€™t have a ring around its input variable action. When you drag a +variable into a ringed input slot, you generally do want to use the +value of the variable, which will be the block or script youā€™re trying +to run or call, rather than the orange variable reporter itself. So +Snap! automatically removes the ring in this case. If you ever do want +to use the variable block itself, rather than the value of the +variable, as a Procedure-type input, you can drag the variable into the +input slot, then control-click or right-click it and choose ā€œringifyā€ +from the menu that appears. (Similarly, if you ever want to call a +function that will report a block to use as the input, such as item 1 of +applied to a list of blocks, you can choose ā€œunringifyā€ from the menu. +Almost all the time, though, Snap! does what you mean without help.)

+ +

Writing Higher Order Procedures

+ +

A higher order procedure is one that takes another procedure as an +input, or that reports a procedure. In this document, the word +ā€œprocedureā€ encompasses scripts, individual blocks, and nested +reporters. (Unless specified otherwise, ā€œreporterā€ includes predicates. +When the word is capitalized inside a sentence, it means specifically +oval-shaped blocks. So, ā€œnested reportersā€ includes predicates, but ā€œa +Reporter-type inputā€ doesnā€™t.)

+ +

Although an Any-type input slot (what you get if you use the small +input-name dialog box) will accept a procedure input, it doesnā€™t +automatically ring the input as described above. So the declaration of +Procedure-type inputs makes the use of your custom higher order block +much more convenient.

+ +

{width=ā€2.375inā€ +height=ā€1.3541666666666667inā€}Why would you want a block to take a +procedure as input? This is actually not an obscure thing to do; the +primitive conditional and looping blocks (the C-shaped ones in the +Control palette) take a script as input. Users just donā€™t usually think +about it in those terms! We could write the repeat block as a custom +block this way, if Snap! didnā€™t already have one:

+ +

The lambda (Ī») next to action in the prototype indicates that this is a +C-shaped block, and that the script enclosed by the C when the block is +used is the input named action in the body of the script. The only way +to make sense of the variable action is to understand that its value is +a script.

+ +

{width=ā€2.5833333333333335inā€ +height=ā€1.6041666666666667inā€}To declare an input to be Procedure-type, +open the input name dialog as usual, and click on the arrowhead:

+ +

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

+ +

{width=ā€0.19791666666666666inā€ +height=ā€0.19791666666666666inā€}{width=ā€3.6527777777777777inā€ +height=ā€2.75455271216098inā€}
+Why would you ever choose an inline Command slot rather than a C shape? +Other than the run block +{width=ā€2.1145833333333335inā€ +height=ā€0.46875inā€}discussed below, the only case I can think of is +something like the C/C++/Java for loop, which actually has three +command script inputs (and one predicate input), only one of which is +the ā€œfeaturedā€ loop body:

+ +

Okay, now that we have procedures as inputs to our blocks, how do we use +them? We use the blocks run (for commands) and call (for reporters). The +run blockā€™s script input is an inline ring, not C-shaped, because we +anticipate that it will be rare to use a specific, literal script as the +input. Instead, the input will generally be a variable whose value is +a script.

+ +

The run and call blocks have arrowheads at the end that can be used to +open slots for inputs to the called procedures. How does Snap! know +where to use those inputs? If the called procedure (block or script) has +empty input slots, Snap! ā€œdoes the right thing.ā€ This has several +possible meanings:

+ +

{width=ā€3.4479166666666665inā€ +height=ā€0.34405949256342955inā€}1. If the number of empty slots is +exactly equal to the number of inputs provided, then Snap! fills the +empty slots from left to right:

+ +

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

+ +

{width=ā€2.8020833333333335inā€ +height=ā€0.30694444444444446inā€}

+ +

3. Otherwise, Snap! wonā€™t fill any slots, because the userā€™s intention +is unclear.

+ +

If the user wants to override these rules, the solution is to use a ring +with explicit input names that can be put into the given block or script +to indicate how inputs are to be used. This will be discussed more fully +below.

+ +

Recursive Calls to Multiple-Input Blocks

+ +

A relatively rare situation not yet considered here is the case of a +recursive block that has a variable number of inputs. Letā€™s say the user +of your project calls your block with five inputs one time, and 87 +inputs another time. How do you write the recursive call to your block +when you donā€™t know how many inputs to give it? The answer is that you +collect the inputs in a list (recall that, when you declare an input +name to represent a variable number of inputs, your block sees those +inputs as a list of values in the first place), and then, in the +recursive call, you drop that input list onto the arrowheads that +indicate a variable-input slot, rather than onto the input slot:

+ +

{width=ā€0.13194444444444445inā€ +height=ā€0.13194444444444445inā€}{width=ā€2.501388888888889inā€ +height=ā€1.9444444444444444inā€}{width=ā€2.225inā€ +height=ā€1.1708333333333334inā€}{width=ā€2.2756944444444445inā€ +height=ā€1.5972222222222223inā€}
+Note that the halo you see while dragging onto the arrowheads is red +instead of white, and covers the input slot as well as the arrowheads. +And when you drop the expression onto the arrowheads, the words ā€œinput +list:ā€ are added to the block text and the arrowheads disappear (in this +invocation only) to remind you that the list represents all of the +multiple inputs, not just a single input. The items in the list are +taken individually as inputs to the script. Since numbers is a list of +numbers, each individual item is a number, just what sizes wants. This +{width=ā€6.8125inā€ +height=ā€1.7104166666666667inā€}block will take any number of numbers as +inputs, and will make the sprite grow and shrink accordingly:

+ +

{width=ā€2.9583333333333335inā€ +height=ā€0.6875inā€}The user of this block calls it with any number of +individual numbers as inputs. But inside the definition of the block, +all of those numbers form a list that has a single input name, +numbers. This recursive definition ļ¬rst checks to make sure there are +any inputs at all. If so, it processes the ļ¬rst input (item 1 of the +list), then it wants to make a recursive call with all but the ļ¬rst +number. But sizes doesnā€™t take a list as input; it takes numbers as +inputs! So this would be wrong:

+ +

Formal Parameters

+ +

{width=ā€3.5208333333333335inā€ +height=ā€1.0395833333333333inā€}The rings around Procedure-type inputs +have an arrowhead at the right. Clicking the arrowhead allows you to +give the inputs to a block or script explicit names, instead of using +empty input slots as weā€™ve done until now.

+ +

The names #1, #2, etc. are provided by default, but you can change a +name by clicking on its orange oval in the input names list. Be careful +not to drag the oval when clicking; thatā€™s how you use the input +inside the ring. The names of the input variables are called the formal +parameters of the encapsulated procedure.

+ +

{width=ā€4.322916666666667inā€ +height=ā€0.45416666666666666inā€}Hereā€™s a simple but contrived example +using explicit names to control which input goes where inside the ring:

+ +

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

+ +

{width=ā€4.679861111111111inā€ +height=ā€3.0180555555555557inā€}Here is a more realistic, much more +advanced example:

+ +

{width=ā€4.347222222222222inā€ +height=ā€1.4027777777777777inā€}

+ +

This is the definition of a block that takes any number of lists, and +reports the list of all possible combinations of one item from each +list. The important part for this discussion is that near the bottom +there are two nested calls to map, the higher order function that +applies an input function to each item of an input list. In the inner +block, the function being mapped is in front of, and that block takes +two inputs. The second, the empty List-type slot, will get its value in +each call from an item of the inner mapā€™s list input. But there is no +way for the outer map to communicate values to empty slots of the in +front of block. We must give an explicit name, newitem, to the value +that the outer map is giving to the inner one, then drag that variable +into the in front of block.

+ +

By the way, once the called block provides names for its inputs, Snap! +will not automatically fill empty slots, on the theory that the user has +taken control. In fact, thatā€™s another reason you might want to name the +inputs explicitly: to stop Snap! from filling a slot that should +really remain empty.

+ +

Procedures as Data

+ +

{width=ā€5.1875inā€ +height=ā€1.65625inā€}Hereā€™s an example of a situation in which a procedure +must be explicitly marked as data by pulling a ring from the Operators +palette and putting the procedure (block or script) inside it:

+ +

Here, we are making a list of procedures. But the list block accepts +inputs of any type, so its input slots are not ringed. We must say +explicitly that we want the block itself as the input, rather than +whatever value would result from evaluating the block.

+ +

{width=ā€3.8333333333333335inā€ +height=ā€0.84375inā€}Besides the list block in the example above, other +blocks into which you may want to put procedures are set (to set the +value of a variable to a procedure), say and think (to display a +procedure to the user), and report (for a reporter that reports a +procedure):

+ +

Special Forms

+ +

{width=ā€2.4993055555555554inā€ +height=ā€0.27847222222222223inā€}{width=ā€2.402083333333333inā€ +height=ā€1.4270833333333333inā€}The primitive if else block has two +C-shaped command slots and chooses one or the other depending on a +Boolean test. Because Scratch doesnā€™t emphasize functional programming, +it lacks a corresponding reporter block to choose between two +expressions. Snap! has one, but we could write our own:

+ +

{width=ā€4.291666666666667inā€ +height=ā€0.8486111111111111inā€}{width=ā€3.818985126859143inā€ +height=ā€0.27433070866141734inā€}Our block works for these simple +examples, but if we try to use it in writing a recursive operator, itā€™ll +fail:

+ +

The problem is that when any block is called, all of its inputs are +computed (evaluated) before the block itself runs. The block itself +knows only the values of its inputs, not what expressions were used to +compute them. In particular, all of the inputs to our if then else block +are evaluated ļ¬rst thing. That means that even in the base case, +factorial will try to call itself recursively, causing an infinite loop. +We need our if then else block to be able to select only one of the two +alternatives to be evaluated.

+ +

We have a mechanism to allow that: declare the then and else inputs to +be of type Reporter rather than type Any. Then, when calling the block, +those inputs will be enclosed in a ring so that the expressions +themselves, rather than their values, become the inputs:

+ +

{width=ā€1.1145833333333333inā€ +height=ā€0.6979166666666666inā€}{width=ā€4.520833333333333inā€ +height=ā€1.0229166666666667inā€}{width=ā€2.6173611111111112inā€ +height=ā€1.5104166666666667inā€}

+ +

In this version, the program works, with no infinite loop. But weā€™ve +paid a heavy price: this reporter-if is no longer as intuitively obvious +as the Scratch command-if. You have to know about procedures as data, +about rings, and about a trick to get a constant value in a ringed slot. +(The id block implements the identity function, which reports its +input.6 We need it because rings take only reporters as input, not +numbers.) What weā€™d like is a reporter-if that behaves like this one, +delaying the evaluation of its inputs, but looks like our ļ¬rst +version, which was easy to use except that it didnā€™t work.

+ +

Such blocks are indeed possible. A block that seems to take a simple +expression as input, but delays the evaluation of that input by wrapping +an ā€œinvisible ringā€ around it (and, if necessary, an id-like +transformation of constant data into constant functions) is called a +special form. To turn our if block into a special form, we edit the +blockā€™s prototype, declaring the inputs yes and no to be of type ā€œAny +(unevaluated)ā€ instead of type Reporter. The script for the block is +still that of the second version, including the use of call to evaluate +either yes or no but not both. But the slots appear as white Any-type +rectangles, not Reporter-type rings, and the factorial block will look +like our ļ¬rst attempt.

+ +

In a special formā€™s prototype, the unevaluated input slot(s) are +indicated by a lambda (Ī») next to the input name, just as if they were +declared as Procedure type. They are Procedure type, really; theyā€™re +just disguised to the user of the block.

+ +

Special forms trade off implementor sophistication for user +sophistication. That is, you have to understand all about procedures as +data to make sense of the special form implementation of my if then +else. But any experienced Scratch programmer can use my if then else +without thinking at all about how it works internally.

+ +

Special Forms in Scratch

+ +

Special forms are actually not a new invention in Snap!. Many of +Scratchā€™s conditional and looping blocks are really special forms. The +hexagonal input slot in the if block is a straightforward Boolean value, +because the value can be computed once, before the if block makes its +decision about whether or not to run its action input. But the forever +if, repeat until, and wait until blocksā€™ inputs canā€™t be Booleans; they +have to be of type ā€œBoolean (unevaluated),ā€ so that Scratch can evaluate +them over and over again. Since Scratch doesnā€™t have custom Cā€‘shaped +blocks, it can afford to handwave away the distinction between evaluated +and unevaluated Booleans, but Snap! canā€™t. The pedagogic value of +special forms is proven by the fact that no Scratcher ever notices that +thereā€™s anything strange about the way in which the hexagonal inputs in +the Control blocks are evaluated.

+ +

Also, the C-shaped slot familiar to Scratch users is an unevaluated +procedure type; you donā€™t have to use a ring to keep the commands in the +C-slot from being run before the C-shaped block is run. Those commands +themselves, not the result of running them, are the input to the +C-shaped Control block. (This is taken for granted by Scratch users, +especially because Scratchers donā€™t think of the contents of a C-slot as +an input at all.) This is why it makes sense that ā€œCā€‘shapedā€ is on the +fourth row of types in the long form input dialog, with other +unevaluated types.

+ +

Object Oriented Programming with Sprites

+ +

Object oriented programming is a style based around the abstraction +object: a collection of data and methods (procedures, which from +our point of view are just more data) that you interact 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. Our approach +is therefore less restrictive than that of some other OOP languages; we +give objects easy access to each othersā€™ data and methods.

+ +

Technically, object oriented programming rests on three legs: (1) +Message passing: There is a notation by which any object can send a +message to another object. (2) Local state: Each object can remember +the important past history of the computation it has performed. +(ā€œImportantā€ means that it need not remember every message it has +handled, but only the lasting effects of those messages that will affect +later computation.) (3) Inheritance: It would be impractical if each +individual object had to contain methods, many of them identical to +those of other objects, for all of the messages it can accept. Instead, +we need a way to say that this new object is just like that old object +except for a few differences, so that only those differences need be +programmed explicitly.

+ +

First Class Sprites

+ +

Like Scratch, Snap! comes with things that are natural objects: its +sprites. Each sprite can own local variables; each sprite has its own +scripts (methods). A Scratch animation is plainly a simulation of the +interaction of characters in a play. There are two ways in which Scratch +sprites are less versatile than the objects of an OOP language. First, +Scratch message passing is weak in three respects: Messages can only be +broadcast, not addressed to an individual sprite; messages canā€™t take +inputs; and methods canā€™t return values to their caller. Second, and +more basic, in the OOP paradigm objects are data; they can be the +value of a variable, an element of a list, and so on, but thatā€™s not the +case for Scratch sprites.

+ +

Snap! sprites are ļ¬rst class data. They can be created and deleted by +a script, stored in a variable or list, and sent messages individually. +The children of a sprite can inherit sprite-local variables, methods +(sprite-local procedures), and other attributes (e.g., x position).

+ +

{width=ā€0.9652777777777778inā€ +height=ā€0.19444444444444445inā€}{width=ā€1.0833333333333333inā€ +height=ā€0.19444444444444445inā€}{width=ā€0.6666666666666666inā€ +height=ā€0.19444444444444445inā€}The fundamental means by which programs +get access to sprites is the my reporter block. It has a dropdown-menu +input slot that, when clicked, gives access to all the sprites, plus the +stage. reports a single sprite, the one asking the question. reports a +list of all sprites other than the one asking the question. reports a +list of all sprites that are near the one askingā€”the ones that are +candidates for having collided with this one, for example. The my block +has many other options, discussed below. If you know the name of a +particular sprite, the object reporter will report the sprite itself.

+ +

{width=ā€3.5520833333333335inā€ +height=ā€0.5104166666666666inā€}{width=ā€2.691434820647419inā€ +height=ā€1.25inā€}An object or list of objects reported by my or object +can be used as input to any block that accepts any input type, such as +setā€™s second input. If you say an object, the resulting speech balloon +will contain a smaller image of the objectā€™s costume or (for the stage) +background.

+ +

Permanent and Temporary Clones

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.19444444444444445inā€}The block is used to create and report an +instance (a clone) of any sprite. (There is also a command version, for +historical reasons.) There are two different kinds of situations in +which clones are used. One is that youā€™ve made an example sprite and, +when you start the project, you want a fairly large number of +essentially identical sprites that behave like the example. (Hereafter +weā€™ll call the example sprite the ā€œparentā€ and the others the +ā€œchildren.ā€) Once the game or animation is over, you donā€™t need the +copies any more. (As weā€™ll see, ā€œcopiesā€ is the wrong word because the +parent and the children share a lot of properties. Thatā€™s why we use +the word ā€œclonesā€ to describe the children rather than ā€œcopies.ā€) These +are temporary clones. They are automatically deleted when the user +presses either the green flag or the red stop sign. In Scratch 2.0 and +later, all clones are temporary.

+ +

The other kind of situation is what happens when you want +specializations of sprites. For example, letā€™s say you have a sprite +named Dog. It has certain behaviors, such as running up to a person who +comes near it. Now you decide that the family in your story really likes +dogs, so they adopt a lot of them. Some are cocker spaniels, who wag +their tails when they see you. Others are rottweilers, who growl at you +when they see you. So you make a clone of Dog, perhaps rename it Cocker +Spaniel, and give it a new costume and a script for what to do when +someone gets near. You make another clone of Dog, perhaps rename it +Rottweiler, and give it a new costume, etc. Then you make three clones +of Cocker Spaniel (so there are four altogether) and two clones of +Rottweiler. Maybe you hide the Dog sprite after all this, since itā€™s no +breed in particular. Each dog has its own position, special behaviors, +and so on. You want to save all of these dogs in the project. These are +permanent clones. In BYOB 3.1, the predecessor to Snap!, all clones +are permanent.

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.19444444444444445inā€}One advantage of temporary clones is that +they donā€™t slow down Snap! even when you have a lot of them. (If +youā€™re curious, one reason is that permanent clones appear in the sprite +corral, where their pictures have to be updated to reflect the cloneā€™s +current costume, direction, and so on.) We have tried to anticipate your +needs, as follows: When you make a clone in a script, using the block, +it is ā€œbornā€ temporary. But when you make a clone from the user +interface, for example by right-clicking on a sprite and choosing +ā€œclone,ā€ it is born permanent. The reason this makes sense is that you +donā€™t create 100 kinds of dogs automatically. Each kind has many +different characteristics, programmed by hand. But when your project is +running, it might create 100 rottweilers, and those will be identical +unless you change them in the program.

+ +

{width=ā€1.5138888888888888inā€ +height=ā€0.2569444444444444inā€}You can change a temporary sprite to +permanent by right-clicking it and choosing ā€œedit.ā€ (Itā€™s called ā€œeditā€ +rather than, say, ā€œpermanentā€ because it also shifts the scripting area +to reflect that sprite, as if youā€™d pressed its button in the sprite +corral.) You can change a permanent sprite to temporary by +right-clicking it and choosing ā€œrelease.ā€ You can also change the status +of a clone in your program with with true or false as the second input.

+ +

Sending Messages to Sprites

+ +

The messages that a sprite accepts are the blocks in its palettes, +including both all-sprites and this-sprite-only blocks. (For custom +blocks, the corresponding methods are the scripts as seen in the Block +Editor.

+ +

{width=ā€5.702083333333333inā€ +height=ā€0.3611111111111111inā€}The way to send a message to a sprite (or +the stage) is with the tell block (for command messages) or the ask +block (for reporter messages).

+ +

{width=ā€6.236111111111111inā€ +height=ā€0.8055555555555556inā€}A small point to note in the examples +above: all dropdown menus include an empty entry at the top, which can +be selected for use in higher order procedures like the for each and map +examples. Each of the sprites in my neighbors or my other sprites is +used to fill the blank space in turn.

+ +

{width=ā€5.164583333333334inā€ +height=ā€0.2847222222222222inā€}By the way, if you want a list of all +the sprites, including this sprite, you can use either of these:

+ +

{width=ā€3.545138888888889inā€ +height=ā€0.8263888888888888inā€}Tell and ask wait until the other sprite +has carried out its method before this spriteā€™s script continues. (That +has to be the case for ask, since we want to do something with the value +it reports.) So tell is analogous to broadcast and wait. Sometimes the +other spriteā€™s method may take a long time, or may even be a forever +loop, so you want the originating script to continue without waiting. +For this purpose we have the launch block:

+ +

Launch is analogous to broadcast without the ā€œwait.ā€

+ +

Snap! 4.1, following BYOB 3.1, used an extension of the of block to +provide access to other spritesā€™ methods. That interface was designed +back when we were trying hard to avoid adding new primitive blocks; it +allowed us to write ask and tell as tool procedures in Snap! itself. +That technique still works, but is deprecated, because nobody understood +it, and now we have the more straightforward primitives.

+ +

Polymorphism

+ +

{width=ā€1.6736111111111112inā€ +height=ā€1.4020833333333333inā€}Suppose you have a Dog sprite with two +clones CockerSpaniel and PitBull. In the Dog sprite you define this +method (ā€œFor this sprite onlyā€ block):

+ +

Note the location (map-pin) symbol before the blockā€™s name. The symbol +is not part of the block title; itā€™s a visual reminder that this is a +sprite-local block. Sprite-local variables are similarly marked.

+ +

But you donā€™t define greet as friend or greet as enemy in Dog. Each kind +of dog has a different behavior. Hereā€™s what a CockerSpaniel does:

+ +

{width=ā€4.052777777777778inā€ +height=ā€0.7430555555555556inā€}{width=ā€4.074305555555555inā€ +height=ā€0.7013888888888888inā€}And hereā€™s what a PitBull does:

+ +

Greet is defined in the Dog sprite. If Fido is a particular cocker +spaniel, and you ask Fido to greet someone, Fido inherits the greet +method from Dog, but Dog itself couldnā€™t actually run that method, +because Dog doesnā€™t have greet as friend or greet as enemy. And perhaps +only individual dogs such as Fido have friend? methods. Even though the +greet method is defined in the Dog sprite, when itā€™s running it +remembers what specific dog sprite called it, so it knows which greet as +friend to use. Dogā€™s greet block is called a polymorphic method, +because it means different things to different dogs, even though they +all share the same script.

+ +

Local State in Sprites: Variables and Attributes

+ +

A spriteā€™s memory of its own past history takes two main forms. It has +variables, created explicitly by the user with the ā€œMake a variableā€ +button; it also has attributes, the qualities every sprite has +automatically, such as position, direction, and pen color. Each variable +can be examined using its own orange oval block; there is one set block +to modify all variables. Attributes, however, have a less uniform +programming interface in Scratch:

+ + + +

The block, if any, that examines a variable or attribute is called its +getter; a block (there may be more than one, as in the direction +example above) that modifies a variable or attribute is called a +setter.

+ +

{width=ā€2.2381944444444444inā€ +height=ā€2.084722222222222inā€}In Snap! we allow virtually all +attributes to be examined. But instead of adding dozens of reporters, we +use a more uniform interface for attributes: The my blockā€™s menu (in +Sensing; see page 78) includes many of the attributes of a sprite. It +serves as a general getter for those attributes, e.g., my [anchor] to +find the sprite, if any, to which this sprite is attached in a nesting +arrangement (see page 10). Similarly, the same set block used to set +variable values allows setting some sprite attributes.

+ +

Prototyping: Parents and Children

+ +

Most current OOP languages use a class/instance approach to creating +objects. A class is a particular kind of object, and an instance is an +actual object of that type. For example, there might be a Dog class, +and several instances Fido, Spot, and Runt. The class typically +specifies the methods shared by all dogs (RollOver, SitUpAndBeg, Fetch, +and so on), and the instances contain data such as species, color, and +friendliness. Snap! uses a different approach called prototyping, in +which there is no distinction between classes and instances. Prototyping +is better suited to an experimental, tinkering style of work: You make a +single dog sprite, with both methods (blocks) and data (variables); you +can actually watch it and interact with it on the stage; and when you +like it, you use it as the prototype from which to clone other dogs. If +you later discover a bug in the behavior of dogs, you can edit a method +in the parent, and all of the children will automatically share the new +version of the method block. Experienced class/instance programmers may +find prototyping strange at first, but it is actually a more expressive +system, because you can easily simulate a class/instance hierarchy by +hiding the prototype sprite! Prototyping is also a better fit with the +Scratch design principle that everything in a project should be concrete +and visible on the stage; in class/instance OOP the programming process +begins with an abstract, invisible entity, the class, that must be +designed before any concrete objects can be made.7

+ +

{width=ā€7.500694444444444inā€ +height=ā€1.5743055555555556inā€}There are three ways to make a child +sprite. If you control-click or right-click on a sprite in the ā€œsprite +corralā€ at the bottom right corner of the window, you get a menu that +includes ā€œcloneā€ as one of the choices. There is an a new clone of block +in the Control palette that creates and reports a child sprite. And +sprites have a ā€œparentā€ attribute that can be set, like any attribute, +thereby changing the parent of an existing sprite.

+ +

Inheritance by Delegation

+ +

A clone inherits properties of its parent. ā€œPropertiesā€ include +scripts, custom blocks, variables, named lists, system attributes, +costumes, and sounds. Each individual property can be shared between +parent and child, or not shared (with a separate one in the child). The +getter block for a shared property, in the childā€™s palette, is displayed +in a lighter color; separate properties of the child are displayed in +the traditional colors.

+ +
+

When a new clone is created, by default it shares only its methods, +wardrobe, and jukebox with its parent. All other properties are copied +to the clone, but not shared. (One exception is that a new permanent +clone is given a random position. Another is that temporary clones +share the scripts in their parentā€™s scripting area. A third is that +sprite-local variables that the parent creates after cloning are +shared with its children.) If the value of a shared property is +changed in the parent, then the children see the new value. If the +value of a shared property is changed in the child, then the sharing +link is broken, and a new private version is created in that child. +(This is the mechanism by which a child chooses not to share a +property with its parent.) ā€œChangedā€ in this context means using the +set or change block for a variable, editing a block in the Block +Editor, editing a costume or sound, or inserting, deleting, or +reordering costumes or sounds. To change a property from unshared to +shared, the child uses the inherit command block. The pulldown menu in +the block lists all the things this sprite can inherit from its parent +(which might be nothing, if this sprite has no parent) and is not +already inheriting. But that would prevent telling a child to inherit, +so if the inherit block is inside a ring, its pulldown menu includes +all the things a child could inherit from this sprite. Right-clicking +on the scripting area of a permanent clone gives a menu option to +share the entire collection of scripts from its parent, as a temporary +clone does.

+
+ +

The rules are full of details, but the basic idea is simple: Parents can +change their children, but children canā€™t directly change their parents. +Thatā€™s what youā€™d expect from the word ā€œinheritā€: the influence just +goes in one direction. When a child changes some property, itā€™s +declaring independence from its parent (with respect to that one +property). What if you really want the child to be able to make a change +in the parent (and therefore in itself and all its siblings)? Remember +that in this system any object can tell any other object to do +something:

+ +

{width=ā€5.072916666666667inā€ +height=ā€0.5833333333333334inā€}When a sprite gets a message for which it +doesnā€™t have a corresponding block, the message is delegated to that +spriteā€™s parent. When a sprite does have the corresponding block, then +the message is not delegated. If the script that implements a delegated +message refers to my (self), it means the child to which the message was +originally sent, not the parent to which the message was delegated.

+ +

{width=ā€0.7895833333333333inā€ height=ā€3.4680555555555554inā€}List of attributes

+ +

{width=ā€1.19inā€ +height=ā€0.25inā€}{width=ā€1.1756944444444444inā€ +height=ā€6.116666666666666inā€}At the right is a picture of the dropdown +menu of attributes in the my block.

+ +

Several of these are not real attributes, but things related to +attributes:

+ + + +

The others are individual attributes:

+ + + +
+

bounding box, rounded oļ¬€ā€“the geometric center of the costume.

+
+ +

First Class Costumes and Sounds

+ +

Costumes and sounds donā€™t have methods, as sprites do; you canā€™t ask +them to do things. But they are first class: you can make a list of +them, put them in variables, use them as input to a procedure, and so +on. My [costumes] and my [sounds] report lists of them.

+ +

Media Computation with Costumes

+ +

{width=ā€1.6319444444444444inā€ +height=ā€0.1875inā€}The components of a costume are its name, width, +height, and pixels. The block gives access to these components using its +left menu. From its right menu you can choose the current costume, the +Turtle costume, or any costume in the spriteā€™s wardrobe. Since costumes +are first class, you can also drop an expression whose value is a +costume, or a list of costumes, on that second input slot. (Due to a +misfeature, even though you can select Turtle in the right menu, the +block reports 0 for its width and height, and an empty string for the +other components.) The costumeā€™s width and height are in its standard +orientation, regardless of the spriteā€™s current direction. (This is +different from the spriteā€™s width and height, reported by the my +block.)

+ +

But the really interesting part of a costume is its bitmap, a list of +pixels. (A pixel, short for ā€œpicture element,ā€ represents one dot on +your display.) Each pixel is itself a list of four items, the red, +green, and blue components of its color (in the range 0-255) and what is +standardly called its ā€œtransparencyā€ but should be called its opacity, +also in the range 0-255, in which 0 means that the pixel is invisible +and 255 means that itā€™s fully opaque: you canā€™t see anything from a +rearward layer at that point on the stage. (Costume pixels typically +have an opacity of 0 only for points inside the bounding box of the +costume but not actually part of the costume; points in the interior of +a costume typically have an opacity of 255. Intermediate values appear +mainly at the edge of a costume, or at sharp boundaries between colors +inside the costume, where they are used to reduce ā€œjaggiesā€: the +stairstep-like shape of a diagonal line displayed on an array of +discrete rectangular screen coordinates. Note that the opacity of a +sprite pixel is determined by combining the costumeā€™s opacity with the +spriteā€™s ghost effect. (The latter really is a measure of transparency: +0 means opaque and 100 means invisible.)

+ +

{width=ā€6.100694444444445inā€ +height=ā€1.3895833333333334inā€}The bitmap is a one-dimensional list of +pixels, not an array of height rows of width pixels each. Thatā€™s why +the pixel list has to be combined with the dimensions to produce a +costume. This choice partly reflects the way bitmaps are stored in the +computerā€™s hardware and operating system, but also makes it easy to +produce transformations of a costume with map:

+ +

In this simplest possible transformation, the red value of all the +pixels have been changed to a constant 150. Colors that were red in the +original (such as the logo printed on the t-shirt) become closer to +black (the other color components being near zero); the blue jeans +become purple (blue plus red); perhaps counterintuitively, the white +t-shirt, which has the maximum value for all three color components, +loses some of its red and becomes cyan, the color opposite red on the +color wheel. In reading the code, note that the function that is the +first input to map is applied to a single pixel, whose first item is its +red component. Also note that this process works only on bitmap +costumes; if you call pixels of on a vector costume (one with ā€œsvgā€ in +the corner of its picture), it will be converted to pixels first.

+ +

{width=ā€2.2569444444444446inā€ +height=ā€0.2847222222222222inā€}One important point to see here is that a +bitmap (list of pixels) is not, by itself, a costume. The new costume +block creates a costume by combining a bitmap, a width, and a height. +But, as in the example above, switch to costume will accept a bitmap as +input and will automatically use the width and height of the current +costume. Note that thereā€™s no name input; costumes computed in this way +are all named costume. Note also that the use of switch to costume does +not add the computed costume to the spriteā€™s wardrobe; to do that, say

+ +

{width=ā€7.508333333333334inā€ +height=ā€1.2090277777777778inā€}Hereā€™s a more interesting example of color +manipulation:

+ +

{width=ā€4.5625inā€ +height=ā€0.40694444444444444inā€}Each color value is constrained to be 0, +80, 160, or 240. This gives the picture a more cartoonish look. +Alternatively, you can do the computation taking advantage of +hyperblocks:

+ +

Hereā€™s one way to exchange red and green values:

+ +

{width=ā€7.5inā€ +height=ā€0.6555555555555556inā€}{width=ā€0.9583333333333334inā€ +height=ā€0.18055555555555555inā€}Itā€™s the list that determines the +rearrangement of colors: greenāž”red, redāž”green, and the other two +unchanged. That list is inside another list because otherwise it would +be selecting rows of the pixel array, and we want to select columns. +We use pixels of costume current rather than costume apple because the +latter is always a red apple, so this little program would get stuck +turning it green, instead of alternating colors.

+ +

{width=ā€5.569444444444445inā€ +height=ā€0.4236111111111111inā€}{width=ā€1.7222222222222223inā€ +height=ā€0.22916666666666666inā€}The stretch block takes a costume as its +first input, either by selecting a costume from the menu or by dropping +a costume-valued expression such as onto it. The other two inputs are +percents of the original width and height, as advertised, so you can +make fun house mirror versions of costumes:

+ +

The resulting costumes can be used with switch to costume and so on.

+ +

{width=ā€5.330729440069991inā€ +height=ā€0.3541666666666667inā€}Finally, you can use pictures from your +computerā€™s camera in your projects using these blocks:

+ +

{width=ā€1.4722222222222223inā€ +height=ā€0.24305555555555555inā€}Using the video on block turns on the +camera and displays what it sees on the stage, regardless of the inputs +given. The camera remains on until you click the red stop button, your +program runs the stop all block, or you turn it off explicitly with the +block. The video image on the stage is partly ghosted, to an extent +determined by the set video transparency block, whose input really is +transparency and not opacity. (Small numbers make the video more +visible.) By default, the video image is mirrored, like the selfie +camera on your cell phone: When you raise your left hand, your image +raises its right hand. You can control this +{width=ā€1.4027777777777777inā€ +height=ā€0.24305555555555555inā€}mirroring with the block.

+ +

{width=ā€1.2041666666666666inā€ +height=ā€1.6125inā€}The video snap on block then takes a still picture +from the camera, and trims it to fit on the selected sprite. (Video snap +on stage means to use the entire stage-sized rectangle.) For example, +hereā€™s a camera snapshot trimmed to fit Alonzo:

+ +

{width=ā€2.670138888888889inā€ +height=ā€1.2986111111111112inā€}The ā€œVideo Captureā€ project in the +Examples collection repeatedly takes such trimmed snapshots and has the +Alonzo sprite use the current snapshot as its costume, so it looks like +this:

+ +

{width=ā€2.6666666666666665inā€ +height=ā€2.0inā€}{width=ā€3.3333333333333335inā€ +height=ā€2.5inā€}(The picture above was actually taken with transparency +set to 50, to make the background more visible for printing.) Because +the sprite is always still in the place where the snapshot was taken, +its costume exactly fits in with the rest of the full-stage video. If +you were to add a move 100 steps block after the switch to costume, +youā€™d see something like this:

+ +

This time, the spriteā€™s costume was captured at one position, and then +the sprite is shown at a different position. (You probably wouldnā€™t want +to do this, but perhaps itā€™s helpful for explanatory purposes.)

+ +

{width=ā€7.375694444444444inā€ +height=ā€1.6423611111111112inā€}What you would want to do is push the +sprite around the stage:

+ +

{width=ā€3.0902777777777777inā€ +height=ā€1.9236111111111112inā€}(Really these should be Jensā€™s picture; +itā€™s his project. But heā€™s vacationing. ā˜ŗ) Video motion compares two +snapshots a moment apart, looking only at the part within the given trim +(here myself, meaning the current sprite, not the person looking into +the camera), to detect a difference between them. It reports a number, +measuring the number of pixels through which some part of the picture +has moved. Video direction also compares two snapshots to detect motion, +but what it reports is the direction (in the point in direction sense) +of the motion. So the script above moves the sprite in the direction in +which itā€™s being pushed, but only if a significant amount of motion is +found; otherwise the sprite would jiggle around too much. And yes, you +can run the second script without the first to push a balloon around the +stage.

+ +

Media Computation with Sounds {#media-computation-with-sounds .ListParagraph}

+ +

The starting point for computation with sound is the microphone block. +It starts by recording a brief burst of sound from your microphone. (How +brief? On my computer, 0.010667 seconds, but youā€™ll see shortly how to +ļ¬nd out or control the sample size on your computer.)

+ +

{width=ā€1.9652777777777777inā€ +height=ā€0.2569444444444444inā€}{width=ā€5.999305555555556inā€ +height=ā€2.620138888888889inā€}Just as the pixel is the smallest piece +of a picture, the sample is the smallest piece of a sound. It says +here: that on my computer, 48,000 samples are recorded per second, so +each sample is 1/48,000 of a second. The value of a sample is between -1 +and 1, and represents the sound pressure on the microphoneā€”how hard +the air is pushingā€”at that instant. (You can skip the next page or so +if you know about Fourier analysis.) Hereā€™s a picture of 400 samples:

+ +

In this graph, the x axis represents the time at which each sample was +measured; the y axis measures the value of the sample at that time. +The first obvious thing about this graph is that it has a lot of ups and +downs. The most basic up-and-down function is the sine wave:

+ +

Every periodic function (more or less, any sample that sounds like music +rather than sounding like static) is composed of a sum of sine waves of +different frequencies.

+ +

Look back at the graph of our sampled sound. There is a green dot every +seven samples. Thereā€™s nothing magic about the number seven; I tried +different values until I found one that looked right. What ā€œrightā€ means +is that, for the first few dots at least, they coincide almost perfectly +with the high points and low points of the graph. Near the middle +(horizontally) of the graph, the green dots donā€™t seem anywhere near the +high and low points, but if you find the very lowest point of the graph, +about 2/3 of the way along, the dots start lining up almost perfectly +again.

+ +

The red graph above shows two cycles of a sine wave. One cycle goes +up, then down, then up again. The amount of time taken for one cycle is +the period of the sine function. If the green dots match both ups and +downs in the captured sound, then two dotsā€”14 samples, or 14/48000 of +a secondā€”represent the period. The first cycle and a half of the graph +looks like it could be a pure sine wave, but after that, the tops and +bottoms donā€™t line up, and there are peculiar little jiggles, such as +the one before the fifth green dot. This happens because sine waves of +different periods are added together.

+ +

It turns out to be more useful to measure the reciprocal of the period, +in our case, 48000/14 or about 3429 cycles per second. Another name +for ā€œcycles per secondā€ is ā€œHertz,ā€ abbreviated Hz, so our sound has a +component at 3249 Hz. As a musical note, thatā€™s about an A (a little +flat), four octaves above middle C. (Donā€™t worry too much about the note +being a little off; remember that the 14-sample period was just +eyeballed and is unlikely to be exactly right.)

+ +

Four octaves above middle C is really high! That would be a +shrill-sounding note. But remember that a complex waveform is the sum of +multiple sine waves at different frequency. Hereā€™s a different +up-and-down regularity:

+ +

{width=ā€2.795138888888889inā€ +height=ā€1.2222222222222223inā€}{width=ā€2.7847222222222223inā€ +height=ā€1.0486111111111112inā€}Itā€™s not obvious, but in the left part of +the graph, the signal is more above the x axis than below it. Toward +the right, it seems to be more below than above the axis. At the very +right it looks like it might be climbing again.

+ +

The period of the red sine wave is 340 samples, or 340/48000 second. +Thatā€™s a frequency of about 141 Hz, about D below middle C. Again, this +is measuring by eyeball, but likely to be close to the right frequency.

+ +

All this eyeballing doesnā€™t seem very scientific. Canā€™t we just get the +computer to find all the relevant frequencies? Yes, we can, using a +mathematical technique called Fourier analysis. (Jean-Baptiste Joseph +Fourier, 1768ā€“1830, made many contributions to mathematics and physics, +but is best known for working out the nature of periodic functions as a +sum of sine waves.) Luckily we donā€™t have to do the math; the microphone +block will do it for us, if we ask for microphone spectrum:

+ +

{width=ā€7.493055555555555inā€ +height=ā€1.4861111111111112inā€}These are frequency spectra from (samples +of) three different songs. The most obvious thing about these graphs is +that their overall slope is downward; the loudest frequency is the +lowest frequency. Thatā€™s typical of music.

+ +

The next thing to notice is that thereā€™s a regularity in the spacing of +spikes in the graph. This is partly just an artifact; the frequency +(horizontal) axis isnā€™t continuous. There are a finite number of +ā€œbucketsā€ (default: 512), and all the frequencies within a bucket +contribute to the amplitude (vertical axis) of that bucket. The spectrum +is a list of that many amplitudes. But the patterns of alternating +rising and falling values are real; the frequencies that are multiples +of the main note being sampled will have higher amplitude than other +frequencies.

+ +

Samples and spectrum are the two most detailed representations of a +sound. But the microphone block has other, simpler options also:

+ +

volume the instantaneous volume when the block is called

+ +

note the MIDI note number (as in play note) of the main note heard

+ +

frequency the frequency in Hz of the main note heard

+ +

sample rate the number of samples being collected per second

+ +

{width=ā€2.9166666666666665inā€ +height=ā€0.28125inā€}resolution the size of the array in which data are +collected (typically 512, must be a power of 2)

+ +

The block for sounds that corresponds to new picture for pictures is

+ +

Its first input is a list of samples, and its second input specifies how +many samples occupy one second.

+ +

OOP with Procedures

+ +

The idea of object oriented programming is often taught in a way that +makes it seem as if a special object oriented programming language is +necessary. In fact, any language with ļ¬rst class procedures and lexical +scope allows objects to be implemented explicitly; this is a useful +exercise to help demystify objects.

+ +

The central idea of this implementation is that an object is represented +as a dispatch procedure that takes a message as input and reports the +corresponding method. In this section we start with a stripped-down +example to show how local state works, and build up to full +implementations of class/instance and prototyping OOP.

+ +

Local State with Script Variables

+ +

{width=ā€3.473611111111111inā€ +height=ā€3.1805555555555554inā€}{width=ā€2.2395833333333335inā€ +height=ā€1.5104166666666667inā€}This script implements an object class, +a type of object, namely the counter class. In this ļ¬rst simplified +version there is only one method, so no explicit message passing is +necessary. When the make a counter block is called, it reports a +procedure, the ringed script inside its body. That procedure implements +a specific counter object, an instance of the counter class. When +invoked, a counter instance increases and reports its count variable. +Each counter has its own local count:

+ +

This example will repay careful study, because it isnā€™t obvious why each +instance has a separate count. From the point of view of the make a +counter procedure, each invocation causes a new count variable to be +created. Usually such script variables are temporary, going out of +existence when the script ends. But this one is special, because make a +counter returns another script that makes reference to the count +variable, so it remains active. (The script variables block makes +variables local to a script. It can be used in a spriteā€™s script area or +in the Block Editor. Script variables can be ā€œexportedā€ by being used in +a reported procedure, as here.)

+ +

In this approach to OOP, we are representing both classes and instances +as procedures. The make a counter block represents the class, while each +instance is represented by a nameless script created each time make a +counter is called. The script variables created inside the make a +counter block but outside the ring are instance variables, belonging +to a particular counter.

+ +

Messages and Dispatch Procedures

+ +

{width=ā€4.416666666666667inā€ +height=ā€3.1666666666666665inā€}In the simplified class above, there is +only one method, and so there are no messages; you just call the +instance to carry out its one method. Here is a more refined version +that uses message passing:

+ +

Again, the make a counter block represents the counter class, and again +the script creates a local variable count each time it is invoked. The +large outer ring represents an instance. It is a dispatch procedure: +it takes a message (just a text word) as input, and it reports a method. +The two smaller rings are the methods. The top one is the next method; +the bottom one is the reset method. The latter requires an input, named +value.

+ +

In the earlier version, calling the instance did the entire job. In this +version, calling the instance gives access to a method, which must then +be called to finish the job. We can provide a block to do both procedure +calls in one:

+ +

{width=ā€4.010416666666667inā€ +height=ā€0.7077198162729659inā€}

+ +

The ask block has two required inputs: an object and a message. It also +accepts optional additional inputs, which Snap! puts in a list; that +list is named args inside the block. Ask has two nested call blocks. The +inner one calls the object, i.e., the dispatch procedure. The dispatch +procedure always takes exactly one input, namely the message. It reports +a method, which may take any number of inputs; note that this is the +situation in which we drop a list of values onto the arrowheads of a +multiple input (in the outer call block). Note also that this is one of +the rare cases in which we must unringify the inner call block, whose +value when called gives the method.

+ +

{width=ā€3.9069444444444446inā€ +height=ā€1.6125inā€}

+ +

Inheritance via Delegation

+ +

So, our objects now have local state variables and message passing. What +about inheritance? We can provide that capability using the technique of +delegation. Each instance of the child class contains an instance of +the parent class, and simply passes on the messages it doesnā€™t want to +specialize:

+ +

{width=ā€3.8125inā€ +height=ā€3.5833333333333335inā€}

+ +

This script implements the buzzer class, which is a child of counter. +Instead of having a count (a number) as a local state variable, each +buzzer has a counter (an object) as a local state variable. The class +specializes the next method, reporting what the counter reports unless +that result is divisible by 7, in which case it reports ā€œbuzz.ā€ (Yeah, +it should also check for a digit 7 in the number, but this code is +complicated enough already.) If the message is anything other than next, +though, such as reset, then the buzzer simply invokes its counterā€™s +dispatch procedure. So the counter handles any message that the buzzer +doesnā€™t handle explicitly. (Note that in the non-next case we call the +counter, not ask it something, because we want to report a method, not +the value that the message reports.) So, if we ask a buzzer to reset to +a value divisible by 7, it will end up reporting that number, not +ā€œbuzz.ā€

+ +

An Implementation of Prototyping OOP

+ +

In the class/instance system above, it is necessary to design the +complete behavior of a class before you can make any instances of the +class. This is okay for top-down design, but not great for +experimentation. Here we sketch the implementation of a prototyping +OOP system: You make an object, tinker with it, make clones of it, and +keep tinkering. Any changes you make in the parent are inherited by its +children. In effect, that first object is both the class and an instance +of the class. In the implementation below, children share properties +(methods and local variables) of their parent unless and until a child +changes a property, at which point that child gets a private copy. (If a +child wants to change something for its entire family, it must ask the +parent to do it.)

+ +

Because we want to be able to create and delete properties dynamically, +we wonā€™t use Snap! variables to hold an objectā€™s variables or methods. +Instead, each object has two tables, called methods and data, each of +which is an association list: a list of two-item lists, in which each +of the latter contains a key and a corresponding value. We provide a +lookup procedure to locate the key-value pair corresponding to a given +key in a given table.

+ +

{width=ā€3.2152777777777777inā€ +height=ā€2.361111111111111inā€}

+ +

{width=ā€2.625inā€ +height=ā€0.78125inā€}

+ +

{width=ā€5.604166666666667inā€ +height=ā€1.15625inā€}{width=ā€5.604166666666667inā€ +height=ā€1.15625inā€}

+ +

There are also commands to insert and delete entries:

+ +

{width=ā€3.71875inā€ +height=ā€1.8263888888888888inā€}{width=ā€3.2291666666666665inā€ +height=ā€2.1283136482939633inā€}

+ +

As in the class/instance version, an object is represented as a dispatch +procedure that takes a message as its input and reports the +corresponding method. When an object gets a message, it will ļ¬rst look +for that keyword in its methods table. If itā€™s found, the corresponding +value is the method we want. If not, the object looks in its data table. +If a value is found there, what the object returns is not that value, +but rather a reporter method that, when called, will report the value. +This means that what an object returns is always a method.

+ +

If the object has neither a method nor a datum with the desired name, +but it does have a parent, then the parent (that is, the parentā€™s +dispatch procedure) is invoked with the message as its input. +Eventually, either a match is found, or an object with no parent is +found; the latter case is an error, meaning that the user has sent the +object a message not in its repertoire.

+ +

Messages can take any number of inputs, as in the class/instance system, +but in the prototyping version, every method automatically gets the +object to which the message was originally sent as an extra ļ¬rst input. +We must do this so that if a method is found in the parent (or +grandparent, etc.) of the original recipient, and that method refers to +a variable or method, it will use the childā€™s variable or method if the +child has its own version.

+ +

{width=ā€4.375inā€ +height=ā€7.469444444444444inā€}The clone of block below takes an object as +its input and makes a child object. It should be considered as an +internal part of the implementation; the preferred way to make a child +of an object is to send that object a clone message.

+ +

{width=ā€1.5729166666666667inā€ +height=ā€0.6875inā€}Every object is created with predefined methods for +set, method, delete-var, delete-method, and clone. It has one predefined +variable, parent. Objects without a parent are created by calling new +object:

+ +

As before, we provide procedures to call an objectā€™s dispatch procedure +and then call the method. But in this version, we provide the desired +object as the ļ¬rst method input. We provide one procedure for Command +methods and one for Reporter methods:

+ +

{width=ā€6.938888888888889inā€ +height=ā€1.0inā€}(Remember that the ā€œInput list:ā€ variant of the run and +call blocks is made by dragging the input expression over the arrowheads +rather than over the input slot.)

+ +

The script below demonstrates how this prototyping system can be used to +make counters. We start with one prototype counter, called counter1. We +count this counter up a few times, then create a child counter2 and give +it its own count variable, but not its own total variable. The next +method always sets counter1ā€™s total variable, which therefore keeps +count of the total number of times that any counter is incremented. +Running this script should [say] and (think) the following lists:

+ +

{width=ā€4.208333333333333inā€ +height=ā€4.395833333333333inā€}[1 1] [2 2] [3 3] [4 4] (1 5) (2 6) +(3 7) [5 8] [6 9] [7 10] [8 11]

+ +

The Outside World

+ +

{width=ā€1.6201388888888888inā€ +height=ā€0.25inā€}The facilities discussed so far are fine for projects +that take place entirely on your computerā€™s screen. But you may want to +write programs that interact with physical devices (sensors or robots) +or with the World Wide Web. For these purposes Snap! provides a single +primitive block:

+ +

This might not seem like enough, but in fact it can be used to build the +desired capabilities.

+ +

The World Wide Web

+ +

The input to the url block is the URL (Uniform Resource Locator) of a +web page. The block reports the body of the Web serverā€™s response (minus +HTTP header), without interpretation. This means that in most cases +the response is a description of the page in HTML (HyperText Markup +Language) notation. Often, especially for commercial web sites, the +actual information youā€™re trying to find on the page is actually at +another URL included in the reported HTML. The Web page is typically a +very long text string, and so the primitive split block is useful to get +the text in a manageable form, namely, as a list of lines:

+ +

{width=ā€6.520833333333333inā€ +height=ā€4.277777777777778inā€}

+ +

The second input to split is the character to be used to separate the +text string into a list of lines, or one of a set of common cases (such +as line, which separates on carriage return and/or newline characters.

+ +

This might be a good place for a reminder that list-view watchers scroll +through only 100 items at a time. The downarrow near the bottom right +corner of the speech balloon in the picture presents a menu of +hundred-item ranges. (This may seem unnecessary, since the scroll bar +should allow for any number of items, but doing it this way makes +Snap! much faster.) In table view, the entire list is included.

+ +

If you include a protocol name in the input to the url block (such as +http:// or https://), that protocol will be used. If not, the block +first tries HTTPS and then, if that fails, HTTP.

+ +

A security restriction in JavaScript limits the ability of one web site +to initiate communication with another site. There is an official +workaround for this limitation called the CORS protocol (Cross-Origin +Resource Sharing), but the target site has to allow snap.berkeley.edu +explicitly, and of course most donā€™t. To get around this problem, you +can use third-party sites (ā€œcors proxiesā€) that are not limited by +JavaScript and that forward your requests.

+ +

Hardware Devices

+ +

Another JavaScript security restriction prevents Snap! from having +direct access to devices connected to your computer, such as sensors and +robots. (Mobile devices such as smartphones may also have useful devices +built in, such as accelerometers and GPS receivers.) The url block is +also used to interface Snap! with these external capabilities.

+ +

The idea is that you run a separate program that both interfaces with +the device and provides a local HTTP server that Snap! can use to make +requests to the device. Unlike Snap! itself, these programs have +access to anything on your computer, so you have to trust the author of +the software! Our web site, snap.berkeley.edu, provides links to +drivers for several devices, including, at this writing, the Lego NXT, +Finch, Hummingbird, and Parallax S2 robots; the Nintendo Wiimote and +Leap Motion sensors, the Arduino microcomputer, and Super-Awesome +Sylviaā€™s Water Color Bot. The same server technique can be used for +access to third party software libraries, such as the speech synthesis +package linked on our web site.

+ +

Most of these packages require some expertise to install; the links are +to source code repositories. This situation will improve with time.

+ +

Date and Time

+ +

{width=ā€5.305555555555555inā€ +height=ā€0.3194444444444444inā€}The current block in the Sensing palette +can be used to find out the current date or time. Each call to this +block reports one component of the date or time, so you will probably +combine several calls, like this:

+ +

{width=ā€5.305555555555555inā€ +height=ā€0.3194444444444444inā€}for Americans, or like this:

+ +

for Europeans.

+ +

Continuations

+ +

Blocks are usually used within a script. The continuation of a block +within a particular script is the part of the computation that remains +to be completed after the block does its job. A continuation can be +represented as a ringed script. Continuations are always part of the +interpretation of any program in any language, but usually these +continuations are implicit in the data structures of the language +interpreter or compiler. Making continuations explicit is an advanced +but versatile programming technique that allows users to create control +structures such as nonlocal exit and multithreading.

+ +

{width=ā€1.40625inā€ +height=ā€1.5416666666666667inā€}In the simplest case, the continuation of +a command block may just be the part of the script after the block. For +example, in the script

+ +

{width=ā€1.59375inā€ +height=ā€0.7083333333333334inā€}the continuation of the move 100 steps +block is

+ +

{width=ā€1.4784722222222222inā€ +height=ā€0.8020833333333334inā€}But some situations are more complicated. +For example, what is the continuation of move 100 steps in the following +script?

+ +

{width=ā€1.6666666666666667inā€ +height=ā€1.0729166666666667inā€}Thatā€™s a trick question; the move block is +run four times, and it has a different continuation each time. The first +time, its continuation is

+ +

Note that there is no repeat 3 block in the actual script, but the +continuation has to represent the fact that there are three more times +through the loop to go. The fourth time, the continuation is just

+ +

{width=ā€1.59375inā€ +height=ā€0.29791666666666666inā€}What counts is not whatā€™s physically +below the block in the script, but what computational work remains to be +done.

+ +

(This is a situation in which visible code may be a little misleading. +We have to put a repeat 3 block in the picture of the continuation, +but the actual continuation is made from the evaluatorā€™s internal +bookkeeping of where itā€™s up to in a script. So itā€™s really the original +script plus some extra information. But the pictures here do correctly +represent what work the process still has left to do.)
+{width=ā€1.4791666666666667inā€ +height=ā€1.25inā€}When a block is used inside a custom block, its +continuation may include parts of more than one script. For example, if +we make a custom square block

+ +

and then use that block in a script:

+ +

{width=ā€0.7291666666666666inā€ +height=ā€0.59375inā€}then the continuation of the first use of move 100 +steps is

+ +

{width=ā€1.6666666666666667inā€ +height=ā€1.2604166666666667inā€}in which part comes from inside the square +block and part comes from the call to square. Nevertheless, ordinarily +when we display a continuation we show only the part within the +current script.

+ +

{width=ā€2.1875inā€ +height=ā€0.5729166666666666inā€}The continuation of a command block, as +weā€™ve seen, is a simple script with no input slots. But the continuation +of a reporter block has to do something with the value reported by the +block, so it takes that value as input. For example, in the script

+ +

the continuation of the 3+4 block is

+ +

{width=ā€3.5729166666666665inā€ +height=ā€0.5729166666666666inā€}Of course the name result in that picture +is arbitrary; any name could be used, or no name at all by using the +empty-slot notation for input substitution.

+ +

Continuation Passing Style

+ +

Like all programming languages, Snap! evaluates compositions of nested +reporters from the inside out. For example, in the expression +{width=ā€1.3125inā€ +height=ā€0.22916666666666666inā€}Snap! first adds 4 and 5, then +multiplies 3 by that sum. This often means that the order in which the +operations are done is backwards from the order in which they appear in +the expression: When reading the above expression you say ā€œtimesā€ before +you say ā€œplus.ā€ In English, instead of saying ā€œthree times four plus +five,ā€ which actually makes the order of operations ambiguous, you could +say, ā€œtake the sum of four and five, and then take the product of three +and that sum.ā€ This sounds more awkward, but it has the virtue of +putting the operations in the order in which theyā€™re actually performed.

+ +

{width=ā€3.1875inā€ +height=ā€0.3541666666666667inā€}That may seem like overkill in a simple +expression, but suppose youā€™re trying to convey the expression

+ +

to a friend over the phone. If you say ā€œfactorial of three times +factorial of two plus two plus fiveā€ you might mean any of these:

+ +

{width=ā€3.1875inā€ +height=ā€1.71875inā€}{width=ā€7.490277777777778inā€ +height=ā€3.622916666666667inā€}Wouldnā€™t it be better to say, ā€œAdd two and +two, take the factorial of that, add five to that, multiply three by +that, and take the factorial of the resultā€? We can do a similar +reordering of an expression if we first define versions of all the +reporters that take their continuation as an explicit input. In the +following picture, notice that the new blocks are commands, not +reporters.

+ +

{width=ā€4.052777777777778inā€ +height=ā€1.6354166666666667inā€}We can check that these blocks give the +results we want:

+ +

{width=ā€5.533333333333333inā€ +height=ā€2.3180555555555555inā€}The original expression can now be +represented as

+ +

{width=ā€2.1930555555555555inā€ +height=ā€1.0527777777777778inā€}If you read this top to bottom, donā€™t you +get ā€œAdd two and two, take the factorial of that, add five to that, +multiply three by that, and take the factorial of the resultā€? Just what +we wanted! This way of working, in which every block is a command that +takes a continuation as one of its inputs, is called +continuation-passing style (CPS). Okay, it looks horrible, but it has +subtle virtues. One of them is that each script is just one block long +(with the rest of the work buried in the continuation given to that one +block), so each block doesnā€™t have to remember what else to doā€”in the +vocabulary of this section, the (implicit) continuation of each block is +empty. Instead of the usual picture of recursion, with a bunch of little +people all waiting for each other, with CPS what happens is that each +little person hands off the problem to the next one and goes to the +beach, so thereā€™s only one active little person at a time. In this +example, we start with Alfred, an add specialist, who computes the value +4 and then hands off the rest of the problem to Francine, a factorial +specialist. She computes the value 24, then hands the problem off to +Anne, another add specialist, who computes 29. And so on, until finally +Sam, a say specialist, says the value 2.107757298379527Ɨ10^132^, which +is a very large number!

+ +

Go back to the definitions of these blocks. The ones, such as add, that +correspond to primitive reporters are simple; they just call the +reporter and then call their continuation with its result. But the +definition of factorial is more interesting. It doesnā€™t just call our +original factorial reporter and send the result to its continuation. CPS +is used inside factorial too! It says, ā€œSee if my input is zero. Send +the (true or false) result to if. If the result is true, then call my +continuation with the value 1. Otherwise, subtract 1 from my input. Send +the result of that to factorial, with a continuation that multiplies the +smaller numberā€™s factorial by my original input. Finally, call my +continuation with the product.ā€ You can use CPS to unwind even the most +complicated branched recursions.

+ +

By the way, I cheated a bit above. The if/else block should also use +CPS; it should take one true/false input and two continuations. It +will go to one or the other continuation depending on the value of its +input. But in fact the C-shaped blocks (or E-shaped, like if/else) are +really using CPS in the first place, because they implicitly wrap rings +around the sub-scripts within their branches. See if you can make an +explicitly CPS if/else block.

+ +

Call/Run w/Continuation

+ +

To use explicit continuation passing style, we had to define special +versions of all the reporters, add and so on. Snap! provides a +primitive mechanism for capturing continuations when we need to, without +using continuation passing throughout a project.

+ +

Hereā€™s the classic example. We want to write a recursive block that +takes a list of numbers as input, and reports the product of all the +numbers:

+ +

{width=ā€3.8958333333333335inā€ +height=ā€1.9375inā€}{width=ā€3.8958333333333335inā€ +height=ā€1.3416666666666666inā€}But we can improve the efficiency of this +block, in the case of a list that includes a zero; as soon as we see the +zero, we know that the entire product is zero.

+ +

But this is not as efficient as it might seem. Consider, as an example, +the list 1,2,3,0,4,5. We find the zero on the third recursive call (the +fourth call altogether), as the first item of the sublist 0,4,5. What is +the continuation of the report 0 block? Itā€™s

+ +

{width=ā€4.333333333333333inā€ +height=ā€0.4166666666666667inā€}Even though we already know that result is +zero, weā€™re going to do three unnecessary multiplications while +unwinding the recursive calls.

+ +

{width=ā€4.038194444444445inā€ +height=ā€1.9256944444444444inā€}{width=ā€3.9451388888888888inā€ +height=ā€1.0979166666666667inā€}We can improve upon this by capturing the +continuation of the top-level call to product:

+ +

{width=ā€2.7083333333333335inā€ +height=ā€0.2916666666666667inā€}The +{width=ā€1.59125inā€ +height=ā€0.18611111111111112inā€} block takes as its input a one-input +script, as shown in the product example. It calls that script with the +continuation of the call-with-continuation block itself as its input. +In this case, that continuation is

+ +

{width=ā€4.40625inā€ +height=ā€1.15625inā€}reporting to whichever script called product. If the +input list doesnā€™t include a zero, then nothing is ever done with that +continuation, and this version works just like the original product. But +if the input list is 1,2,3,0,4,5, then three recursive calls are made, +the zero is seen, and product-helper runs the continuation, with an +input of 0. The continuation immediately reports that 0 to the caller of +product, without unwinding all the recursive calls and without the +unnecessary multiplications.

+ +

{width=ā€4.385416666666667inā€ +height=ā€0.5104166666666666inā€}I could have written product a little more +simply using a Reporter ring instead of a Command ring:

+ +

but itā€™s customary to use a script to represent the input to +callĀ w/continuation because very often that input takes the form

+ +

so that the continuation is saved permanently and can be called from +anywhere in the project. Thatā€™s why the input slot in call +w/continuation has a Command ring rather than a Reporter ring.

+ +

First class continuations are an experimental feature in Snap! and +there are many known limitations in it. One is that the display of +reporter continuations shows only the single block in which the call +w/continuation is an input.

+ +

Nonlocal exit

+ +

{width=ā€6.268055555555556inā€ +height=ā€1.125inā€}Many programming languages have a break command that +can be used inside a looping construct such as repeat to end the +repetition early. Using first class continuations, we can generalize +this mechanism to allow nonlocal exit even within a block called from +inside a loop, or through several levels of nested loops:

+ +

{width=ā€1.8541666666666667inā€ +height=ā€2.6534722222222222inā€}The upvar break has as its value a +continuation that can be called from anywhere in the program to jump +immediately to whatever comes after the catch block in its script. +Hereā€™s an example with two nested invocations of catch, with the upvar +renamed in the outer one:

+ +

As shown, this will say 1, then 2, then 3, then exit both nested catches +and think ā€œHmm.ā€ If in the run block the variable break is used instead +of outer, then the script will say 1, 2, 3, and ā€œHello!ā€ before thinking +ā€œHmm.ā€

+ +

{width=ā€4.354166666666667inā€ +height=ā€1.4708333333333334inā€}There are corresponding catch and throw +blocks for reporters. The catch block is a reporter that takes an +expression as input instead of a C-shaped slot. But the throw block is a +command; it doesnā€™t report a value to its own continuation, but instead +reports a value (which it takes as an additional input, in addition to +the catch tag) to the corresponding catch blockā€™s continuation:

+ +

Without the throw, the inner call reports 5, the + block reports 8, so +the catch block reports 8, and the Ɨ block reports 80. With the throw, +the inner call doesnā€™t report at all, and neither does the + block. The +throw blockā€™s input of 20 becomes the value reported by the catch block, +and the Ɨ block multiplies 10 and 20.
+Creating a Thread System

+ +

Snap! can be running several scripts at once, within a single sprite +and across many sprites. If you only have one computer, how can it do +many things at once? The answer is that only one is actually running at +any moment, but Snap! switches its attention from one script to +another frequently. At the bottom of every looping block (repeat, repeat +until, forever), there is an implicit ā€œyieldā€ command, which remembers +where the current script is up to, and switches to some other script, +each in turn. At the end of every script is an implicit ā€œend threadā€ +command (a thread is the technical term for the process of running a +script), which switches to another script without remembering the old +one.

+ +

{width=ā€2.9479166666666665inā€ +height=ā€4.254166666666666inā€}{width=ā€6.5569444444444445inā€ +height=ā€2.770138888888889inā€}Since this all happens automatically, there +is generally no need for the user to think about threads. But, just to +show that this, too, is not magic, here is an implementation of a simple +thread system. It uses a global variable named tasks that initially +contains an empty list. Each use of the C-shaped thread block adds a +continuation (the ringed script) to the list. The yield block uses run +w/continuation to create a continuation for a partly done thread, adds +it to the task list, and then runs the first waiting task. The +endĀ thread block (which is automatically added at the end of every +threadā€™s script by the thread block) just runs the next waiting task.

+ +

Here is a sample script using the thread system. One thread says +numbers; the other says letters. The number thread yields after every +prime number, while the letter thread yields after every vowel. So the +sequence of speech balloons is +1,2,a,3,b,c,d,e,4,5,f,g,h,i,6,7,j,k,l,m,n,o,8,9,10,11, +p,q,r,s,t,u,12,13,v,w,x,y,z,14,15,16,17,18,ā€¦30.

+ +

If we wanted this to behave exactly like Snap!ā€™s own threads, weā€™d +define new versions of repeat and so on that run yield after each +repetition.

+ +

Metaprogramming

+ +

The scripts and custom blocks that make up a program can be examined or +created by the program itself.

+ +

{width=ā€7.4945702099737534inā€ height=ā€2.0380686789151357inā€}Reading a block

+ +

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.

+ +

{width=ā€7.4inā€ +height=ā€2.51inā€}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.

+ +

{width=ā€7.496969597550306inā€ +height=ā€2.079861111111111inā€}Using split by blocks to select custom +blocks whose definitions contain another block gives us this debugging +aid:

+ +

Note in passing the my blocks block, which reports a list of all visible +blocks, primitive and custom. (Thereā€™s also a my categories block, which +reports a list of the names of the palette categories.) Also note +custom? of block, which reports True if its input is a custom block.

+ +

Writing a block

+ +

{width=ā€6.071211723534558inā€ +height=ā€2.209722222222222inā€}The inverse function to split by blocks is +provided by the join block, which when given a syntax tree as input +reports the corresponding expression or script.

+ +

Here we are taking the definition of square, modifying the repetition +count (to 6), modifying the turning angle (to 60), using join to turn +the result back into a ringed definition, and using the define block to +create a new hexagon block.

+ +

The define block has three ā€œinputā€ slots. The quotation marks are there +because the first slot is an upvar, i.e., a way for define to provide +information to its caller, rather than the other way around. In this +case, the value of block is the new block itself (the hexagon block, in +this example). The second slot is where you give the label for the new +block. In this example, the label is ā€œhexagon _ā€ in which the +underscore represents an input slot. So, here are a few examples of +block labels:

+ +

set pen _ to _

+ +

for _ = _ to _ _

+ +

ask _ and wait

+ +

_ of _

+ +

Note that the underscores are separated from the block text by spaces. +Note in the case of the for blockā€™s label that the upvar (the i) and the +C-slot both count as inputs. Note also that the label is not meant to be +a unique symbol that represents only this block. For example, +{width=ā€0.8611111111111112inā€ +height=ā€0.19444444444444445inā€} and A picture containing text, hitting
+Description automatically
+generated{width=ā€1.15inā€ +height=ā€0.19inā€} both have the label

+ +

_ of _. The label does not give the input slots names (thatā€™s done in +the body, coming next) or types (thatā€™s done in the set _ of block _ +to _ block, coming in two paragraphs).

+ +

The third slot is for the definition of the new block. This is a +(ringed) script whose input names (formal parameters) will become the +formal parameters of the new block. And the script is its script.

+ +

So far we know the blockā€™s label, parameters, and script. There are +other things to specify about the block, and one purpose of the block +upvar is to allow that. In the example on the previous page, there are +four

+ +

{width=ā€2.83inā€ +height=ā€0.97inā€}set _ of block _ to _ blocks, reproduced below for +your convenience:

+ +

The category of the block can be set to any primitive or custom +category. The default is other. The type is command, reporter, or +predicate. Command is the default, so this setting is redundant, but we +want to show all the choices in the set block. The scope is either +global or sprite, with global as the default. The last input to set +slots is a list of length less than or equal to the number of +underscores in the label. Each item of the list is a type name, like the +ones in the is (5) a (number)? block. If there is only one input, you +can use just the name instead of putting it in a list. An empty or +missing list item means type Any.

+ +

{width=ā€4.31inā€ +height=ā€0.83inā€}It's very important that these set blocks appear in the +same script as the define that creates the block, because the block +upvar is local to that script. You canā€™t later say, for example,

+ +

because the copy of the hexagon block in this instruction counts as +ā€œusingā€ it.

+ +

{width=ā€2.6inā€ +height=ā€0.32inā€}The of block reporter is useful to copy attributes from +one block to another, as we copied the definition of square, modified +it, and used it to define hexagon. Some of the values this block reports +are a little unfriendly:

+ +

ā€œ1ā€? Yes, this block reports numbers instead of names for category, +type, and scope. The reason is that maybe someday weā€™ll have +translations to other languages for custom category names, as we already +do for the built-in categories, types, and scopes; if you translate a +program using this block to another language, the numeric outputs wonā€™t +change, simplifying comparisons in your code. The set block accepts +these numbers as an alternative to the names.

+ +

{width=ā€3.379861111111111inā€ +height=ā€0.3798611111111111inā€}{width=ā€1.02inā€ +height=ā€0.25inā€}There are a few more attributes of a block, less +commonly used.

+ +

{width=ā€3.5194444444444444inā€ +height=ā€0.6194444444444445inā€}{width=ā€1.9314370078740157inā€ +height=ā€0.6102252843394576inā€}{width=ā€3.2909722222222224inā€ +height=ā€0.6097222222222223inā€}{width=ā€2.35inā€ +height=ā€2.56inā€}{width=ā€1.6694444444444445inā€ +height=ā€0.25inā€}The list input is just like the one for set slots except +for default values instead of types. Now for a block with a menu input:

+ +

{width=ā€4.169444444444444inā€ +height=ā€1.2694444444444444inā€}We passed too quickly over how the script +turned the square block into a hexagon block:

+ +

{width=ā€6.677272528433946inā€ +height=ā€3.6666666666666665inā€}Those replace item blocks arenā€™t very +elegant. I had to look at foo by hand to figure out where the numbers I +wanted to change are. This situation can be improved with a little +programming:

+ +

Exercise for the reader: Implement this:Graphical user interface
+Description automatically
+generated{width=ā€3.11inā€ +height=ā€0.57inā€}

+ +

{width=ā€7.501514654418198inā€ +height=ā€2.109722222222222inā€}Returning to the define block, thereā€™s +another reason for the block upvar: Itā€™s helpful in defining a recursive +procedure using define. For a procedure to call itself, it needs a name +for itself. But in the definition input to the define block, define +itself hasnā€™t been called yet, so the new block isnā€™t in the palette +yet. So you do this:

+ +

Yes, you put block in the define, but it gets changed into this script +in the resulting definition. You could use this script directly in a +simple case like this, but in a complicated case with a recursive call +inside a ring inside the one giving the block definition, this script +always means the innermost ring. But the upvar means the outer +{width=ā€7.5inā€ +height=ā€0.5354166666666667inā€}{width=ā€4.809722222222222inā€ +height=ā€0.4inā€}{width=ā€4.809722222222222inā€ +height=ā€1.4895833333333333inā€}ring:

+ +

Itā€™s analogous to using explicit formal parameters when you nest calls +to higher order functions.

+ +

{width=ā€5.76875inā€ height=ā€3.879861111111111inā€}Macros

+ +

Users of languages in the C family have learned to think of macros as +entirely about text strings, with no relation to the syntax of the +language. So you can do things like

+ +

#define foo baz)

+ +

with the result that you can only use the foo macro after an open +parenthesis.

+ +

In the Lisp family of languages we have a different tradition, in which +macros are syntactically just like procedure calls, except that the +ā€œprocedureā€ is a macro, with different evaluation rules from ordinary +procedures. Two things make a macro different: its input expressions are +not evaluated, so a macro can establish its own syntax (but still +delimited by parentheses, in Lisp, or still one block, in Snap! ); and +the result of a macro call is a new expression that is evaluated as if +it appeared in the caller of the macro, with access to the callerā€™s +variables and, implicitly, its continuation.

+ +

Snap! has long had the first part of this, the ability to make inputs +unevaluated. In version 8.0 we add the ability to run code in the +context of another procedure, just as we can run code in the context of +another sprite, using the same mechanism: the of block. In the example +on the previous page, the if _ report _ caller block runs a report +block, but not in its own context; it causes the fizzbuzz block to +report ā€œfizzā€ or ā€œbuzzā€ as appropriate. (Yes, we know that the rules +implemented here are simplified compared to the real game.) It doesnā€™t +just report out of the entire toplevel script; you can see that map is +able to prepend ā€œThe answer isā€ to each reported value.

+ +

This macro capability isnā€™t fully implemented. First, we shouldnā€™t have +to use the calling script as an explicit input to the macro. In a later +release, this will be fixed; when defining a block youā€™ll be able to say +that itā€™s a macro, and it will automatically get its callerā€™s context as +an invisible input. Second, there is a possibility of confusion between +the variables of the macro and the variables of its caller. (What if the +macro wanted to refer to a variable value in its caller?) The one +substantial feature of Scheme that we donā€™t yet implement is hygienic +macros, which make it possible to keep the two namespaces separate.

+ +

User Interface Elements

+ +

In this chapter we describe in detail the various buttons, menus, and +other clickable elements of the Snap! user interface. Here again is +the map of the Snap! window:

+ +

{width=ā€7.494419291338582inā€ +height=ā€4.663194444444445inā€}

+ +

Tool Bar Features

+ +

Holding down the Shift key while clicking on any of the menu buttons +gives access to an extended menu with options, shown in red, that are +experimental or for use by the developers. Weā€™re not listing those extra +options here because they change frequently and you shouldnā€™t rely on +them. But theyā€™re not secrets.

+ +

The Snap! Logo Menu

+ +

The Snap! logo at the left end of the tool bar is clickable. It shows +a menu of options about Snap! itself:

+ +

{width=ā€2.3292213473315835inā€ +height=ā€1.02inā€}

+ +

The About option displays information about Snap! itself, including +version numbers for the source modules, the implementors, and the +license (AGPL: you can do anything with it except create proprietary +versions, basically).

+ +

The Reference manual option downloads a copy of the latest revision of +this manual in PDF format.

+ +

The Snap! website option opens a browser window pointing to +snap.berkeley.edu, the web site for Snap!.

+ +

The Download source option opens a browser window displaying the Github +repository of the source files for Snap!. At the bottom of the page +are links to download the latest official release. Or you can navigate +around the site to find the current development version. You can read +the code to learn how Snap! is implemented, host a copy on your own +computer (this is one way to keep working while on an airplane), or make +a modified version with customized features. (However, access to cloud +accounts is limited to the official version hosted at Berkeley.)

+ +

The File Menu

+ +

{width=ā€0.3194444444444444inā€ +height=ā€0.18055555555555555inā€}The file icon shows a menu mostly about +saving and loading projects. You may not see all these options, if you +donā€™t have multiple sprites, scenes, custom blocks, and custom +categories.

+ +

The Notes option opens a window in which you can type notes about the +project: How to use it, what it does, whose project you modified to +create it, if any, what other sources of ideas you used, or any other +information about the project. This text is saved with the project, and +is useful if you share it with other users.

+ +

The New option starts a new, empty project. Any project you were working +on before disappears, so you are asked to confirm that this is really +what you want. (It disappears only from the current working Snap! +window; you should save the current project, if you want to keep it, +before using New.)

+ +

Note the \^N at the end of the line. This indicates that you can type +control-N as a shortcut for this menu item. Alas, this is not the case +in every browser. Some Mac browsers require command-N (āŒ˜N) instead, +while others open a new browser window instead of a new project. Youā€™ll +have to experiment. In general, the keyboard shortcuts in Snap! are +the standard ones you expect in other software.

+ +

{width=ā€2.8895833333333334inā€ +height=ā€2.097916666666667inā€}The Openā€¦ option shows a project open +dialog box in which you can choose a project to open:

+ +

In this dialog, the three large buttons at the left select a source of +projects: Cloud means your Snap! accountā€™s cloud storage. Examples +means a collection of sample projects we provide. Computer is for +projects saved on your own computer; when you click it, this dialog is +replaced with your computerā€™s system dialog for opening files. The text +box to the right of those buttons is an alphabetical listing of projects +from that source; selecting a project by clicking shows its thumbnail (a +picture of the stage when it was saved) and its project notes at the +right.

+ +

{width=ā€2.7243055555555555inā€ +height=ā€1.9777777777777779inā€}The search bar at the top can be used to +find a project by name or text in the project notes. So in this example:

+ +

{width=ā€2.723611111111111inā€ +height=ā€1.9777777777777779inā€}I was looking for my ice cream projects +and typed ā€œcreaā€ in the search bar, then wondered why ā€œferrisā€ matched. +But then when I clicked on ferris I saw this:

+ +

My search matched the word ā€œrecreateā€ in the project notes.

+ +

The six buttons at the bottom select an action to perform on the +selected project. In the top row, Recover looks in your cloud account +for older versions of the chosen project. If your project is damaged, +donā€™t keep saving broken versions! Use Recover first thing. You will +see a list of saved versions; choose one to open it. Typically, youā€™ll +see the most recent version before the last save, and the newest version +saved before today. Then come buttons Share/Unshare and +Publish/Unpublish. The labelling of the buttons depends on your +projectā€™s publication status. If a project is neither shared nor +published (the ones in lightface type in the project list), it is +private and nobody can see it except you, its owner. If it is shared +(boldface in the project list), then when you open it youā€™ll see a URL +like this one:

+ +

https://snap.berkeley.edu/snapsource/snap.html#present:Username=bh&ProjectName=count%20change

+ +

but with your username and project name. (ā€œ%20ā€ in the project name +represents a space, which canā€™t be part of a URL.) Anyone who knows this +URL can see your project. Finally, if your project is published +(bold italic in the list), then your project is shown on the +Snap! web site for all the world to see. (In all of these cases, you +are the only one who can write to (save) your project. If another user +saves it, a separate copy will be saved in that userā€™s account. Projects +remember the history of who created the original version and any other +ā€œremixā€ versions along the way.

+ +

In the second row, the first button, Open, loads the project into +Snap! and closes the dialog box. The next button (if Cloud is the +source) is Delete, and if clicked it deletes the selected project. +Finally, the Cancel button closes the dialog box without opening a +project. (It does not undo any sharing, unsharing, or deletion youā€™ve +done.)

+ +

Back to the File menu, the Save menu option saves the project to the +same source and same name that was used when opening the project. (If +you opened another userā€™s shared project or an example project, the +project will be saved to your own cloud account. You must be logged in +to save to the cloud.)

+ +

{width=ā€3.236111111111111inā€ +height=ā€2.3493055555555555inā€}The Save asā€¦ menu option opens a dialog +box in which you can specify where to save the project:

+ +

This is much like the Open dialog, except for the horizontal text box at +the top, into which you type a name for the project. You can also +publish, unpublish, share, unshare, and delete projects from here. There +is no Recover button.

+ +

The Importā€¦ menu option is for bringing some external resource into +the current project, or it can load an entirely separate project, from +your local disk. You can import costumes (any picture format that your +browser supports), sounds (again, any format supported by your browser), +and block libraries or sprites (XML format, previously exported from +Snap! itself). Imported costumes and sounds will belong to the +currently selected sprite; imported blocks are global (for all sprites). +Using the Import option is equivalent to dragging the file from your +desktop onto the Snap! window.

+ +

Depending on your browser, the Export projectā€¦ option either directly +saves to your disk or opens a new browser tab containing your complete +project in XML notation (a plain text format). You can then use the +browserā€™s Save feature to save the project as an XML file, which should +be named something.xml so that Snap! will recognize it as a project +when you later drag it onto a Snap! window. This is an alternative to +saving the project to your cloud account: keeping it on your own +computer. It is equivalent to choosing Computer from the Save dialog +described earlier.

+ +

The Export summaryā€¦ option creates a web page, in HTML, with all of +the information about your project: its name, its project notes, a +picture of whatā€™s on its stage, definitions of global blocks, and then +per-sprite information: name, wardrobe (list of costumes), and local +variables and block definitions. The page can be converted to PDF by the +browser; itā€™s intended to meet the documentation requirements of the +Advanced Placement Computer Science Principles create task.

+ +

The Export blocksā€¦ option is used to create a block library. It +presents a list of all the global (for all sprites) blocks in your +project, and lets you select which to export. It then opens a browser +tab with those blocks in XML format, or stores directly to your local +disk, as with the Export project option. Block libraries can be imported +with the Import option or by dragging the file onto the Snap! window. +This option is shown only if you have defined custom blocks.

+ +

The Unused blocksā€¦ option presents a listing of all the global custom +blocks in your project that arenā€™t used anywhere, and offers to delete +them. As with Export blocks, you can choose a subset to delete with +checkboxes. This option is shown only if you have defined custom blocks.

+ +

The Hide blocksā€¦ option shows all blocks, including primitives, with +checkboxes. This option does not remove any blocks from your project, +but it does hide selected block in your palette. The purpose of the +option is to allow teachers to present students with a simplified +Snap! with some features effectively removed. The hiddenness of +primitives is saved with each project, so students can load a shared +project and see just the desired blocks. But users can always unhide +blocks by choosing this option and unclicking all the checkboxes. +(Right-click in the background of the dialog box to get a menu from +which you can check all boxes or uncheck all boxes.)

+ +

The New categoryā€¦ option allows you to add your own categories to the +palette. It opens a dialog box in which you specify a name and a color +for the category. (A lighter version of the same color will be used for +the zebra coloring feature.)

+ +

The Remove a categoryā€¦ option appears only if youā€™ve created custom +categories. It opens a very small, easy-to-miss menu of category names +just under the file icon in the menu bar. If you remove a category that +has blocks in it, all those blocks are also removed.

+ +

{width=ā€1.1666666666666667inā€ +height=ā€0.19791666666666666inā€}The next group of options concern the +scenes feature, new in Snap! 7.0. A scene is a complete project, +with its own stage, sprites, and code, but several can be merged into +one project, using the block to bring another scene onscreen. The +Scenesā€¦ option presents a menu of all the scenes in your project, +where the File menu was before you clicked it. The New scene option +creates a new, empty scene, which you can rename as you like from its +context menu. Add sceneā€¦ is like Importā€¦ but for scenes. (A complete +project can be imported as a scene into another project, so you have to +specify that youā€™re importing the project as a scene rather than +replacing the current project.)

+ +

The Librariesā€¦ option presents a menu of useful, optional block +libraries:{width=ā€7.401388888888889inā€ +height=ā€3.238888888888889inā€}

+ +

When you click on the one-line description of a library, you are shown +the actual blocks in the library and a longer explanation of its +purpose. You can browse the libraries to find one that will satisfy your +needs. The libraries are described in detail in Section I.H, page 25.

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The Costumesā€¦ option opens a browser +into the costume library:

+ +

You can import a single costume by clicking it and then clicking the +Import button. Alternatively, you can import more than one costume by +double-clicking each one, and then clicking Cancel when done. Notice +that some costumes are tagged with ā€œsvgā€ in this picture; those are +vector-format costumes that are not (yet) editable within Snap!.

+ +

If you have the stage selected in the sprite corral, rather than a +sprite, the Costumesā€¦ option changes to a Backgroundsā€¦ option, with +different choices in the browser:

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The costume and background libraries +include both bitmap (go jagged if enlarged) and vector (enlarge +smoothly) images. Thanks to Scratch 2.0/3.0 for most of these images! +Some older browsers refuse to import a vector image, but instead convert +it to bitmap.

+ +

The Soundsā€¦ option opens the third kind of media browser:

+ +

{width=ā€4.28125inā€ +height=ā€3.2395833333333335inā€}The Play buttons can be used to preview +the sounds.

+ +

Finally, the Undelete spritesā€¦ option appears only if you have deleted +a sprite; it allows you to recover a sprite that was deleted by accident +(perhaps intending to delete only a costume).

+ +

The Cloud Menu

+ +

{width=ā€1.4368055555555554inā€ +height=ā€0.7597222222222222inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.6645833333333333inā€ +height=ā€0.1673611111111111inā€}The cloud icon shows a menu of options +relating to your Snap! cloud account. If you are not logged in, you +see the outline icon and get this menu:

+ +

Choose Loginā€¦ if you have a Snap! account and remember your +password. Choose Signupā€¦ if you donā€™t have an account. Choose Reset +Passwordā€¦ if youā€™ve forgotten your password or just want to change it. +You will then get an email, at the address you gave when you created +your account, with a new temporary password. Use that password to log +in, then you can choose your own password, as shown below. Choose Resend +Verification Emailā€¦ if you have just created a Snap! account but +canā€™t find the email we sent you with the link to verify that itā€™s +really your email. (If you still canā€™t find it, check your spam folder. +If you are using a school email address, your school may block incoming +email from outside the school.) The Open in Community Site option +appears only if you have a project open; it takes you to the community +site page about that project.

+ +

{width=ā€1.6111111111111112inā€ +height=ā€0.6527777777777778inā€}If you are already logged in, youā€™ll see +the solid icon +{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€} and get this menu:

+ +

Logout is obvious, but has the additional benefit of showing you whoā€™s +logged in. Change passwordā€¦ will ask for your old password (the +temporary one if youā€™re resetting your password) and the new password +you want, entered twice because it doesnā€™t echo. Open in Community Site +is the same as above.

+ +

The Settings Menu

+ +

{width=ā€1.2479166666666666inā€ +height=ā€2.5833333333333335inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The settings icon shows a menu of Snap! +options, either for the current project or for you permanently, +depending on the option:

+ +

The Languageā€¦ option lets you see the Snap! user interface (blocks +and messages) in a language other than English. (Note: Translations have +been provided by Snap! users. If your native language is missing, send +us an email!)

+ +

The Zoom blocks... option lets you change the size of blocks, both in +the palettes and in scripts. The standard size is 1.0 units. The main +purpose of this option is to let you take very high-resolution pictures +of scripts for use on posters. It can also be used to improve +readability when projecting onto a screen while lecturing, but bear in +mind that it doesnā€™t make the palette or script areas any wider, so your +computerā€™s command-option-+ feature may be more practical. Note that a +zoom of 2 is gigantic! Donā€™t even try 10.

+ +

The Fade blocksā€¦ option opens a dialog in which you can change the +appearance of blocks:

+ +

{width=ā€7.4847222222222225inā€ +height=ā€2.577777777777778inā€}Mostly this is a propaganda aid to use on +people who think that text languages are somehow better or more grown up +than block languages, but some people do prefer less saturated block +colors. You can use the pulldown menu for preselected fadings, use the +slider to see the result as you change the fading amount, or type a +number into the text box once youā€™ve determined your favorite value.

+ +

The Stage sizeā€¦ option lets you set the size of the full-size stage +in pixels. If the stage is in half-size or double-size (presentation +mode), the stage size values donā€™t change; they always reflect the +full-size stage.

+ +

The Microphone resolutionā€¦ option sets the buffer size used by the +microphone block in Settings. ā€œResolutionā€ is an accurate name if you +are getting frequency domain samples; the more samples, the narrower the +range of frequencies in each sample. In the time domain, the buffer size +determines the length of time over which samples are collected.

+ +

The remaining options let you turn various features on and off. There +are three groups of checkboxes. The first is for temporary settings not +saved in your project nor in your user preferences.

+ +

The JavaScript extensions option enables the use of the JavaScript +function block. Because malicious projects could use JavaScript to +collect private information about you, or to delete or modify your saved +projects, you must enable JavaScript each time you load a project that +uses it.

+ +

{width=ā€1.1895833333333334inā€ +height=ā€0.18958333333333333inā€}{width=ā€1.229861111111111inā€ +height=ā€0.25972222222222224inā€}The Extension blocks option adds two +blocks to the palette:

+ +

These blocks provide assorted capabilities to official libraries that +were formerly implemented with the JavaScript function block. This +allows these libraries to run without requiring the JavaScript +extensions option. Details are subject to change.

+ +

{width=ā€1.104861111111111inā€ +height=ā€2.0833333333333335inā€}{width=ā€1.6388888888888888inā€ +height=ā€0.4131944444444444inā€}Input sliders provides an alternate way to +put values in numeric input slots; if you click in such a slot, a slider +appears that you can control with the mouse:

+ +

The range of the slider will be from 25 less than the inputā€™s current +value to 25 more than the current value. If you want to make a bigger +change than that, you can slide the slider all the way to either end, +then click on the input slot again, getting a new slider with a new +center point. But you wonā€™t want to use this technique to change the +input value from 10 to 1000, and it doesnā€™t work at all for non-integer +input ranges. This feature was implemented because software keyboard +input on phones and tablets didnā€™t work at all in the beginning, and +still doesnā€™t work perfectly on Android devices, so sliders provide a +workaround. It has since found another use in providing ā€œlivelyā€ +response to input changes; if Input sliders is checked, reopening the +settings menu will show an additional option called Execute on slider +change. If this option is also checked, then changing a slider in the +scripting area automatically runs the script in which that input +appears. The project live-tree in the Examples collection shows how this +can be used; it features a fractal tree custom block with several +inputs, and you can see how each input affects the picture by moving a +slider.

+ +

Turbo mode makes many projects run much faster, at the cost of not +keeping the stage display up to date. (Snap! ordinarily spends most of +its time drawing sprites and updating variable watchers, rather than +actually carrying out the instructions in your scripts.) So turbo mode +isnā€™t a good idea for a project with glide blocks or one in which the +user interacts with animated characters, but itā€™s great for drawing a +complicated fractal, or computing the first million digits of šœ‹, so that +you donā€™t need to see anything until the final result. While in turbo +mode, the button that normally shows a green flag instead shows a green +lightning bolt. (But when āš‘ clicked hat blocks still activate when the +button is clicked.)

+ +

Visible stepping enables the slowed-down script evaluation described in +Chapter I. Checking this option is equivalent to clicking the footprint +button above the scripting area. You donā€™t want this on except when +youā€™re actively debugging, because even the fastest setting of the +slider is still slowed a lot.

+ +

Log pen vectors tells Snap! to remember lines drawn by sprites as +exact vectors, rather than remember only the pixels that the drawing +leaves on the stage. This remembered vector picture can be used in two +ways: First, right-clicking on a pen trails block gives an option to +relabel it into a pen vectors block which, when run, reports the logged +lines as a vector (svg) costume. Second, right-clicking on the stage +when there are logged vectors shows an extra option, svgā€¦, that +exports a picture of the stage in vector format. Only lines are logged, +not color regions made with the fill block.

+ +

The next group of four are user preference options, preserved when you +load a new project. Long form input dialog, if checked, means that +whenever a custom block input name is created or edited, you immediately +see the version of the input name dialog that includes the type options, +default value setting, etc., instead of the short form with just the +name and the choice between input name and title text. The default +(unchecked) setting is definitely best for beginners, but more +experienced Snap! programmers may find it more convenient always to +see the long form.

+ +

Plain prototype labels eliminates the plus signs between words in the +Block Editor prototype block. This makes it harder to add an input to a +custom block; you have to hover the mouse where the plus sign would have +been, until a single plus sign appears temporarily for you to click on. +Itā€™s intended for people making pictures of scripts in the block editor +for use in documentation, such as this manual. You probably wonā€™t need +it otherwise.

+ +

Clicking sound causes a really annoying sound effect whenever one block +snaps next to another in a script. Certain very young children, and our +colleague Dan Garcia, like this, but if you are such a child you should +bear in mind that driving your parents or teachers crazy will result in +you not being allowed to use Snap!. It might, however, be useful for +visually impaired users.

+ +

Flat design changes the ā€œskinā€ of the Snap! window to a really hideous +design with white and pale-grey background, rectangular rather than +rounded buttons, and monochrome blocks (rather than the shaded, somewhat +3D-looking normal blocks). The monochrome blocks are the reason for the +ā€œflatā€ in the name of this option. The only thing to be said for this +option is that, because of the white background, it may blend in better +with the rest of a web page when a Snap! project is run in a frame in +a larger page. (I confess I used it to make the picture of blocks faded +all the way to just text two pages ago, though.)

+ +

The final group of settings change the way Snap! interprets your +program; they are saved with the project, so anyone who runs your +project will experience the same behavior. Thread safe scripts changes +the way Snap! responds when an event (clicking the green flag, say) +starts a script, and then, while the script is still running, the same +event happens again. Ordinarily, the running process stops where it is, +ignoring the remaining commands in the script, and the entire script +starts again from the top. This behavior is inherited from Scratch, and +some converted Scratch projects depend on it; thatā€™s why itā€™s the +default. Itā€™s also sometimes the right thing, especially in projects +that play music in response to mouse clicks or keystrokes. If a note is +still playing but you ask for another one, you want the new one to start +right then, not later after the old process finishes. But if your script +makes several changes to a database and is interrupted in the middle, +the result may be that the database is inconsistent. When you select +Thread safe scripts, the same event happening again in the middle of +running a script is simply ignored. (This is arguably still not the +right thing; the event should be remembered and the script run again as +soon as it finishes. Weā€™ll probably get around to adding that choice +eventually.) Keyboard events (when __ key pressed) are always +thread-safe.

+ +

Flat line ends affects the drawing of thick lines (large pen width). +Usually the ends are rounded, which looks best when turning corners. +With this option selected, the ends are flat. Itā€™s useful for drawing a +brick wall or a filled rectangle.

+ +

Codification support enables a feature that can translate a Snap! +project to a text-based (rather than block-based) programming language. +The feature doesnā€™t know about any particular other language; instead, +you can provide a translation for each primitive block using these +special blocks:

+ +

{width=ā€3.120644138232721inā€ +height=ā€0.5451388888888888inā€}

+ +

Using these primitive blocks, you can build a block library to translate +into any programming language. Watch for such libraries to be added to +our library collection (or contribute one). To see some examples, open +the project ā€œCodificationā€ in the Examples project list. Edit the blocks +map to Smalltalk, map to JavaScript, etc., to see examples of how to +provide translations for blocks.

+ +

{width=ā€2.209722222222222inā€ +height=ā€4.969444444444444inā€}{width=ā€1.38inā€ +height=ā€4.79inā€}The Single palette option puts all blocks, regardless of +category, into a single palette. Itā€™s intended mainly for use by +curriculum developers building Parsons problems: projects in which +only a small set of blocks are provided, and the task is to arrange +those blocks to achieve a set goal. In that application, this option is +combined with the hiding of almost all primitive blocks. (See page 119.) +When Single palette is turned on, two additional options (initially on) +appear in the settings menu; the Show categories option controls the +appearance of the palette category names such as +{width=ā€0.36inā€ height=ā€0.16inā€} +and A picture containing logo Description automatically
+generated{width=ā€0.33inā€ +height=ā€0.18inā€}, while the Show buttons option controls the appearance +of the {width=ā€0.61inā€ +height=ā€0.16inā€} and +{width=ā€0.53inā€ height=ā€0.16inā€} +buttons in the palette.

+ +

The HSL pen color model option changes the set pen, change pen, and pen +blocks to provide menu options hue, saturation, and lightness instead of +hue, saturation, and brightness (a/k/a value). Note: the name +ā€œsaturationā€ means something different in HSL from in HSV! See Appendix +A for all the information you need about colors.

+ +

The Disable click-to-run option tells Snap! to ignore user mouse +clicks on blocks and scripts if it would ordinarily run the block or +script. (Right-clicking and dragging still work, and so does clicking in +an input slot to edit it.) This is another Parsons problem feature; the +idea is that there will be buttons displayed that run code only in +teacher-approved ways. But kids can uncheck the checkbox. ā˜ŗļøŽ

+ +

Visible Stepping Controls

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}After the menu buttons youā€™ll see the +project name. After that comes the footprint button used to turn on +visible stepping and, when itā€™s on, the slider to control the speed of +stepping.

+ +

Stage Resizing Buttons

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}Still in the tool bar, but above the left +edge of the stage, are two buttons that change the size of the stage. +The first is the shrink/grow button. Normally it looks like this: +Clicking the button displays the stage at half-normal size horizontally +and vertically (so it takes up Ā¼ of its usual area). When the stage is +half size the button looks like this: and clicking it returns the stage +to normal size. The main reason youā€™d want a half size stage is during +the development process, when youā€™re assembling scripts with wide input +expressions and the normal scripting area isnā€™t wide enough to show the +complete script. Youā€™d typically then switch back to normal size to try +out the project. The next presentation mode button normally looks like +this: Clicking the button makes the stage double size in both dimensions +and eliminates most of the other user interface elements (the palette, +the scripting area, the sprite corral, and most of the tool bar). When +you open a shared project using a link someone has sent you, the project +starts in presentation mode. While in presentation mode, the button +looks like this: Clicking it returns to normal (project development) +mode.

+ +

Project Control Buttons {#project-control-buttons .ListParagraph}

+ +

Above the right edge of the stage are three buttons that control the +running of the project.

+ +

{width=ā€0.38inā€ +height=ā€0.22inā€}Technically, the green flag is no more a project control +than anything else that can trigger a hat block: typing on the keyboard +or clicking on a sprite. But itā€™s a convention that clicking the flag +should start the action of the project from the beginning. Itā€™s only a +convention; some projects have no flag-controlled scripts at all, but +respond to keyboard controls instead. Clicking the green flag also +deletes temporary clones.

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}Whenever any script is running (not necessarily in the +current sprite), the green flag is lit: .

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}{width=ā€1.3590277777777777inā€ +height=ā€0.8840277777777777inā€}Shift-clicking the button enters Turbo +mode, and the button then looks like a lightning bolt: . Shift-clicking +again turns Turbo mode off.

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}Scripts can simulate clicking the green +flag by broadcasting the special message +{width=ā€0.3055555555555556inā€ +height=ā€0.3055555555555556inā€}.

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}The pause button suspends running all +scripts. If clicked while scripts are running, the button changes shape +to become a play button: Clicking it while in this form resumes the +suspended scripts. There is also a pause all block in the Control +palette that can be inserted in a script to suspend all scripts; this +provides the essence of a breakpoint debugging capability. The use of +the pause button is slightly different in visible stepping mode, +described in Chapter I.

+ +

{width=ā€0.5486111111111112inā€ +height=ā€0.17708333333333334inā€}The stop button stops all scripts, like +the stop all block. It does not prevent a script from starting again +in response to a click or keystroke; the user interface is always +active. There is one exception: generic when blocks will not fire after +a stop until some non-generic event starts a script. The stop button +also deletes all temporary clones.

+ +

The Palette Area

+ +

At the top of the palette area are the eight buttons that select which +palette (which block category) is shown: Motion, Looks, Sound, Pen, +Control, Sensing, Operators, and Variables (which also includes the List +and Other blocks). There are no menus behind these buttons.

+ +

Buttons in the Palette

+ +

{width=ā€0.2604166666666667inā€ +height=ā€0.2604166666666667inā€}Under the eight palette selector buttons, +at the top of the actual palette, are two semi-transparent buttons. The +first is the search button, which is equivalent to typing control-F: +It replaces the palette with a search bar into which you can type part +of the title text of the block youā€™re trying to find. To leave this +search mode, click one of the eight palette selectors, or type the +Escape key.

+ +

{width=ā€0.2604166666666667inā€ +height=ā€0.2604166666666667inā€}The other button is equivalent to the +ā€œMake a blockā€ button, except that the dialog window that it opens has +the current palette (color) preselected.

+ +

Context Menus for Palette Blocks

+ +

{width=ā€0.8611111111111112inā€ +height=ā€0.45902777777777776inā€}Most elements of the Snap! display can +be control-clicked/right-clicked to show a context menu, with items +relevant to that element. If you control-click/right-click a primitive +block in the palette, you see this menu:

+ +

The helpā€¦ option displays a box with documentation about the block. +Hereā€™s an example:

+ +

{width=ā€1.6229166666666666inā€ +height=ā€0.8888888888888888inā€}{width=ā€3.3222222222222224inā€ +height=ā€2.4277777777777776inā€}If you control-click/right-click a +custom (user-defined) block in the palette, you see this menu:

+ +

The helpā€¦ option for a custom block displays the comment, if any, +attached to the custom blockā€™s hat block in the Block Editor. Here is an +example of a block with a comment and its help display:

+ +

{width=ā€6.758333333333334inā€ +height=ā€2.451388888888889inā€}If the help text includes a URL, it is +clickable and will open the page in a new tab.

+ +

The delete block definitionā€¦ option asks for confirmation, then +deletes the custom block and removes it from any scripts in which it +appears. (The result of this removal may not leave a sensible script; +itā€™s best to find and correct such scripts before deleting a block.) +Note that there is no option to hide a custom block; this can be done +in the Block Editor by right-clicking on the hat block.

+ +

The duplicate block definitionā€¦ option makes a copy of the block and +opens that copy in the Block Editor. Since you canā€™t have two custom +blocks with the same title text and input types, the copy is created +with ā€œ(2)ā€ (or a higher number if necessary) at the end of the block +prototype.

+ +

The export block definitionā€¦ option writes a file in your browserā€™s +downloads directory containing the definition of this block and any +other custom blocks that this block invokes, directly or indirectly. So +the resulting file can be loaded later without the risk of red +Undefined! blocks because of missing dependencies.

+ +

The editā€¦ option opens a Block Editor with the definition of the +custom block.

+ +

Context Menu for the Palette Background

+ +

{width=ā€0.9895833333333334inā€ +height=ā€0.5895833333333333inā€}Right-click/control-click on the grey +background of the palette area shows this menu:

+ +

{width=ā€1.6inā€ +height=ā€2.1597222222222223inā€}The find blocksā€¦ option does the same +thing as the magnifying-glass button. The hide blocksā€¦ option opens a +dialog box in which you can choose which blocks (custom as well as +primitive) should be hidden. (Within that dialog box, the context menu +of the background allows you to check or uncheck all the boxes at once.)

+ +

The make a categoryā€¦ option, which is intended mainly for authors of +snap extensions, lets you add custom categories to the palette. It +opens a small dialog window in which you specify a name and a color +for the new category:

+ +

{width=ā€1.429861111111111inā€ +height=ā€2.9097222222222223inā€}{width=ā€1.53inā€ +height=ā€1.13inā€}Pick a dark color, because it will be lightened for +zebra coloring when users nest blocks of the same category. Custom +categories are shown below the built-in categories in the category +selector:

+ +

{width=ā€1.35inā€ +height=ā€1.8395833333333333inā€}This example comes from Eckart Modrowā€™s +SciSnap! library. Note that the custom category list has its own +scroll bar, which appears if you have more than six custom categories. +Note also that the buttons to select a custom category occupy the full +width of the palette area, unlike the built-in categories, which occupy +only half of the width. Custom categories are listed in alphabetical +order; this is why Prof. Modrow chose to start each category name with a +number, so that he could control their order.

+ +

If there are no blocks visible in a category, the category name is +dimmed in the category selector:

+ +

Here we see that category foo has blocks in it, but categories bar and +garply are empty. The built-in categories are also subject to dimming, +if all of the blocks of a category are hidden.

+ +


+Palette Resizing

+ +

At the right end of the palette area, just to the left of the scripting +area, is a resizing +handle{width=ā€1.4166666666666667inā€ +height=ā€1.5138888888888888inā€} that can be dragged rightward to increase +the width of the palette area. This is useful if you write custom blocks +with very long names. You canā€™t reduce the width of the palette below +its standard value.

+ +

The Scripting Area

+ +

The scripting area is the middle vertical region of the Snap! window, +containing scripts and also some controls for the appearance and +behavior of a sprite. There is always a current sprite, whose scripts +are shown in the scripting area. A dark grey rounded rectangle in the +sprite corral shows which sprite (or the stage) is current. Note that +itā€™s only the visible display of the scripting area that is ā€œcurrentā€ +for a sprite; all scripts of all sprites may be running at the same +time. Clicking on a sprite thumbnail in the sprite corral makes it +current. The stage itself can be selected as current, in which case the +appearance is different, with some primitives not shown.

+ +

Sprite Appearance and Behavior Controls

+ +

At the top of the scripting area are a picture of the sprite and some +controls for it:

+ +

{width=ā€3.486111111111111inā€ +height=ā€1.0416666666666667inā€}

+ +

Note that the sprite picture reflects its rotation, if any. There are +three things that can be controlled here:

+ +

1. The three circular buttons in a column at the left control the +spriteā€™s rotation behavior. Sprite costumes are designed to be +right-side-up when the sprite is facing toward the right (direction = +90). If the topmost button is lit, the default as shown in the picture +above, then the spriteā€™s costume rotates as the sprite changes +direction. If the middle button is selected, then the costume is +reversed left-right when the spriteā€™s direction is roughly leftward +(direction between 180 and 359, or equivalently, between -180 and -1). +If the bottom button is selected, the costumeā€™s orientation does not +change regardless of the spriteā€™s direction.

+ +

2. The spriteā€™s name can be changed in the text box that, in this +picture, says ā€œSprite.ā€

+ +

3. Finally, if the draggable checkbox is checked, then the user can move +the sprite on the stage by clicking and dragging it. The common use of +this feature is in game projects, in which some sprites are meant to be +under the playerā€™s control but others are not.

+ +

Scripting Area Tabs

+ +

{width=ā€3.0972222222222223inā€ +height=ā€0.25inā€}Just below the sprite controls are three tabs that +determine what is shown in the scripting area:

+ +

Scripts and Blocks Within Scripts

+ +

Most of whatā€™s described in this section also applies to blocks and +scripts in a Block Editor.

+ +

Clicking on a script (which includes a single unattached block) runs it. +If the script starts with a hat block, clicking on the script runs it +even if the event in the hat block doesnā€™t happen. (This is a useful +debugging technique when you have a dozen sprites and they each have +five scripts with green-flag hat blocks, and you want to know what a +single one of those scripts does.) The script will have a green ā€œhaloā€ +around it while itā€™s running. If the script is shared with clones, then +while it has the green halo it will also have a count of how many +instances of the script are running. Clicking a script with such a halo +stops the script. (If the script includes a warp block, which might be +inside a custom block used in the script, then Snap! may not respond +immediately to clicks.)

+ +

{width=ā€0.3333333333333333inā€ +height=ā€0.2604166666666667inā€}If a script is shown with a red halo, +that means that an error was caught in that script, such as using a list +where a number was needed, or vice versa. Clicking the script will turn +off the halo.

+ +

{width=ā€0.3125inā€ +height=ā€0.23958333333333334inā€}{width=ā€0.3333333333333333inā€ +height=ā€0.2604166666666667inā€}If any blocks have been dragged into the +scripting area, then in its top right corner youā€™ll see an undo and/or +redo button that can be used to undo or redo block and script drops. +When you undo a drop into an input slot, whatever used to be in the slot +is restored. The redo button appears once youā€™ve used undo.

+ +

The third button starts keyboard editing mode (Section D, page 130).

+ +

Control-click/right-clicking a primitive block within a script shows a +menu like this one:

+ +

{width=ā€0.6208333333333333inā€ +height=ā€1.0625inā€}{width=ā€0.6263888888888889inā€ +height=ā€1.0902777777777777inā€}

+ +

command block: reporter block:

+ +

The helpā€¦ option shows the help screen for the block, just as in the +palette. The other options appear only when a block is +right-clicked/control-clicked in the scripting area.

+ +

{width=ā€1.53inā€ +height=ā€2.13inā€}Not every primitive block has a relabelā€¦ option. When +present, it allows the block to be replaced by another, similar block, +keeping the input expressions in place. For example, hereā€™s what happens +when you choose relabelā€¦ for an arithmetic operator:

+ +

Note that the inputs to the existing ā€“ block are displayed in the menu +of alternatives also. Click a block in the menu to choose it, or click +outside the menu to keep the original block. Note that the last three +choices are not available in the palette; you must use the relabel +feature to access them.

+ +

Not every reporter has a compile option; it exists only for the higher +order functions. When selected, a lightning bolt appears before the +block name: +{width=ā€1.4027777777777777inā€ +height=ā€0.2013888888888889inā€} and Snap! tries to compile the function +inside the ring to JavaScript, so it runs at primitive speed. This works +only for simple functions (but the higher order function still works +even if the compilation doesnā€™t). The function to be compiled must be +quick, because it will be uninterruptable; in particular, if itā€™s an +infinite loop, you may have to quit your browser to recover. Therefore, +save your project before you experiment with the compilation +feature. The right-click menu for a compiled higher order function will +have an uncompile option. This is an experimental feature.

+ +

The duplicate option for a command block makes a copy of the entire +script starting from the selected block. For a reporter, it copies only +that reporter and its inputs. The copy is attached to the mouse, and you +can drag it to another script (or even to another Block Editor window), +even though you are no longer holding down the mouse button. Click the +mouse to drop the script copy.

+ +

The block picture underneath the word duplicate for a command block is +another duplication option, but it duplicates only the selected block, +not everything under it in the script. Note that if the selected block +is a C-shaped control block, the script inside its C-shaped slot is +included. If the block is at the end of its script, this option does not +appear. (Use duplicate instead.)

+ +

The extract option removes the selected block from the script and leaves +you holding it with the mouse. In other words, itā€™s like the block +picture option, but it doesnā€™t leave a copy of the block in the original +script. If the block is at the end of its script, this option does not +appear. (Just grab the block with the mouse.) A shorthand for this +operation is to shift-click and drag out the block.

+ +

The delete option deletes the selected block from the script.

+ +

The add comment option creates a comment, like the same option in the +background of the scripting area, but attaches it to the block you +clicked.

+ +

The script picā€¦ option saves a picture of the entire script, not just +from the selected block to the end, into your download folder; or, in +some browsers, opens a new browser tab containing the picture. In the +latter case, you can use the browserā€™s Save feature to put the picture +in a file. This is a super useful feature if you happen to be writing a +Snap! manual! (If you have a Retina display, consider turning off +Retina support before making script pictures; if not, they end up huge.) +For reporters not inside a script, there is an additional result picā€¦ +option that calls the reporter and includes a speech balloon with the +result in the picture. Note: The downloaded file is a ā€œsmart pictureā€: +It also contains the code of the script, as if youā€™d exported the +project. If you later drag the file into the costumes tab, it will be +loaded as a costume. But if you drag it into the scripts tab, it will +be loaded as a script, which you can drop wherever you want it in the +scripting area.

+ +

If the script does not start with a hat block, or you clicked on a +reporter, then thereā€™s one more option: ringify (and, if there is +already a grey ring around the block or script, unringify). Ringify +surrounds the block (reporter) or the entire script (command) with a +grey ring, meaning that the block(s) inside the ring are themselves +data, as an input to a higher order procedure, rather than something to +be evaluated within the script. See Chapter VI, Procedures as Data.

+ +

{width=ā€0.9736111111111111inā€ +height=ā€1.2986111111111112inā€}Clicking a custom block in a script +gives a similar but different menu:

+ +

The relabelā€¦ option for custom blocks shows a menu of other same-shape +custom blocks with the same inputs. At present you canā€™t relabel a +custom block to a primitive block or vice versa. The two options at the +bottom, for custom blocks only, are the same as in the palette. The +other options are the same as for primitive commands.

+ +

{width=ā€0.88125inā€ +height=ā€1.0833333333333333inā€}If a reporter block is in the scripting +area, possibly with inputs included, but not itself serving as input to +another block, then the menu is a little different again:

+ +

Whatā€™s new here is the result picā€¦ option. Itā€™s like script picā€¦ but +it includes in the picture a speech balloon with the result of calling +the block.

+ +

Broadcast and broadcast and wait blocks in the scripting area have an +additional option: receiversā€¦. When clicked, it causes a momentary (be +looking for it when you click!) halo around the picture in the sprite +corral of those sprites that have a when I receive hat block for the +same message. Similarly, when I receive blocks have a sendersā€¦ option +that light up the sprite corral icons of sprites that broadcast the same +message.

+ +

Scripting Area Background Context Menu

+ +

{width=ā€1.2895833333333333inā€ +height=ā€1.2777777777777777inā€}Control-click/right-click on the grey +striped background of the scripting area gives this menu:

+ +

{width=ā€0.8416666666666667inā€ +height=ā€0.18819444444444444inā€}The undrop option is a sort of ā€œundoā€ +feature for the common case of dropping a block somewhere other than +where you meant it to go. It remembers all the dragging and dropping +youā€™ve done in this spriteā€™s scripting area (that is, other sprites have +their own separate drop memory), and undoes the most recent, returning +the block to its former position, and restoring the previous value in +the relevant input slot, if any. Once youā€™ve undropped something, the +redrop option appears, and allows you to repeat the operation you just +undid. These menu options are equivalent to the and buttons described +earlier.

+ +

The clean up option rearranges the position of scripts so that they are +in a single column, with the same left margin, and with uniform spacing +between scripts. This is a good idea if you canā€™t read your own project!

+ +

{width=ā€1.3888888888888888inā€ +height=ā€0.7083333333333334inā€}The add comment option puts a comment box, +like the picture to the right, in the scripting area. Itā€™s attached to +the mouse, as with duplicating scripts, so you position the mouse where +you want the comment and click to release it. You can then edit the text +in the comment as desired.

+ +

{width=ā€1.3888888888888888inā€ +height=ā€0.2361111111111111inā€}You can drag the bottom right corner of +the comment box to resize it. Clicking the arrowhead at the top left +changes the box to a single-line compact form, , so that you can have a +number of collapsed comments in the scripting area and just expand one +of them when you want to read it in full.

+ +

If you drag a comment over a block in a script, the comment will be +attached to the block with a yellow line:

+ +

{width=ā€1.4861111111111112inā€ +height=ā€0.8472222222222222inā€}{width=ā€3.3333333333333335inā€ +height=ā€0.9333333333333333inā€}Comments have their own context menu, with +obvious meanings:

+ +

Back to the options in the menu for the background of the scripting area +(picture on the previous page):

+ +

The scripts picā€¦ option saves, or opens a new browser tab with, a +picture of all scripts in the scripting area, just as they appear, but +without the grey striped background. Note that ā€œall scripts in the +scripting areaā€ means just the top-level scripts of the current sprite, +not other spritesā€™ scripts or custom block definitions. This is also a +ā€œsmart pictureā€; if you drag it into the scripting area, it will create +a new sprite with those scripts in its scripting area.

+ +

Finally, the make a blockā€¦ option does the same thing as the ā€œMake a +blockā€ button in the palettes. Itā€™s a shortcut so that you donā€™t have to +keep scrolling down the palette if you make a lot of blocks.

+ +

Controls in the Costumes Tab

+ +

{width=ā€1.9631944444444445inā€ +height=ā€2.1319444444444446inā€}If you click on the word ā€œCostumesā€ under +the sprite controls, youā€™ll see something like this:

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.21666666666666667inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}The Turtle costume is always present in +every sprite; it is costume number 0. Other costumes can be painted +within Snap! or imported from files or other browser tabs if your +browser supports that. Clicking on a costume selects it; that is, the +sprite will look like the selected costume. Clicking on the paint brush +icon
+opens the Paint Editor, in which you can create a new costume. +Clicking on the camera icon opens a window in which you see what your +computerā€™s camera is seeing, and you can take a picture (which will be +the full size of the stage unless you shrink it in the Paint Editor). +This works only if you give Snap! permission to use the camera, and +maybe only if you opened Snap! in secure (HTTPS) mode, and then only +if your browser loves you.

+ +

{width=ā€3.5694444444444446inā€ +height=ā€3.1805555555555554inā€} Brianā€™s bedroom when heā€™s staying at +Paulā€™s house.

+ +

Control-clicking/right-clicking on the turtle picture gives this menu:

+ +

{width=ā€1.0555555555555556inā€ +height=ā€0.9027777777777778inā€}In this menu, you choose the turtleā€™s +rotation point, which is also the point from which the turtle draws +lines. The two pictures below show what the stage looks like after +drawing a square in each mode; tip (otherwise known as ā€œJens modeā€) is +on the left in the pictures below, middle (ā€œBrian modeā€) on the right:

+ +

{width=ā€3.134027777777778inā€ +height=ā€1.1743055555555555inā€}As you see, ā€œtipā€ means the front tip of +the arrowhead; ā€œmiddleā€ is not the middle of the shaded region, but +actually the middle of the four vertices, the concave one. (If the shape +were a simple isosceles triangle instead of a fancier arrowhead, it +would mean the midpoint of the back edge.) The advantage of tip mode is +that the sprite is less likely to obscure the drawing. The advantage of +middle mode is that the rotation point of a sprite is rarely at a tip, +and students are perhaps less likely to be confused about just what will +happen if you ask the turtle to turn 90 degrees from the position shown. +(Itā€™s also the traditional rotation point of the Logo turtle, which +originated this style of drawing.)

+ +

{width=ā€0.9833333333333333inā€ +height=ā€1.3194444444444444inā€}Costumes other than the turtle have a +different context menu:

+ +

The edit option opens the Paint Editor on this costume. The rename +option opens a dialog box in which you can rename the costume. (A +costumeā€™s initial name comes from the file from which it was imported, +if any, or is something like costume5.) Duplicate makes a copy of the +costume, in the same sprite. (Presumably youā€™d do that because you +intend to edit one of the copies.) Delete is obvious. The get blocks +option appears only for a smart costume, and brings its script to the +scripting area. The export option saves the costume as a file on your +computer, in your usual downloads folder.

+ +

You can drag costumes up and down in the Costumes tab in order to +renumber them, so that next costume will behave as you prefer.

+ +

{width=ā€1.2804921259842519inā€ +height=ā€0.8694444444444445inā€}If you drag a smart picture of a script +into the Costumes tab, its icon will display the text ā€œ</>ā€ in the +corner to remind you that it includes code:

+ +

Its right-click menu will have an extra get blocks option that switches +to the Scripts tab with the script ready to be dropped there.

+ +

The Paint Editor

+ +

{width=ā€3.938888888888889inā€ +height=ā€2.577777777777778inā€}Here is a picture of a Paint Editor window:

+ +

If youā€™ve used any painting program, most of this will be familiar to +you. Currently, costumes you import can be edited only if they are in a +bitmap format (png, jpeg, gif, etc.). There is a vector editor, but it +works only for creating a costume, not editing an imported vector (svg) +picture. Unlike the case of the Block Editor, only one Paint Editor +window can be open at a time.

+ +

The ten square buttons in two rows of five near the top left of the +window are the tools. The top row, from left to right, are the +paintbrush tool, the outlined rectangle tool, the outlined ellipse tool, +the eraser tool, and the rotation point tool. The bottom row tools are +the line drawing tool, the solid rectangle tool, the solid ellipse tool, +the floodfill tool, and the eyedropper tool. Below the tools is a row of +four buttons that immediately change the picture. The first two change +its overall size; the next two flip the picture around horizontally or +vertically. Below these are a color palette, a greyscale tape, and +larger buttons for black, white, and transparent paint. Below these is a +solid bar displaying the currently selected color. Below that is a +picture of a line showing the brush width for painting and drawing, and +below that, you can set the width either with a slider or by typing a +number (in pixels) into the text box. Finally, the checkbox constrains +the line tool to draw horizontally or vertically, the rectangle tools to +draw squares, and the ellipse tools to draw circles. You can get the +same effect temporarily by holding down the shift key, which makes a +check appear in the box as long as you hold it down. (But the Caps Lock +key doesnā€™t affect it.)

+ +

You can correct errors with the undo button, which removes the last +thing you drew, or the clear button, which erases the entire picture. +(Note, it does not revert to what the costume looked like before you +started editing it! If thatā€™s what you want, click the Cancel button at +the bottom of the editor.) When youā€™re finished editing, to keep your +changes, click OK.

+ +

Note that the ellipse tools work more intuitively than ones in other +software you may have used. Instead of dragging between opposite corners +of the rectangle circumscribing the ellipse you want, so that the +endpoints of your dragging have no obvious connection to the actual +shape, in Snap! you start at the center of the ellipse you want and +drag out to the edge. When you let go of the button, the mouse cursor +will be on the curve. If you drag out from the center at 45 degrees to +the axes, the resulting curve will be a circle; if you drag more +horizontally or vertically, the ellipse will be more eccentric. (Of +course if you want an exact circle you can hold down the shift key or +check the checkbox.) The rectangle tools, though, work the way you +expect: You start at one corner of the desired rectangle and drag to the +opposite corner.

+ +

Using the eyedropper tool, you can click anywhere in the Snap! window, +even outside the Paint Editor, and the tool will select the color at the +mouse cursor for use in the Paint Editor. You can only do this once, +because the Paint Editor automatically selects the paintbrush when you +choose a color. (Of course you can click on the eyedropper tool button +again.)

+ +

The only other non-obvious tool is the rotation point tool. It shows in +the Paint Editor where the spriteā€™s current rotation center is (the +point around which it turns when you use a turn block); if you click or +drag in the picture, the rotation point will move where you click. +(Youā€™d want to do this, for example, if you want a character to be able +to wave its arm, so you use two sprites connected together. You want the +rotation point of the arm sprite to be at the end where it joins the +body, so it remains attached to the shoulder while waving.)

+ +

{width=ā€3.8361111111111112inā€ +height=ā€2.548611111111111inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}{width=ā€0.2152777777777778inā€ +height=ā€0.2152777777777778inā€}The vector editorā€™s controls are much like +those in the bitmap editor. One point of difference is that the bitmap +editor has two buttons for solid and outline rectangles, and similarly +for ellipses, but in the vector editor there is always an edge color and +a fill color, even if the latter is ā€œtransparent paint,ā€ and so only one +button per shape is needed. Since each shape that you draw is a separate +layer (like sprites on the stage), there are controls to move the +selected shape up (frontward) or down (rearward) relative to other +shapes. There is a selection tool to drag out a rectangular area and +select all the shapes within that area.

+ +

###

+ +

Controls in the Sounds Tab

+ +

{width=ā€0.35inā€ +height=ā€0.2inā€}There is no Sound Editor in Snap!, and also no current +sound the way thereā€™s a current costume for each sprite. (The sprite +always has an appearance unless hidden, but it doesnā€™t sing unless +explicitly asked.) So the context menu for sounds has only rename, +delete, and export options, and it has a clickable button labeled Play +or Stop as appropriate. There is a sound recorder, which appears if +you click the red record button ( ):

+ +

{width=ā€2.325inā€ +height=ā€1.0333333333333334inā€}The first, round button starts recording. +The second, square button stops recording. The third, triangular button +plays back a recorded sound. If you donā€™t like the result, click the +round button again to re-record. When youā€™re satisfied, push the Save +button. If you need a sound editor, consider the free (both senses) +http://audacity.sourceforge.net.

+ +

Keyboard Editing

+ +

An ongoing area of research is how to make visual programming languages +usable by people with visual or motoric disabilities. As a first step in +this direction, we provide a keyboard editor, so that you can create and +edit scripts without tracking the mouse. So far, not every user +interface element is controllable by keyboard, and we havenā€™t even begun +providing output support, such as interfacing with a speech +synthesizer. This is an area in which we know we have a long way to go! +But itā€™s a start. The keyboard editor may also be useful to anyone who +can type faster than they can drag blocks.

+ +

Starting and stopping the keyboard editor

+ +

There are three ways to start the keyboard editor. Shift-clicking +anywhere in the scripting area will start the editor at that point: +either editing an existing script or, if you shift-click on the +background of the scripting area, editing a new script at the mouse +position. Alternatively, typing shift-enter will start the editor on an +existing script, and you can use the tab key to switch to another +script. Or you can click the keyboard button at the top of the scripting +area.

+ +

When the script editor is running, its position is represented by a +blinking white bar:

+ +

{width=ā€2.2083333333333335inā€ +height=ā€1.59375inā€}To leave the keyboard editor, type the escape key, or +just click on the background of the scripting area.

+ + + +

To move to a different script, type the tab key. Shift-tab to move +through the scripts in reverse order.

+ +

A script is a vertical stack of command blocks. A command block may have +input slots, and each input slot may have a reporter block in it; the +reporter may itself have input slots that may have other reporters. You +can navigate through a script quickly by using the up arrow and down +arrow keys to move between command blocks. Once you find the command +block that you want to edit, the left and right arrow keys move between +editable items within that command. (Left and right arrow when there are +no more editable items within the current command block will move up or +down to another command block, respectively.) Here is a sequence of +pictures showing the results of repeated right arrow keys starting from +the position shown above:

+ +

{width=ā€7.313888888888889inā€ +height=ā€1.2527777777777778inā€}You can rearrange scripts within the +scripting area from the keyboard. Typing shift-arrow keys (left, right, +up, or down) will move the current script. If you move it onto another +script, the two wonā€™t snap together; the one youā€™re moving will overlap +the one already there. This means that you can move across another +script to get to a free space.

+ +

Editing a script

+ +

Note that the keyboard editor focus, the point shown as a white bar or +halo, is either between two command blocks or on an input slot. The +editing keys do somewhat different things in each of those two cases.

+ +

The backspace key deletes a block. If the focus is between two commands, +the one before (above) the blinking bar is deleted. If the focus is on +an input slot, the reporter in that slot is deleted. (If that input slot +has a default value, it will appear in the slot.) If the focus is on a +variadic input (one that can change the number of inputs by clicking +on arrowheads), then one input slot is deleted. (When you right-arrow +into a variadic input, the focus first covers the entire thing, +including the arrowheads; another right-arrow focuses on the first slot +within that input group. The focus is ā€œon the variadic inputā€ when it +covers the entire thing.)

+ +

The enter key does nothing if the focus is between commands, or on a +reporter. If the focus is on a variadic input, the enter key adds one +more input slot. If the focus is on a white input slot (one that doesnā€™t +have a reporter in it), then the enter key selects that input slot for +editing; that is, you can type into it, just as if youā€™d clicked on +the input slot. (Of course, if the focus is on an input slot containing +a reporter, you can use the backspace key to delete that reporter, and +then use the enter key to type a value into it.) When you finish typing +the value, type the enter key again to accept it and return to +navigation, or the escape key if you decide not to change the value +already in the slot.

+ +

The space key is used to see a menu of possibilities for the input slot +in focus. It does nothing unless the focus is on a single input slot. If +the focus is on a slot with a pulldown menu of options, then the space +key shows that menu. (If itā€™s a block-colored slot, meaning that only +the choices in the menu can be used, the enter key will do the same +thing. But if itā€™s a white slot with a menu, such as in the turn blocks, +then enter lets you type a value, while space shows the menu.) +Otherwise, the space key shows a menu of variables available at this +point in the script. In either case, use the up and down arrow keys to +navigate the menu, use the enter key to accept the highlighted entry, or +use the escape key to leave the menu without choosing an option.

+ +

{width=ā€1.5347222222222223inā€ +height=ā€1.6944444444444444inā€}Typing any other character key (not +special keys on fancy keyboards that do something other than generating +a character) activates the block search palette. This palette, which +is also accessible by typing control-F or command-F outside the keyboard +editor, or by clicking the search button floating at the top of the +palette, has a text entry field at the top, followed by blocks whose +title text includes what you type. The character key you typed to start +the block search palette is entered into the text field, so you start +with a palette of blocks containing that character. Within the palette, +blocks whose titles start with the text you type come first, then +blocks in which a word of the title starts with the text you type, and +finally blocks in which the text appears inside a word of the title. +Once you have typed enough text to see the block you want, use the arrow +keys to navigate to that block in the palette, then enter to insert that +block, or escape to leave the block search palette without inserting the +block. (When not in the keyboard editor, instead of navigating with the +arrow keys, you drag the block you want into the script, as you would +from any other palette.)

+ +

{width=ā€2.8333333333333335inā€ +height=ā€0.8409722222222222inā€}If you type an arithmetic operator (+-*/) +or comparison operator (<=>) into the block search text box, you can +type an arbitrarily complicated expression, and a collection of +arithmetic operator blocks will be constructed to match:

+ +

As the example shows, you can also use parentheses for grouping, and +non-numeric operands are treated as variables or primitive functions. (A +variable name entered in this way may or may not already exist in the +script. Only round and the ones in the pulldown menu of the sqrt block +can be used as function names.)

+ +

Running the selected script

+ +

Type control-shift-enter to run the script with the editor focus, like +clicking the script.

+ +

Controls on the Stage

+ +

The stage is the area in the top right of the Snap! window in which +sprites move.

+ +

Sprites

+ +

{width=ā€0.6013888888888889inā€ +height=ā€1.0833333333333333inā€}Most sprites can be moved by clicking and +dragging them. (If you have unchecked the draggable checkbox for a +sprite, then dragging it has no effect.) Control-clicking/right-clicking +a sprite shows this context menu:

+ +

The duplicate option makes another sprite with copies of the same +scripts, same costumes, etc., as this sprite. The new sprite starts at a +randomly chosen position different from the original, so you can see +quickly which is which. The new sprite is selected: It becomes the +current sprite, the one shown in the scripting area. The clone option +makes a permanent clone of this sprite, with some shared attributes, and +selects it.

+ +

The delete option deletes the sprite. Itā€™s not just hidden; itā€™s gone +for good. (But you can undelete it by clicking the wastebasket just +below the right edge of the stage.) The edit option selects the sprite. +It doesnā€™t actually change anything about the sprite, despite the name; +itā€™s just that making changes in the scripting area will change this +sprite.

+ +

{width=ā€0.6527777777777778inā€ +height=ā€0.8888888888888888inā€}The move option shows a ā€œmove handleā€ +inside the sprite (the diagonal striped square in the middle):

+ +

You can ordinarily just grab and move the sprite without this option, +but there are two reasons you might need it: First, it works even if the +ā€œdraggableā€ checkbox above the scripting area is unchecked. Second, it +works for part sprites relative to their anchor; ordinarily, dragging a +part moves the entire nested sprite.

+ +

The rotate option displays a rotation menu:

+ +

{width=ā€0.9333333333333333inā€ +height=ā€1.5833333333333333inā€}You can choose one of the four compass +directions in the lower part (the same as in the point in direction +block) or use the mouse to rotate the handle on the dial in 15Ā° +increments.

+ +

{width=ā€0.6527777777777778inā€ +height=ā€0.8472222222222222inā€}The pivot option shows a crosshair inside +the sprite:

+ +

You can click and drag the crosshair anywhere onstage to set the +costumeā€™s pivot point. (If you move it outside the sprite, then turning +the sprite will revolve as well as rotate it around the pivot.) When +done, click on the stage not on the crosshair. Note that, unlike moving +the pivot point in the Paint Editor, this technique does not visibly +move the sprite on the stage. Instead, the values of x position and y +position will change.

+ +

The edit option makes this the selected sprite, highlighting it in the +sprite corral and showing its scripting area. If the sprite was a +temporary clone, it becomes permanent.

+ +

The exportā€¦ option saves, or opens a new browser tab containing, the +XML text representation of the sprite. (Not just its costume, but all of +its costumes, scripts, local variables and blocks, and other +properties.) You can save this tab into a file on your computer, and +later import the sprite into another project. (In some browsers, the +sprite is directly saved into a file.)

+ +

{width=ā€0.9583333333333334inā€ height=ā€1.4479166666666667inā€}Variable watchers

+ +

Right-clicking on a variable watcher shows this menu:

+ +

The first section of the menu lets you choose one of three +visualizations of the watcher:

+ +

{width=ā€2.3159722222222223inā€ +height=ā€0.3263888888888889inā€}

+ +

The first (normal) visualization is for debugging. The second (large) is +for displaying information to the user of a project, often the score in +a game. And the third (slider) is for allowing the user to control the +program behavior interactively. When the watcher is displayed as a +slider, the middle section of the menu allows you to control the range +of values possible in the slider. It will take the minimum value when +the slider is all the way to the left, the maximum value when all the +way to the right.

+ +

The third section of the menu allows data to be passed between your +computer and the variable. The importā€¦ option will read a computer +text file. Its name must end with .txt, in which case the text is read +into the variable as is, or .csv or .json, in which case the text is +converted into a list structure, which will always be a two-dimensional +array for csv (comma-separated values) data, but can be any shape for +json data. The raw dataā€¦ option prevents that conversion to list form. +The exportā€¦ option does the opposite conversion, passing a text-valued +variable value into a .txt file unchanged, but converting a list value +into csv format if the list is one- or two-dimensional, or into json +format if the list is more complicated. (The scalar values within the +list must be numbers and/or text; lists of blocks, sprites, costumes, +etc. cannot be exported.)

+ +

An alternative to using the importā€¦ option is simply to drag the file +onto the Snap! window, in which case a variable will be created if +necessary with the same name as the file (but without the extension).

+ +

If the value of the variable is a list, then the menu will include an +additional blockify option; clicking it will generate an expression with +nested list blocks that, if evaluated, will reconstruct the list. Itā€™s +useful if you imported a list and then want to write code that will +construct the same list later.

+ +

The stage itself

+ +

Control-clicking/right-clicking on the stage background (that is, +anywhere on the stage except on a sprite or watcher) shows the stageā€™s +own context menu:

+ +

{width=ā€0.8215277777777777inā€ +height=ā€0.8472222222222222inā€}The stageā€™s edit option selects the stage, +so the stageā€™s scripts and backgrounds are seen in the scripting area. +Note that when the stage is selected, some blocks, especially the Motion +ones, are not in the palette area because the stage canā€™t move.

+ +

The show all option makes all sprites visible, both in the sense of the +show block and by bringing the sprite onstage if it has moved past the +edge of the stage.

+ +

The picā€¦ option saves, or opens a browser tab with, a picture of +everything on the stage: its background, lines drawn with the pen, and +any visible sprites. What you see is what you get. (If you want a +picture of just the background, select the stage, open its costumes tab, +control-click/right-click on a background, and export it.)

+ +

The pen trails option creates a new costume for the currently selected +sprite consisting of all lines drawn on the stage by the pen of any +sprite. The costumeā€™s rotation center will be the current position of +the sprite.

+ +

If you previously turned on the log pen vectors option, and there are +logged vectors, the menu includes an extra option, svgā€¦, that exports +a picture of the stage in vector format. Only lines are logged, not +color regions made with the fill block.

+ +

The Sprite Corral and Sprite Creation Buttons

+ +

{width=ā€0.37916666666666665inā€ +height=ā€0.20555555555555555inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}{width=ā€0.2916666666666667inā€ +height=ā€0.16666666666666666inā€}Between the stage and the sprite corral +at the bottom right of the Snap! window is a dark grey bar containing +three buttons at the left and one at the right. The first three are used +to create a new sprite. The first button makes a sprite with just the +turtle costume, with a randomly chosen position and pen color. (If you +hold down the Shift key while clicking, the new spriteā€™s direction will +also be random.) The second button makes a sprite and opens the Paint +Editor so that you can make your own costume for it. (Of course you +could click the first button and then click the paint button in its +costumes tab; this paint button is a shortcut for all that.) Similarly, +the third button uses your camera, if possible, to make a costume for +the new sprite.

+ +

The trash can button +{width=ā€0.2916666666666667inā€ +height=ā€0.1736111111111111inā€} at the right has two uses. You can drag a +sprite thumbnail onto it from the sprite corral to delete that sprite, +or you can click it to undelete a sprite you deleted by accident.

+ +

In the sprite corral, you click on a spriteā€™s ā€œthumbnailā€ picture to +select that sprite (to make it the one whose scripts, costumes, etc. are +shown in the scripting area). You can drag sprite thumbnails (but not +the stage one) to reorder them; this has no special effect on your +project, but lets you put related ones next to each other, for example. +Double-clicking a thumbnail flashes a halo around the actual sprite on +the stage.

+ +

You can right-click/control-click a spriteā€™s thumbnail to get this +context menu:

+ +

{width=ā€0.6770833333333334inā€ +height=ā€1.1090277777777777inā€}The show option makes the sprite visible, +if it was hidden, and also brings it onto the stage, if it had moved +past the stage boundary. The next three options are the same as in the +context menu of the actual sprite on the stage, discussed above.

+ +

The parentā€¦ option displays a menu of all other sprites, showing which +if any is this spriteā€™s parent, and allowing you to choose another +sprite (replacing any existing parent). The release option is shown only +if this sprite is a (permanent, or it wouldnā€™t be in the sprite corral) +clone; it changes the sprite to a temporary clone. (The name is supposed +to mean that the sprite is released from the corral.) The exportā€¦ +option exports the sprite, like the same option on the stage.

+ +

The context menu for the stage thumbnail has only one option, picā€¦, +which takes a picture of everything on the stage, just like the same +option in the context menu of the stage background. If pen trails are +being logged, there will also be an svgā€¦ option.

+ +

If your project includes scenes, then under the stage icon in the sprite +corral will be the scene corral:

+ +

{width=ā€3.3333333333333335inā€ +height=ā€1.7083333333333333inā€}Clicking on a scene will select it; +right-clicking will present a menu in which you can rename, delete, or +export the scene.

+ +

Preloading a Project when Starting Snap!

+ +

There are several ways to include a pointer to a project in the URL when +starting Snap! in order to load a project automatically. You can think +of such a URL as just running the project rather than as running +Snap!, especially if the URL says to start in presentation mode and +click the green flag. The general form is

+ +

http://snap.berkeley.edu/run#verb:project&flag&flagā€¦

+ +

The ā€œverbā€ above can be any of open, run, cloud, present, or dl. The +last three are for shared projects in the Snap! cloud; the first two +are for projects that have been exported and made available anywhere on +the Internet.

+ +

Hereā€™s an example that loads a project stored at the Snap! web site +(not the Snap! cloud!):

+ +

http://snap.berkeley.edu/run#open:http://snap.berkeley.edu/snapsource/Examples/vee.xml

+ +

The project file will be opened, and Snap! will start in edit mode +(with the program visible). Using #run: instead of #open: will start +in presentation mode (with only the stage visible) and will ā€œstartā€ the +project by clicking the green flag. (ā€œStartā€ is in quotation marks +because there is no guarantee that the project includes any scripts +triggered by the green flag. Some projects are started by typing on the +keyboard or by clicking a sprite.)

+ +

If the verb is run, then you can also use any subset of the following +flags:

+ +

&editMode Start in edit mode, not presentation mode.

+ +

&noRun Donā€™t click the green flag.

+ +

&hideControls Donā€™t show the row of buttons above the stage (edit mode, +green flag, pause, stop).

+ +

&lang=fr Set language to (in this example) French.

+ +

&noCloud Donā€™t allow cloud operations from this project (for running +projects from unknown

+ +

sources that include JavaScript code)

+ +

&noExitWarning When closing the window or loading a different URL, donā€™t +show the browser

+ +

ā€œare you sure you want to leave this pageā€ message.

+ +

&blocksZoom=n Like the Zoom blocks option in the Settings menu.

+ +

The last of these flags is intended for use on a web page in which a +Snap! window is embedded.

+ +

Hereā€™s an example that loads a shared (public) project from the Snap! +cloud:

+ +

http://snap.berkeley.edu/run#present:Username=jens&ProjectName=tree%20animation

+ +

(Note that ā€œUsernameā€ and ā€œProjectNameā€ are TitleCased, even though the +flags such as ā€œnoRunā€ are camelCased. Note also that a space in the +project name must be represented in Unicode as %20.) The verb present +behaves like run: it ordinarily starts the project in presentation mode, +but its behavior can be modified with the same four flags as for run. +The verb cloud (yes, we know itā€™s not a verb in its ordinary use) +behaves like open except that it loads from the Snap! cloud rather +than from the Internet in general. The verb dl (short for ā€œdownloadā€) +does not start Snap! but just downloads a cloud-saved project to your +computer as an .xml file. This is useful for debugging; sometimes a +defective project that Snap! wonā€™t run can be downloaded, edited, and +then re-saved to the cloud.

+ +

Mirror Sites

+ +

If the site snap.berkeley.edu is ever unavailable, you can load Snap! +at the following mirror sites:

+ + + +

Appendix A. Snap! color library {#appendix-a.-snap-color-library .ListParagraph}

+ +

{width=ā€5.8inā€ +height=ā€2.1791666666666667inā€}The Colors and Crayons library provides +several tools for manipulating color. Although its main purpose is +controlling a spriteā€™s pen color, it also establishes colors as a first +class data type:

+ +

{width=ā€3.1333333333333333inā€ +height=ā€0.5166666666666667inā€}For people who just want colors in their +projects without having to be color experts, we provide two simple +mechanisms: a color number scale with a broad range of continuous +color variation and a set of 100 crayons organized by color family +(ten reds, ten oranges, etc.) The crayons include the block colors:

+ +

{width=ā€7.166666666666667inā€ +height=ā€1.1inā€}For experts, we provide color selection by RGB, HSL, HSV, +X11/W3C names, and variants on those scales.

+ +

Introduction to Color

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.4444444444444444inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}Your computer monitor can display millions +of colors, but you probably canā€™t distinguish that many. For example, +hereā€™s red 57, green 180, blue 200: And hereā€™s red 57, green 182, blue +200: You might be able to tell them apart if you see them side by side: +ā€¦ but maybe not even then.

+ +

Color spaceā€”the collection of all possible colorsā€”is +three-dimensional, but there are many ways to choose the dimensions. RGB +(red-green-blue), the one most commonly used in computers, matches the +way TVs and displays produce color. Behind every dot on the screen are +three tiny lights: a red one, a green one, and a blue one. But if you +want to print colors on paper, your printer probably uses a different +set of three colors: CMY (cyan-magenta-yellow). You may have seen the +abbreviation CMYK, which represents the common technique of adding black +ink to the collection. (Mixing cyan, magenta, and yellow in equal +amounts is supposed to result in black ink, but typically it comes out a +muddy brown instead, because chemistry.) Other systems that try to mimic +human perception are HSL (hue-saturation-lightness) and HSV +(hue-saturation-value). There are many, many more, each designed for a +particular purpose.

+ +

If you are a color professionalā€”a printer, a web designer, a graphic +designer, an artistā€”then you need to understand all this. It can also +be interesting to learn about. For example, there are colors that you +can see but your computer display canā€™t generate. If that intrigues you, +look up color theory in +Wikipedia.

+ +

Crayons and Color Numbers

+ +

{width=ā€5.995833333333334inā€ +height=ā€0.825inā€}But if you just want some colors in your project, we +provide a simple, one-dimensional subset of the available colors. Two +subsets, actually: crayons and color numbers. Hereā€™s the difference:

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}The first row shows 100 distinct colors. +They have names; this is pumpkin, and this is denim. Youā€™re supposed to +think of them as a big box of 100 crayons. Theyā€™re arranged in families: +grays, pinks, reds, browns, oranges, etc. But theyā€™re not consistently +ordered within a family; youā€™d be unlikely to say ā€œnext crayonā€ in a +project. (But look at the crayon spiral on page 145.) Instead, youā€™d +think ā€œI want this to look like a really old-fashioned photoā€ and so +youā€™d find sepia as crayon number 33. You donā€™t have to memorize the +numbers! You can find them in a menu with a submenu for each family.

+ +

{width=ā€2.1597222222222223inā€ +height=ā€0.2569444444444444inā€}{width=ā€7.55inā€ +height=ā€2.1527777777777777inā€}Or, if you know the crayon name, just .

+ +

{width=ā€5.793055555555555inā€ +height=ā€0.3inā€}The crayon numbers are chosen so that skipping by 10 +gives a sensible box of ten crayons:

+ +

Alternatively, skipping by 5 gives a still-sensible set of twenty +crayons:

+ +

{width=ā€5.8inā€ height=ā€0.3inā€}

+ +

{width=ā€6.245138888888889inā€ +height=ā€0.25625inā€}The set of color numbers is arranged so that each +color number is visually near each of its neighbors. Bright and dark +colors alternate for each family. Color numbers range from 0 to 99, like +crayon numbers, but you can use fractional numbers to get as tiny a step +as you like:

+ +

(ā€œAs tiny as you likeā€ isnā€™t quite true because in the end, your color +has to be rounded to integer RGB values for display.)

+ +

Both of these scales include the range of shades of gray, from black to +white. Since black is the initial pen color, and black isnā€™t a hue, +Scratch and Snap! users would traditionally try to use set color to +escape from black, and it wouldnā€™t work. By including black in the same +scale as other colors, we eliminate the Black Hole problem if people use +only the recommended color scales.

+ +

We are making a point of saying ā€œcolor numberā€ for what was sometimes +called just ā€œcolorā€ in earlier versions of the library, because we now +reserve the name ā€œcolorā€ for an actual color, an instance of the color +data type.
+How to Use the Library

+ +

There are three library blocks specifically about controlling the pen. +They have the same names as three of the primitive Pen blocks:

+ +

{width=ā€6.066666666666666inā€ +height=ā€0.30833333333333335inā€}

+ +

{width=ā€7.4875inā€ +height=ā€1.1inā€}The first (Pen block-colored) input slot is used to +select which color scale you want to use. (These blocks also allow +reading or setting two block properties that are not colors: the pen +size and its transparency.) The pen reporter requires no other inputs; +it reports the state of the pen in whatever dimension you choose.

+ +

As the last example shows, you canā€™t ask for the pen color in a scale +incompatible with how you set it, unless the block can deduce what you +want from what it knows about the current pen color.

+ +

The change pen block applies only to numeric scales (including vectors +of three or four numbers). It adds its numeric or list input to the +current pen value(s), doing vector (item-by-item) addition for vector +scales.

+ +

{width=ā€7.491666666666666inā€ +height=ā€1.1069444444444445inā€}The set pen block changes the pen color to +the value(s) you specify. The meaning of the white input slots depends +on which attribute of the pen youā€™re setting:

+ +

In the last example, the number 37 sets the transparency, on the scale +0=opaque, 100=invisible. (All color attributes are on a 0ā€“100 scale +except for RGB components, which are 0ā€“255.) A transparency value can +be combined with any of these attribute scales.

+ +

{width=ā€5.383333333333334inā€ +height=ā€0.23333333333333334inā€}The library also includes two +constructors and a selector for colors as a data type:

+ +

{width=ā€1.8055555555555556inā€ +height=ā€0.19444444444444445inā€}The latter two are inverses of each +other, translating between colors and their attributes. The color from +blockā€™s attribute menu has fewer choices than the similar set pen block +because you can, for example, set the Red value of the existing pen +color leaving the rest unchanged, but when creating a color out of +nothing you have to provide its entire specification, e.g., all of Red, +Green, and Blue, or the equivalent in other scales. (As youā€™ll see on +the next page, we provide two linear (one-dimensional) color scales +that allow you to specify a color with a single number, at the cost of +including only a small subset of the millions of colors your computer +can generate.) If you have a color and want another color thatā€™s the +same except for one number, as in the Red example, you can use this +block:

+ +

Finally, the library includes the mix block and a helper:

+ +

{width=ā€6.113194444444445inā€ +height=ā€0.23333333333333334inā€}Weā€™ll have more to say about these after +a detour through color theory.

+ +

Thatā€™s all you have to know about colors! Crayons for specific +interesting ones, color numbers for gradual transformation from one +color to the next. But thereā€™s a bit more to say, if youā€™re interested. +If not, stop here. (But look at the samples of the different scales on +page 145.)
+More about Colors: Fair Hues and Shades

+ +

Several of the three-dimensional arrangements of colors use the concept +of ā€œhue,ā€ which more or less means where a color would appear in a +rainbow (magenta, near the right, is a long +story):

+ +

{width=ā€5.806666666666667inā€ +height=ā€0.30666666666666664inā€}

+ +

These are called ā€œspectralā€ colors, after the spectrum of rainbow +colors. But these colors arenā€™t equally distributed. Thereā€™s an awful +lot of green, hardly any yellow, and just a sliver of orange. And no +brown at all.

+ +

And this is already a handwave, because the range of colors that can be +generated by RGB monitors doesnā€™t include some of the true spectral +colors. See Spectral +color in Wikipedia for +all the gory details.

+ +

This isnā€™t a problem with the physics of rainbows. Itā€™s in the human eye +and the human brain that certain ranges of wavelength of light waves are +lumped together as named colors. The eye is just ā€œtunedā€ to recognize a +wide range of colors as green. (See Rods and +Cones.) And +different human cultures give names to different color ranges. +Nevertheless, in old Scratch projects, youā€™d say change pen color by 1 +and itā€™d take forever to reach a color that wasnā€™t green.

+ +

{width=ā€5.9944444444444445inā€ +height=ā€0.29930555555555555inā€}For color professionals, there are good +reasons to want to work with the physical rainbow hue layout. But for +amateurs using a simplified, one-dimensional color model, thereā€™s no +reason not to use a more programmer-friendly hue scale:

+ +

{width=ā€1.4597222222222221inā€ +height=ā€1.3583333333333334inā€}In this scale, each of the seven rainbow +colors and brown get an equal share. (Redā€™s looks too small, but thatā€™s +because itā€™s split between the two ends: hue 0 is pure red, brownish +reds are to its right, and purplish reds are wrapped around to the right +end.) We call this scale ā€œfair hueā€ because each color family gets a +fair share of the total hue range. (By the way, you were probably taught +ā€œā€¦ green, blue, indigo, violetā€ in school, but it turns out that color +names were different in Isaac Newtonā€™s day, and the color he called +ā€œblueā€ is more like modern cyan, while his ā€œindigoā€ is more like modern +blue. See Wikipedia Indigo.)

+ +

{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}{width=ā€0.2361111111111111inā€ +height=ā€0.2361111111111111inā€}Our color number scale is based on fair +hues, adding a range of grays from black (color number 0) to white +(color number14) and also adding shades of the spectral colors. (In +color terminology, a shade is a darker version of a color; a lighter +version is called a tint.) Why do we add shades but not tints? Partly +because I find shades more exciting. A shade of red can be dark candy +apple red or maroon , but a tint is just some kind of pink . This +admitted prejudice is supported by an objective fact: Most projects are +made on a white background, so dark colors stand out better than light +ones.

+ +

{width=ā€5.999305555555556inā€ +height=ā€1.507638888888889inā€}So, in our color number scale, color +numbers 0 to 14 are kinds of gray; the remaining color numbers go +through the fair hues, but alternating full-strength colors with shades.

+ +

This chart shows how the color scales discussed so far are related. Note +that all scales range from 0 to 100; the fair hues scale has been +compressed in the chart so that similar colors line up vertically. (Its +dimensions are different because it doesnā€™t include the grays at the +left. Since there are eight color families, the pure, named fair hues +are at multiples of 100/8=12.5, starting with red=0.)

+ +

{width=ā€1.85inā€ +height=ā€1.0798611111111112inā€}White is crayon 14 and color number 14. +This value was deliberately chosen not to be a multiple of 5 so that +the every-fifth-crayon and every-tenth-crayon selections donā€™t include +it, so that all of the crayons in those smaller boxes are visible +against a white stage background.

+ +

Among purples, the official spectral violet (crayon 90) is the end of +the spectrum. Magenta, brighter than violet, isnā€™t a spectral color at +all. (In the picture at the left, the top part is the spectrum of white +light spread out through a prism; the middle part is a photograph of a +rainbow, and the bottom part is a digital simulation of a rainbow.) +Magenta is a mixture of red and blue. (attribution: Wikipedia user +Andys. CC BY-SA.)

+ +

The light gray at color number 10 is slightly different from crayon 10 +just because of roundoff in computing crayon values. Color number 90 is +different from crayon 90 because the official RGB violet (equal parts +red and blue) is actually lighter than spectral violet. The purple +family is also unusual because magenta, crayon and color number 95, is +lighter than the violet at 90. In other families, the color numbers, +crayons, and (scaled) fair hues all agree at multiples of ten. These +multiple-of-ten positions are the standard RGB primary and secondary +colors, e.g., the yellow at color number 50 is (255, 255, 0) in RGB. +(Gray, brown, and orange donā€™t have such simple RGB settings.)

+ +

The color numbers at odd multiples of five are generally darker shades +than the corresponding crayons. The latter are often official named +shades, e.g., teal, crayon 65, is a half-intensity shade of cyan. The +odd-five color numbers, though, are often darker, since they are +chosen to be the darkest color in a given family thatā€™s visibly +different from black. The pink at color number 15, though, is quite +different from crayon 15, because the former is a pure tint of red, +whereas the crayon, to get a more interesting pink, has a little magenta +mixed in. Color numbers at multiples of five are looked up in a table; +other color values are determined by linear interpolation in RGB space. +(Crayons are of course all found by table lookup.)

+ +

The from color block behaves specially when you ask for the color +number of a color. Most colors donā€™t exactly match a color number, and +for other attributes of a color (crayon number, X11 name) you donā€™t get +an answer unless the color exactly matches one of the names or numbers +in that attribute. But for color number, the block tries to find the +nearest color number to the color you specify. The result will be only +approximate; you canā€™t use the number you get to recreate the input +color. But you can start choosing nearby color numbers as you animate +the sprite.

+ +

Perceptual Spaces: HSV and HSL

+ +

{width=ā€0.7361111111111112inā€ +height=ā€0.7222222222222222inā€}RGB is the right way to think about colors +if youā€™re building or programming a display monitor; CMYK is the right +way if youā€™re building or programming a color printer. But neither of +those coordinate systems is very intuitive if youā€™re trying to +understand what color you see if, for example, you mix 37% red light, +52% green, and 11% blue. The hue scale is one dimension of most +attempts at a perceptual scale. The square at the right has pale blues +along the top edge, dark blues along the right edge, various shades of +gray toward the left, black at the bottom, and pure spectral blue in the +top right corner. Although no other point in the square is pure blue, +you can tell at a glance that no other spectral color is mixed with the +blue.

+ +

{width=ā€2.691666666666667inā€ +height=ā€1.1902777777777778inā€}Aside from hue, the other two dimensions +of a color space have to represent how much white and/or black is mixed +with the spectral color. (Bear in mind that ā€œmixing blackā€ is a metaphor +when it comes to monitors. There really is black paint, but thereā€™s no +such thing as black light.) One such space, HSV, has one dimension for +the amount of color (vs. white), called saturation, and one for the +amount of black, imaginatively called value. HSV stands for +Hue-Saturation-Value. (Value is also called brightness.) The value +is actually measured backward from the above description; that is, if +value is 0, the color is pure black; if value is 100, then a saturation +of 0 means all white, no spectral color; a saturation of 100 means no +white at all. In the square in the previous paragraph, the x axis is +the saturation and the y axis is the value. The entire bottom edge is +black, but only the top left corner is white. HSV is the traditional +color space used in Scratch and Snap!. Set pen color set the hue; set +pen shade set the value. There was originally no Pen block to set the +saturation, but thereā€™s a set brightness effect Looks block to control +the saturation of the spriteā€™s costume. (I speculate that the Scratch +designers, like me, thought tints were less vivid than shades against a +white background, so they made it harder to control tinting.)

+ +

{width=ā€1.5638888888888889inā€ +height=ā€0.29305555555555557inā€}{width=ā€1.5555555555555556inā€ +height=ā€0.2659722222222222inā€}{width=ā€0.7638888888888888inā€ +height=ā€0.7638888888888888inā€}But if youā€™re looking at colors on a +computer display, HSV isnā€™t really a good match for human perception. +Intuitively, black and white should be treated symmetrically. This is +the HSL (hue-saturation-lightness) color space. Saturation, in HSL, is +a measure of the grayness or dullness of a color (how close it comes +to being on a black-and-white scale) and lightness measures +spectralness with pure white at one end, pure black at the other end, +and spectral color in the middle. The saturation number is actually +the opposite of grayness: 0 means pure gray, and 100 means pure spectral +color, provided that the lightness is 50, midway between black and +white. Colors with lightness other than 50 have some black or white +mixed in, but saturation 100 means that the color is as fully saturated +as it can be, given the amount of white or black needed to achieve that +lightness. Saturation less than 100 means that both white and black +are mixed with the spectral color. (Such mixtures are called tones of +the spectral color. Perceptually, colors with saturation 100% donā€™t look +gray: but colors with saturation 75% do:

+ +

Note that HSV and HSL both have a dimension called ā€œsaturation,ā€ but +theyā€™re not the same thing! In HSV, ā€œsaturationā€ means non-whiteness, +whereas in HSL it means non-grayness (vividness).

+ +

More fine print: Itā€™s misleading to talk about the spectrum of light +wavelengths as if it were the same as perceived hue. If your computer +display is showing you a yellow area, for example, itā€™s doing it by +turning on its red and green LEDs over that area, and what hits your +retina is still two wavelengths of light, red and green, superimposed. +You could make whatā€™s perceptually the same yellow by using a single +intermediate wavelength. Your eye and brain donā€™t distinguish between +those two kinds of yellow. Also, your brain automatically adjusts +perceived hue to correct for differences in illumination. When you place +a monochrome object so that itā€™s half in sunlight and half in the shade, +you see it as one even though whatā€™s reaching your eyes from the two +regions differs a lot. And, sadly, itā€™s HSL whose use of ā€œsaturationā€ +disagrees with the official international color vocabulary +standardization committee. I learned all this from this +tutorial, which you might find +more coherent than jumping around Wikipedia if youā€™re interested.

+ +

{width=ā€1.64375inā€ +height=ā€0.8416666666666667inā€}Although traditional Scratch and Snap! +use HSV in programs, they use HSL in the color picker. The horizontal +axis is hue (fair hue, in this version) and the vertical axis is +lightness, the scale with black at one end and white at the other end. +It would make no sense to have only the bottom half of this selector +(HSV Value) or only the top half (HSV Saturation). And, given that you +can only fit two dimensions on a flat screen, it makes sense to pick HSL +saturation (vividness) as the one to keep at 100%. (In this fair-hue +picker, some colors appear twice: ā€œspectralā€ (50% lightness) browns as +shades (ā‰ˆ33% lightness) of red or orange, and shades of those browns.)

+ +

{width=ā€0.20277777777777778inā€ +height=ā€0.20277777777777778inā€}{width=ā€0.18888888888888888inā€ +height=ā€0.18888888888888888inā€}Software that isnā€™t primarily about +colors (so, not including Photoshop, for example) typically use HSV or +HSL, with web-based software more likely to use HSV because thatā€™s +whatā€™s built into the JavaScript programming language provided by +browsers. But if the goal is to model human color perception, neither of +these color spaces is satisfactory, because they assume that all +full-intensity spectral colors are equally bright. But if youā€™re like +most people, you see spectral yellow as much brighter than spectral blue +. There are better perceptual color spaces with names like L*u*v* and +L*a*b* that are based on research with human subjects to determine +true perceived brightness. Wikipedia explains all this and more at HSL +and HSV, where they +recommend ditching both of these simplistic color spaces.

+ +

Mixing Colors

+ +

Given first class colors, the next question is, what operations apply to +them, the way arithmetic operators apply to numbers and higher order +functions apply to lists? The equivalent to adding numbers is mixing +colors, but unfortunately there isnā€™t a simple answer to what that +means.

+ +

{width=ā€4.347222222222222inā€ +height=ā€0.5625inā€}The easiest kind of color mixing to understand is +additive mixing, which is what happens when you shine two colored +lights onto a (white) wall. Itā€™s also what happens in your computer +screen, where each dot (pixel) of an image is created by a tiny red +light, a tiny green light, and a tiny blue light that can be combined at +different strengths to make different colors. Essentially, additive +mixing of two colors is computed by adding the two red components, the +two green components, and the two blue components. Itā€™s not quite that +simple only because each component of the result must be in the range 0 +to 255. So, red (255, 0, 0) mixed with green (0, 255, 0) gives (255, +255, 0), which is yellow. But red (255, 0, 0) plus yellow (255, 255, 0) +canā€™t give (510, 255, 0). Just limiting the red in the result to 255 +would mean that red plus yellow is yellow, which doesnā€™t make sense. +Instead, if the red value has to be reduced by half (from 510 to 255), +then all three values must be reduced by half, so the result is (255, +128, 0), which is orange. (Half of 255 is 127.5, but each RGB value must +be an integer.)

+ +

{width=ā€4.492361111111111inā€ +height=ā€0.55inā€}A different kind of color mixing based on light is done +when different colored transparent plastic sheets are held in front of a +white light, as is done in theatrical lighting. In that situation, the +light that gets through both filters is what remains after some light is +filtered out by the first one and some of whatā€™s left is filtered out by +the second one. In red-green-blue terms, a red filter filters out green +and blue; a yellow filter allows red and green through, filtering out +blue. But there isnā€™t any green light for the yellow filter to pass; it +was filtered out by the red filter. Each filter can only remove light, +not add light, so this is called subtractive mixing:

+ +

Perhaps confusingly, the numerical computation of subtractive mixing is +done by multiplying the RGB values, taken as fractions of the maximum +255, so red (1, 0, 0) times yellow (1, 1, 0) is red again.

+ +

Those are both straightforward to compute. Much, much more complicated +is trying to simulate the result of mixing paints. Itā€™s not just that +weā€™d have to compute a more complicated function of the red, green, and +blue values; itā€™s that RGB values (or any other three-dimensional color +space) are inadequate to describe the behavior of paints. Two paints can +look identical, and have the same RGB values, but may still behave very +differently when mixed with other colors. The differences are mostly due +to the chemistry of the paints, but are also affected by exactly how the +colors are mixed. The mixing is mostly subtractive; red paint absorbs +most of the colors other than red, so whatā€™s reflected off the surface +is whatever isnā€™t absorbed by the colors being mixed. But there can be +an additive component also.

+ +

{width=ā€7.5inā€ +height=ā€0.875inā€}The proper mathematical abstraction to describe a paint +is a reflectance graph, like this:

+ +

(These arenā€™t paints, but minerals, and one software-generated spectrum, +from the US Geological Surveyā€™s Spectral +Library. +The details donā€™t matter, just the fact that a graph like these gives +much more information than three RGB numbers.) To mix two paints +properly, you multiply the y values (as fractions) at each matching +x coordinate of the two graphs.

+ +

{width=ā€4.627777777777778inā€ +height=ā€0.5763888888888888inā€} Having said all that, the mix block takes +the colors it is given as inputs and converts them into what we hope are +typical paint reflectance spectra that would look like those colors, +and then mixes those spectra and converts back to RGB.

+ +

But unlike the other two kinds of mixing, in this case we canā€™t say that +these colors are ā€œthe right answerā€; what would happen with real paints +depends on their chemical composition and how theyā€™re mixed. There are +three more mixing options, but these three are the ones that correspond +to real-world color mixing.

+ +

{width=ā€4.340277777777778inā€ +height=ā€0.6527777777777778inā€}The mix block will accept any number of +colors, and will mix them in equal proportion. If (for any kind of +mixing) you want more of one color than another, use the color at weight +block to make a ā€œweighted colorā€:

+ +

{width=ā€5.166666666666667inā€ +height=ā€0.4305555555555556inā€}This mixes four parts red paint to one +part green paint. All colors in a mixture can be weighted:

+ +

(Thanks to Scott +Burns for his help in +understanding paint mixing, along with David +Briggsā€™s tutorial. Remaining +mistakes are bhā€™s.)

+ +

tl;dr

+ +

{width=ā€1.9326388888888888inā€ +height=ā€2.220833333333333inā€}{width=ā€2.227777777777778inā€ +height=ā€2.267361111111111inā€}For normal people, Snap! provides three +simple, one-dimensional scales: [crayons]{.underline} for specific +interesting colors, [color numbers]{.underline} for a continuum of +high-contrast colors with a range of hues and shading, and [fair +hues]{.underline} for a continuum without shading. For color nerds, it +provides three-dimensional color spaces RGB, HSL, HSV, and fair-hue +variants of the latter two. We recommend ā€œfair HSLā€ for zeroing in on a +desired color.

+ +

{width=ā€1.5347222222222223inā€ +height=ā€1.8472222222222223inā€}

+ +

{width=ā€2.2111111111111112inā€ height=ā€2.267361111111111inā€}{width=ā€2.061111111111111inā€ height=ā€2.2222222222222223inā€}{width=ā€1.9152777777777779inā€ height=ā€2.234722222222222inā€} Subappendix: Geeky details on fair hue

+ +

{width=ā€6.2375inā€ +height=ā€2.5inā€}The left graph shows that, unsurprisingly, all of the +brown fair hues make essentially no progress in real hue, with the +orange-brown section actually a little retrograde, since browns are +really shades of orange and so the real hues overlap between fair browns +and fair oranges. Green makes up some of the distance, because there are +too many green real hues and part of the goal of the fair hue scale is +to squeeze that part of the hue spectrum. But much of the catching up +happens very quickly, between pure magenta at fair hue 93.75 and the +start of the purple-red section at fair hue 97. This abrupt change is +unfortunate, but the alternatives involve either stealing space from red +or stealing space from purple (which already has to include both +spectral violet and RGB magenta). The graph has discontinuous derivative +at the table-lookup points, of which there are two in each color family, +one at the pure-named-RGB colors at multiples of 12.5, and the other +roughly halfway to the next color family, except for the purple +family, which has lookup points at 87.5 (approximate spectral violet), +93.75 (RGB magenta), and 97 (turning point toward the red family). (In +the color picker, blue captures cyan and purple space in dark shades. +This, too, is an artifact of human vision.)

+ +

The right graph shows the HSV saturation and value for all the fair +hues. Saturation is at 100%, as it should be in a hue scale, except for +a very slight drop in part of the browns. (Browns are shades of orange, +not tints, so one would expect full saturation, except that some of the +browns are actually mixtures with related hues.) But value, also as +expected, falls substantially in the browns, to a low of about 56% +(halfway to black) for the ā€œpureā€ brown at 45Ā° (fair hue 12.5). But the +curve is smooth, without inflection points other than that minimum-value +pure brown.

+ +

ā€œFair saturationā€ and ā€œfair valueā€ are by definition 100% for the entire +range of fair hues. This means that in the browns, the real saturation +and value are the product (in percent) of the innate shading of the +specific brown fair hue and the userā€™s fair saturation/value setting. +When the userā€™s previous color setting was in a real scale and the new +setting is in a fair scale, the program assumes that the previous +saturation and value were entirely user-determined; when the previous +color setting was in a brown fair hue and the new setting is also in a +fair scale, the program remembers the userā€™s intention from the previous +setting. (Internal calculations are based on HSV, even though we +recommend HSL to users, because HSV comes to us directly from the +JavaScript color management implementation.) This is why the set pen +block includes options for ā€œfair saturationā€ and so on.

+ +

{width=ā€5.9875inā€ +height=ā€0.3784722222222222inā€}For the extra-geeky, here are the exact +table lookup points (fair hue, [0,100]):

+ +

and here are the RGB settings at those points:

+ +

{width=ā€5.9840277777777775inā€ height=ā€1.3736111111111111inā€} Subappendix: Geeky details on color numbers

+ +

{width=ā€2.0833333333333335inā€ +height=ā€2.2916666666666665inā€}Here is a picture of integer color +numbers, but remember that color numbers are continuous. (As usual, +ā€œcontinuousā€ values are ultimately converted to integer RGB values, so +thereā€™s really some granularity.) Color numbers 0-14 are continuously +varying grayscale, from 0=black to 14=white. Color numbers 14+Īµ to 20 +are linearly varying shades of pink, with RGB Red at color number 20.

+ +

Beyond that point, in each color family, the multiple of ten color +number in the middle is the RGB standard color of that family, in which +each component is either 255 or 0. (Exceptions are brown, which is of +course darker than any of those colors; orange, with its green component +half-strength: [255, 127, 0]; and violet, discussed below.) The +following multiple of five is the number of the darkest color in that +family, although not necessarily the same hue as the multiple of ten +color number. Color numbers between the multiple of ten and the +following multiple of five are shades of colors entirely within the +family. Color numbers in the four before the multiple of ten are +mixtures of this family and the one before it. So, for example, in the +green family, we have

+ +

55 Darkest yellow.

+ +

(55, 60) shades of yellow-green mixtures. As the color number increases, +both the hue and the lightness (or value, depending on your religion) +increase, so we get brighter and greener colors.

+ +

60 Canonical green, [0, 255, 0], whose W3C color name is ā€œlime,ā€ not +ā€œgreen.ā€

+ +

(60, 65) Shades of green. No cyan mixed in.

+ +

65 Darkest green.

+ +

(65,70) Shades of green-cyan mixtures.

+ +

In the color number chart, all the dark color numbers look a lot like +black, but theyā€™re quite different. Here are the darkest colors in each +color number family.

+ +

{width=ā€1.3888888888888888inā€ +height=ā€1.3888888888888888inā€}Darkest yellow doesnā€™t look entirely +yellow. You might see it as greenish or brownish. As it turns out, the +darkest color that really looks yellow is hardly dark at all. This color +was hand-tweaked to look neither green nor brown to me, but ymmv.

+ +

In some families, the center+5 crayon is an important named darker +version of the center color: In the red family, [128, 0, 0] is +ā€œmaroon.ā€ In the cyan family, [0, 128, 128] is ā€œteal.ā€ An early +version of the color number scale used these named shades as the +center+5 color number also. But on this page we use the word ā€œdarkestā€ +advisedly: You canā€™t find a darker shade of this family anywhere in the +color number scale, but you can find lighter shades. Teal is color +number 73.1, ($70 + 5 \bullet \frac{255 - 128}{255 - 50}$), because +darkest cyan, color 75, is [0, 50, 50]. The color number for maroon is +left as an exercise for the reader.

+ +

The purple family is different from the others, because it has to +include both spectral violet and extraspectral RGB magenta. Violet is +usually given as RGB [128, 0, 255], but thatā€™s much brighter than the +violet in an actual spectrum (see page 142). We use [80, 0, 90], a +value hand-tweaked to look as much as possible like the violet in +rainbow photos, as color number 90. (Crayon 90 is [128, 0, 255].) +Magenta, [255, 0, 255], is color number 95. This means that the colors +get brighter, not darker, between 90 and 95. The darkest violet is +actually color number 87.5, so itā€™s bluer than standard violet, but +still plainly a purple and not a blue. Itā€™s [39,0,76]. Itā€™s not +hand-tweaked; itā€™s a linear interpolation between darkest blue, [0, 0, +64], and the violet at color number 90. I determined by experiment that +color number 87.5 is the darkest one thatā€™s still unambiguously purple. +(According to Wikipedia, ā€œvioletā€ names only the spectral color, while +ā€œpurpleā€ is the name of the whole color family.)

+ +

Here are the reference points for color numbers that are multiples of +five, except for item 4, which is used for color 14, not color 15:

+ +

{width=ā€4.583333333333333inā€ +height=ā€1.2777777777777777inā€}

+ +

Appendix B. APL features {#appendix-b.-apl-features .ListParagraph}

+ +

The book A Programming Language was published by mathematician Kenneth +E. Iverson in 1962. He wanted a formal language that would look like +what mathematicians write on chalkboards. The then-unnamed language +would later take its name from the first letters of the words in the +bookā€™s title. It was little-known until 1964, when a formal description +of the just-announced IBM System/360 in the IBM Systems Journal used +APL notation. (Around the same time, Iversonā€™s associate Adin Falkoff +gave a talk on APL to a New York Association for Computing Machinery +chapter, with an excited 14-year-old Brian Harvey in the audience.) But +it wasnā€™t until 1966 that the first public implementation of the +language for the System/360 was published by IBM. (It was called +ā€œAPL\360ā€ because the normal slash character / represents the ā€œreduceā€ +operator in APL, while backslash is ā€œexpand.ā€)

+ +

The crucial idea behind APL is that mathematicians think about +collections of numbers, one-dimensional vectors and two-dimensional +matrices, as valid objects in themselves, what computer scientists +later learned to call ā€œfirst class data.ā€ A mathematician who wants to +add two vectors writes v~1~ + v~2~, not ā€œfor i = 1 to +length(v1), result[i]=v1[i]+v2[i].ā€ Same for a programmer using +APL.

+ +

There are three kinds of function in APL: scalar functions, mixed +functions, and operators. A scalar function is one whose natural +domain is individual numbers or text characters. A mixed function is +one whose domain includes arrays (vectors, matrices, or +higher-dimensional collections). In Snap!, scalar functions are +generally found in the green Operators palette, while mixed functions +are in the red Lists palette. The third category, confusingly for +Snap! users, is called operators in APL, but corresponds to what we +call higher order functions: functions whose domain includes functions.

+ +

Snap! hyperblocks are scalar functions that behave like APL scalar +functions: they can be called with arrays as inputs, and the underlying +function is applied to each number in the arrays. (If the function is +monadic, meaning that it takes one input, then thereā€™s no complexity +to this idea. Take the square root of an array, and you are taking the +square root of each number in the array. If the function is dyadic, +taking two inputs, then the two arrays must have the same shape. Snap! +is more forgiving than APL; if the arrays donā€™t agree in number of +dimensions, called the rank of the array, the lower-rank array is +matched repeatedly with subsets of the higher-rank one; if they donā€™t +agree in length along one dimension, the result has the shorter length +and some of the numbers in the longer-length array are ignored. An +exception in both languages is that if one of the two inputs is a +scalar, then it is matched with every number in the other array input.)

+ +

As explained in Section I.G, this termwise extension of scalar functions +is the main APL-like feature built into Snap! itself. We also include +an extension of the item block to address multiple dimensions, an +extension to the length block with five list functions from APL, and a +new primitive reshape block. The APL library extends the implementation +of APL features to include a few missing scalar functions and several +missing mixed functions and operators.

+ +

Programming in APL really is very different in style from programming +in other languages, even Snap!. This appendix canā€™t hope to be a +complete reference for APL, let alone a tutorial. If youā€™re interested, +find one of those in a library or a (probably used) bookstore, read it, +and do the exercises. Sorry to sound like a teacher, but the notation +is sufficiently weird as to take a lot of practice before you start to +think in APL.

+ +

A note on versions: There is a widely standardized APL2, several +idiosyncratic extensions, and a successor language named J. The latter +uses plain ASCII characters, unlike the ones with APL in their names, +which use the mathematicianā€™s character set, with Greek letters, +typestyles (boldface and/or italics in books; underlined, upper case, or +lower case in APL) as loose type declarations, and symbols not part of +anyoneā€™s alphabet, such as āŒŠ for floor and āŒˆ for ceiling. To use the +original APL, you needed expensive special computer terminals. (This was +before you could download fonts in software. Today the more unusual APL +characters are in Unicode at U+2336 to U+2395.) The character set was +probably the main reason APL didnā€™t take over the world. APL2 has a lot +to recommend it for Snap! users, mainly because it moves from the +original APL idea that all arrays must be uniform in dimension, and the +elements of arrays must be numbers or single text characters, to our +idea that a list can be an element of another list, and that such +elements donā€™t all have to have the same dimensions. Nevertheless, its +mechanism for allowing both old-style APL arrays and more general +ā€œnested arraysā€ is complicated and hard for an APL beginner (probably +all but two or three Snap! users) to understand. So we are starting +with plain APL. If it turns out to be wildly popular, we may decide +later to include APL2 features.

+ +

Here are some of the guiding ideas in the design of the APL library:

+ +

{width=ā€4.451388888888889inā€ +height=ā€0.5208333333333334inā€}Goal:Ā  Enable interested Snap! users +to learn the feel and style of APL programming. Itā€™s really worth the +effort. For example, we didnā€™t hyperize the = block because Snap! +users expect it to give a single yes-or-no answer about the equality of +two complete structures, whatever their types and shapes. In APL, = is a +scalar function; it compares two numbers or two characters. How could +APL users live without the ability to ask if two structures are equal? +Because in APL you can say āˆ§/,a=b to get that answer. Reading from +right to left, a=b reports an array of Booleans (represented in APL as 0 +for False, 1 for True); the comma operator turns the shape of the array +into a simple vector; and āˆ§/ means ā€œreduce with andā€; ā€œreduceā€ is +our combine function. That six-character program is much less effort +than the equivalent

+ +

{width=ā€0.9930555555555556inā€ +height=ā€0.20833333333333334inā€}in Snap!. Note in passing that if you +wanted to know how many corresponding elements of the two arrays are +equal, youā€™d just use +/ instead of āˆ§/. Note also that our APLish +blocks are a little verbose, because they include up to three notations +for the function: the usual Snap! name (e.g., flatten), the name APL +programmers use when talking about it (ravel), and, in yellow type, the +symbol used in actual APL code (,). Weā€™re not consistent about it; seems +self-documenting. And LCM (and) is different even though it has two +names; it turns out that if you represent Boolean values as 0 and 1, +then the algorithm to compute the least common multiple of two integers +computes the and function if the two inputs happen to be Boolean. +Including the APL symbols serves two purposes: the two or three Snap! +users whoā€™ve actually programmed in APL will be sure what function +theyā€™re using, but more importantly, the ones who are reading an APL +tutorial while building programs in Snap! will find the block that +matches the APL theyā€™re reading.
+
+Goal:Ā  Bring the best and most general APL ideas into ā€œmainstreamā€ +Snap! programming style. Media computation, in particular, becomes +much simpler when scalar functions can be applied to an entire picture +or sound. Yes, map provides essentially the same capability, but the +notation gets complicated if you want to map over columns rather than +rows. Also, Snap! lists are fundamentally one-dimensional, but real +data often have more dimensions. A Snap! programmer has to be thinking +all the time about the convention that we represent a matrix as a list +of rows, each of which is a list of individual cells. That is, row 23 of +a spreadsheet is item 23 of spreadsheet, but column 23 is map (item 23 +of _) over spreadsheet. APL treats rows and columns more +symmetrically.
+
+Non-goal:Ā  Allow programs written originally in APL to run in +Snap! essentially unchanged.Ā  For example, in APL the atomic text +unit is a single character, and strings of characters are lists. We +treat a text string as scalar, and that isnā€™t going to change. Because +APL programmers rarely use conditionals, instead computing functions +involving arrays of Boolean values to achieve the same effect, the +notation they do have for conditionals is primitive (in the sense of +Paleolithic, not in the sense of built in). Weā€™re not changing ours.
+
+Non-goal:Ā  Emulate the terse APL syntax. Itā€™s too bad, in a way; as +noted above, the terseness of expressing a computation affects APL +programmersā€™ sense of whatā€™s difficult and what isnā€™t. But you canā€™t say +ā€œterseā€ and ā€œblock languageā€ in the same sentence. Our whole raison +dā€™ĆŖtre is to make it possible to build a program without having to +memorize the syntax or the names of functions, and to allow those names +to be long enough to be self-documenting. And APLā€™s syntax has its own +issues, of which the biggest is that itā€™s hard to use functions with +more than two inputs; because most mathematical dyadic functions use +infix notation (the function symbol between the two inputs), the notion +of ā€œleft argumentā€ and ā€œright argumentā€ is universal in APL +documentation. The thing people most complain about, that there is no +operator precedence (like the multiplication-before-addition rule in +normal arithmetic notation), really doesnā€™t turn out to be a problem. +Function grouping is strictly right to left, so 2Ɨ3+4 means two times +seven, not six plus four. That takes some getting used to, but it really +doesnā€™t take long if you immerse yourself in APL. The reason is that +there are too many infix operators for people to memorize a precedence +table. But in any case, block notation eliminates the problem, +especially with Snap!ā€™s zebra coloring. You can see and control the +grouping by which block is inside which other blockā€™s input slot. +Another problem with APLā€™s syntax is that it bends over backward not to +have reserved words, as opposed to Fortran, its main competition back +then. So the dyadic ā—‹ ā€œcircular functionsā€ function uses the left +argument to select a trig function. 1ā—‹x is sin(x), 2ā—‹x is +cos(x), and so on. ā€¾1ā—‹x is arcsin(x). Whatā€™s 0ā—‹x? Glad you +asked; itā€™s$\ \sqrt{1 - x^{2}}$.

+ +

Boolean values

+ +

Snap! uses distinct Boolean values true and false that are different +from other data types. APL uses 1 and 0, respectively. The APL style of +programming depends heavily on doing arithmetic on Booleans, although +their conditionals insist on only 0 or 1 in a Boolean input slot, not +other numbers. Snap! arithmetic functions treat false as 0 and true +as 1, so our APL library tries to report Snap! Boolean values from +predicate functions.

+ +

{width=ā€5.733333333333333inā€ height=ā€1.1066666666666667inā€}Scalar functions

+ +

{width=ā€2.566666666666667inā€ +height=ā€0.21666666666666667inā€}These are the scalar functions in the APL +library. Most of them are straightforward to figure out. The scalar = +block provides an APL-style version of = (and other exceptions) as a +hyperblock that extends termwise to arrays. Join, the only non-predicate +non-hyper scalar primitive, has its own scalar join block. 7 deal 52 +reports a random vector of seven numbers from 1 to 52 with no +repetitions, as in dealing a hand of cards. Signum of a number reports 1 +if the number is positive, 0 if itā€™s zero, or -1 if itā€™s negative. Roll +6 reports a random roll of a six-sided die. To roll 8 dice, use , which +would look much more pleasant as ?8ā“6. But perhaps our version is more +instantly readable by someone who didnā€™t grow up with APL. All the +library functions have help messages available.

+ +

Mixed functions

+ +

Mixed functions include lists in their natural domain or range. That is, +one or both of its inputs must be a list, or it always reports a list. +Sometimes both inputs are naturally lists; sometimes one input of a +dyadic mixed function is naturally a scalar, and the function treats a +list in that input slot as an implicit map, as for scalar functions. +This means you have to learn the rule for each mixed function +individually.

+ +

{width=ā€4.275inā€ +height=ā€1.1inā€}{width=ā€1.0666666666666667inā€ +height=ā€0.18333333333333332inā€}The shape of function takes any input and +reports a vector of the maximum size of the structure along each +dimension. For a vector, it returns a list of length 1 containing the +length of the input. For a matrix, it returns a two-item list of the +number of rows and number of columns of the input. And so on for higher +dimensions. If the input isnā€™t a list at all, then it has zero +dimensions, and shape of reports an empty vector.

+ +

Equivalent to the dimensions of primitive, as of 6.6.

+ +

{width=ā€1.0416666666666667inā€ +height=ā€0.18333333333333332inā€}{width=ā€2.033333333333333inā€ +height=ā€0.18333333333333332inā€}Rank of isnā€™t an actual APL primitive, +but the composition ā“ā“ (shape of shape of a structure), which reports +the number of dimensions of the structure (the length of its shape +vector), is too useful to omit. (Itā€™s very easy to type the same +character twice on the APL keyboard, but less easy to drag blocks +together.) Equivalent to the rank of primitive, as of 6.6.

+ +

{width=ā€7.325inā€ +height=ā€0.8333333333333334inā€}Reshape takes a shape vector (such as +shape might report) on the left and any structure on the right. It +ignores the shape of the right input, stringing the atomic elements into +a vector in row-major order (that is, all of the first row left to +right, then all of the second row, etc.). (The primitive reshape takes +the inputs in the other order.) It then reports an array with the shape +specified by the first input containing the items of the second:

+ +

{width=ā€6.575inā€ +height=ā€1.0416666666666667inā€}If the right input has more atomic +elements than are required by the left-input shape vector, the excess +are ignored without reporting an error. If the right input has too few +atomic elements, the process of filling the reported array starts again +from the first element. This is most useful in the specific case of an +atomic right input, which produces an array of any desired shape all of +whose atomic elements are equal. But other cases are sometimes useful +too:

+ +

{width=ā€5.508333333333334inā€ +height=ā€1.25inā€}
+{width=ā€1.4333333333333333inā€ +height=ā€0.18333333333333332inā€}Flatten takes an arbitrary structure as +input and reports a vector of its atomic elements in row-major order. +Lispians call this flattening the structure, but APLers call it ā€œravelā€ +because of the metaphor of pulling on a ball of yarn, so what they +really mean is ā€œunravel.ā€ (But the snarky sound of that is uncalled-for, +because a more advanced version that we might implement someday is more +like raveling.) One APL idiom is to apply this to a scalar in order to +turn it into a one-element vector, but we canā€™t use it that way because +you canā€™t type a scalar value into the List-type input slot. Equivalent +to the primitive flatten of block.

+ +

{width=ā€3.3618055555555557inā€ +height=ā€0.25inā€}

+ +

{width=ā€7.204166666666667inā€ +height=ā€0.5833333333333334inā€}Catenate is like our primitive append, +with two differences: First, if either input is a scalar, it is treated +like a one-item vector. Second, if the two inputs are of different rank, +the catenate function is recursively mapped over the higher-rank input:

+ +

{width=ā€0.5333333333333333inā€ +height=ā€0.25inā€}Catenate vertically is similar, but it adds new rows +instead of adding new columns.

+ +

{width=ā€6.341666666666667inā€ +height=ā€1.0416666666666667inā€}Integers (I think thatā€™s what it stands +for, although APLers just say ā€œiotaā€) takes a positive integer input and +reports a vector of the integers from 1 to the input. This is an example +of a function classed as ā€œmixedā€ not because of its domain but because +of its range. The difference between this block and the primitive +numbers from block is in its treatment of lists as inputs. Numbers from +is a hyperblock, applying itself to each item of its input list:

+ +

{width=ā€6.025inā€ +height=ā€0.8333333333333334inā€}Iota has a special meaning for list +inputs: The input must be a shape vector; the result is an array with +that shape in which each item is a list of the indices of the cell along +each dimension. A picture is worth 10^3^ words, but Snap! isnā€™t so +good at displaying arrays with more than two dimensions, so here we +reduce each cellā€™s index list to a string:

+ +

{width=ā€1.475inā€ +height=ā€0.25inā€}

+ +

{width=ā€5.95inā€ +height=ā€1.1inā€}Dyadic iota is like the index of primitive except for its +handling of multi-dimensional arrays. It looks only for atomic elements, +so a vector in the second input doesnā€™t mean to search for that vector +as a row of a matrix, which is what it means to index of, but rather to +look separately for each item of the vector, and report a list of the +locations of each item. If the first input is a multi-dimensional array, +then the location of an item is a vector with the indices along each +row.

+ +

In this example, the 4 is in the second row, second column. (This is +actually an extension of APL iota, which is more like a hyperized index +of.) Generalizing, if the rank of the second input is less than the rank +of the first input by two or more, then iota looks for the entire second +input in the first input. The reported position is a vector +{width=ā€5.841666666666667inā€ +height=ā€0.35inā€}whose length is equal to the difference between the two +ranks. If the rank of the second input is one less than the rank of the +first, the reported value is a scalar, the index of the entire second +input in the first.

+ +

{width=ā€5.383333333333334inā€ +height=ā€1.1inā€}

+ +

{width=ā€5.375inā€ +height=ā€3.2416666666666667inā€}Why the strange design decision to report +length+1 when something isnā€™t found, instead of a more obvious flag +value such as 0 or false? Hereā€™s why:

+ +

{width=ā€2.175inā€ +height=ā€0.225inā€}Note that code has 27 items, not 26. The asterisk at +the end is the ciphertext is the translation of all non-alphabet +characters (spaces and the apostrophe in ā€œdoesnā€™tā€). This is a silly +example, because it makes up a random cipher every time itā€™s called, and +it doesnā€™t report the cipher, so the recipient canā€™t decipher the +message. And you wouldnā€™t want to make the spaces in the message so +obvious. But despite being silly, the example shows the benefit of +reporting length+1 as the position of items not found.

+ +

{width=ā€7.485416666666667inā€ +height=ā€0.6597222222222222inā€}The contained in block is like a hyperized +contains with the input order reversed. It reports an array of Booleans +the same shape as the left input. The shape of the right input doesnā€™t +matter; the block looks only for atomic elements.

+ +

{width=ā€2.6645833333333333inā€ +height=ā€0.31666666666666665inā€}The blocks grade up and grade down are +used for sorting data. Given an array as input, it reports a vector of +the indices in which the items (the rows, if a matrix) should be +rearranged in order to be sorted. This will be +{width=ā€7.4944444444444445inā€ +height=ā€1.8069444444444445inā€}clearer with an example:

+ +

The result from grade up tells us that item 3 of foo comes first in +sorted order, then item 4, then 2, then 1. When we actually select items +of foo based on this ordering, we get the desired sorted version. +The result reported by grade down is almost the reverse of that from +grade up, but not quite, if there are equal items in the list. (The sort +is stable, so if there are equal items, then whichever comes first in +the input list will also be first in the sorted list.)

+ +

Why this two-step process? Why not just have a sort primitive in APL? +One answer is that in a database application you might want to sort one +array based on the order of another array:

+ +

This is the list of employees of a small company. (Taken from Structure +and Interpretation of Computer Programs by Abelson and Sussman. +Creative Commons licensed.) Each of the smaller lists contains a +person's name, job title, and yearly salary. +{width=ā€5.483333333333333inā€ +height=ā€2.2inā€}We would like to sort the employeesā€™ names in +big-to-small order of salary. First we extract column 3 of the database, +the salaries:

+ +

{width=ā€3.5590277777777777inā€ +height=ā€1.976388888888889inā€}
+Then we use grade down to get the reordering indices:

+ +

{width=ā€5.333333333333333inā€ +height=ā€2.3733333333333335inā€}{width=ā€4.978472222222222inā€ +height=ā€2.2333333333333334inā€}At this point we could use the index +vector to sort the salaries:

+ +

{width=ā€5.593333333333334inā€ +height=ā€2.3inā€}But what we actually want is a list of names, sorted by +salary:

+ +

{width=ā€2.308333333333333inā€ +height=ā€0.275inā€}{width=ā€2.9166666666666665inā€ +height=ā€0.325inā€}By taking the index vector from grade down of column 3 +and telling item to apply it to column 1, we get what we set out to +find. As usual the code is more elegant in APL: +database[ā’database[;3];1].

+ +

{width=ā€2.9472222222222224inā€ +height=ā€0.22569444444444445inā€}In case youā€™ve forgotten, or would select +the third row of the database; we need the list 3 in the second input +slot of the outer list to select by columns rather than by rows.

+ +

Select (if take) or select all but (if drop) the first (if n>0) or +last (if n<0) |n| items from a vector, or rows from a matrix. +Alternatively, if the left input is a two-item vector, select rows with +the first item and columns with the second.

+ +

The compress block selects a subset of its right input based on the +Boolean values in its left input, which must be a vector of Booleans +whose length equals the length of the array (the number of rows, for a +matrix) in the right input. The block reports an array of the same rank +as the right input, but containing only those rows whose corresponding +Boolean value is true. The columns version āŒæ is the same but +selecting columns rather than selecting rows.

+ +

{width=ā€6.452083333333333inā€ +height=ā€0.25inā€}A word about the possibly confusing names of these +blocks: There are two ways to think about what they do. Take the +standard / version, to avoid talking about both at once. One way to +think about it is that it selects some of the rows. The other way is +that it shortens the columns. For Lispians, which includes you since +youā€™ve learned about keep, the natural way to think about / is that it +keeps some of the rows. Since we represent a matrix as a list of rows, +that also fits with how this function is implemented. (Read the code; +youā€™ll find a keep inside.) But APL people think about it the other way, +so when you read APL documentation, / is described as operating on the +last dimension (the columns), while āŒæ is described as operating on +rows. We were more than a month into this project before I understood +all this. You get long block names so it wonā€™t take you a month!

+ +

{width=ā€3.175inā€ +height=ā€0.18333333333333332inā€}{width=ā€2.9944444444444445inā€ +height=ā€0.23333333333333334inā€}{width=ā€1.1118055555555555inā€ +height=ā€0.23333333333333334inā€}Donā€™t confuse this block with the reduce +block, whose APL symbol is also a slash. In that block, what comes to +the left of the slash is a dyadic combining function; itā€™s the APL +equivalent of combine. This block is more nearly equivalent to keep. But +keep takes a predicate function as input, and calls the function for +each item of the second input. With compress, the predicate function, if +any, has already been called on all the items of the right input in +parallel, resulting in a vector of Boolean values. This is a typical APL +move; since hyperblocks are equivalent to an implicit map, itā€™s easy to +make the vector of Booleans, because any scalar function, including +predicates, can be applied to a list instead of to a scalar. The reason +both blocks use the / character is that both of them reduce the size of +the input array, although in different ways.

+ +

{width=ā€5.875inā€ +height=ā€2.9944444444444445inā€}The reverse row order, reverse column +order, and transpose blocks form a group: the group of reflections of a +matrix. The APL symbols are all a circle with a line through it; the +lines are the different axes of reflection. So the reverse row order +block reverses which row is where; the reverse column order block +reverses which column is where; and the transpose block turns rows into +columns and vice versa:

+ +

Except for reverse row order, these work only on full arrays, not +ragged-right lists of lists, because the result of the other two would +be an array in which some rows had ā€œholesā€: items 1 and 3 exist, but not +item 2. We donā€™t have a representation for that. (In APL, all arrays are +full, so itā€™s even more restrictive.)

+ +

Higher order functions

+ +

The final category of function is operatorsā€”APL higher order +functions. APL has no explicit map function, because the hyperblock +capability serves much the same need. But APL2 did add an explicit map, +which we might get around to adding to the library next time around. Its +symbol is ĀØ (diaeresis or umlaut).

+ +

The APL equivalent of keep is compress, but itā€™s not a higher order +function. You create a vector of Booleans (0s and 1s, in APL) before +applying the function to the array you want to compress.

+ +

{width=ā€4.258333333333334inā€ +height=ā€0.6131944444444445inā€}But APL does have a higher order version +of combine:

+ +

{width=ā€6.683333333333334inā€ +height=ā€1.0416666666666667inā€}The reduce block works just like combine, +taking a dyadic function and a list. The / version translates each row +to a single value; the āŒæ version translates each column to a single +value. Thatā€™s the only way to think about it from the perspective of +combining individual elements: you are adding up, or whatever the +function is, the numbers in a single row (/) or in a single column +(āŒæ). But APLers think of a matrix as made up of vectors, either row +vectors or column vectors. And if you think of what these blocks do as +adding vectors, rather than adding individual numbers, itā€™s clear that +in

+ +

{width=ā€5.833333333333333inā€ +height=ā€1.1inā€}

+ +

{width=ā€4.808333333333334inā€ +height=ā€1.1inā€}the vector (10, 26, 42) is the sum of column vectors +(1, 5, 9)+(2, 6, 10)+(3, 7, 11)+(4, 8, 12). In pre-6.0 Snap!, weā€™d get +the same result this way:

+ +

mapping over the rows of the matrix, applying combine to each row. +Combining rows, reducing column vectors.
+The outer product block takes two arrays (vectors, typically) and a +dyadic scalar function as inputs. It reports an array whose rank is the +sum of the ranks of the inputs (so, typically a matrix), in which each +item is the result of applying the function to an atomic element of each +array. The third element of the second row of the result is the value +reported by the function with the second element of the left input and +the third element of the right input. (The APL symbol ā—¦. is pronounced +ā€œjot dot.ā€) The way to think about this block is ā€œmultiplication tableā€ +from elementary school:

+ +

{width=ā€7.24inā€ height=ā€1.52inā€}

+ +

{width=ā€2.1666666666666665inā€ +height=ā€0.24166666666666667inā€}

+ +

{width=ā€2.6166666666666667inā€ +height=ā€0.24166666666666667inā€}

+ +

{width=ā€7.338611111111111inā€ +height=ā€1.0069444444444444inā€}The inner product block takes two matrices +and two operations as input. The number of columns in the left matrix +must equal the number of rows in the right matrix. When the two +operations are + and Ɨ, this is the matrix multiplication familiar to +mathematicians:

+ +

But other operations can be used. One common inner product is āˆØ.āˆ§ (ā€œor +dot andā€) applied to Boolean matrices, to find rows and columns that +have corresponding items in common.

+ +

{width=ā€0.9583333333333334inā€ +height=ā€0.18333333333333332inā€}The printable block isnā€™t an APL +function; itā€™s an aid to exploring APL-in-Snap!. It transforms arrays +to a compact representation that still makes the structure clear:

+ +

{width=ā€5.997916666666667inā€ +height=ā€0.3333333333333333inā€}Experts will recognize this as the Lisp +representation of list structure,

+ +

Index

+ +

! block Ā· 32.csv file Ā· 134.json file Ā· 134.txt file Ā· 134# variable Ā· +25#1 Ā· 69+ block Ā· 22Ɨ block Ā· 22ā‰  block Ā· 20ā‰¤ block Ā· 20ā‰„ block Ā· 20āš” +(lightning bolt) Ā· 123Aa new clone of block Ā· 77A Programming Language +Ā· 148Abelson, Hal Ā· 4About option Ā· 107add comment option Ā· 124, 125Add +sceneā€¦ option Ā· 111additive mixing Ā· 144Advanced Placement Computer +Science Principles Ā· 110AGPL Ā· 107all but first blocks Ā· 27all but first +of block Ā· 49all but first of stream block Ā· 26all but last blocks Ā· +27all of block Ā· 28Alonzo Ā· 9, 55anchor Ā· 10anchor (in my block) Ā· +78animate block Ā· 33animation Ā· 12animation library Ā· 33anonymous list Ā· +46Any (unevaluated) type Ā· 72any of block Ā· 28Any type Ā· 60APL Ā· 4, 58, +148APL character set Ā· 149APL library Ā· 35, 148APL2 Ā· 149APL\360 Ā· +148Arduino Ā· 92arithmetic Ā· 11array, dynamic Ā· 49arrow, upward-pointing +Ā· 63arrowheads Ā· 46, 63, 69ask and wait block Ā· 24ask block Ā· 86assoc +block Ā· 25association list Ā· 88associative function Ā· 51at block Ā· +19atan2 block Ā· 20atomic data Ā· 57attribute Ā· 76attributes, list of Ā· +78audio comp library Ā· 34Bbackground blocks Ā· 19Backgroundsā€¦ option Ā· +112backspace key (keyboard editor) Ā· 131Ball, Michael Ā· 4bar chart block +Ā· 28bar charts library Ā· 28base case Ā· 44BIGNUMS block Ā· 32binary tree Ā· +47bitmap Ā· 79, 112bitwise library Ā· 36bjc.edc.org Ā· 137Black Hole +problem Ā· 139block Ā· 6; command Ā· 6; C-shaped Ā· 7; hat Ā· 6; predicate Ā· +12; reporter Ā· 10; sprite-local Ā· 75Block Editor Ā· 41, 42, 59block label +Ā· 102block library Ā· 45, 110block picture option Ā· 124block shapes Ā· 40, +60block variable Ā· 43block with no name Ā· 32blockify option Ā· 134blocks, +color of Ā· 40Boole, George Ā· 12Boolean Ā· 12Boolean (unevaluated) type Ā· +72Boolean constant Ā· 12box of ten crayons Ā· 139box of twenty crayons Ā· +139break command Ā· 99breakpoint Ā· 17, 118Briggs, David Ā· 145broadcast +and wait block Ā· 125broadcast and wait block Ā· 9broadcast block Ā· 21, +23, 73, 125brown dot Ā· 9Build Your Own Blocks Ā· 40Burns, Scott Ā· +145button: pause Ā· 17; recover Ā· 39; visible stepping Ā· 18CC programming +language Ā· 68call block Ā· 65, 68call w/continuation block Ā· 97camera +icon Ā· 126Cancel button Ā· 129carriage return character Ā· 20cascade +blocks Ā· 26case-independent comparisons block Ā· 33cases block Ā· 28catch +block Ā· 26, 99catch errors library Ā· 31catenate block Ā· 152catenate +vertically block Ā· 152center of the stage Ā· 22center x (in my block) Ā· +78center y (in my block) Ā· 78Chandra, Kartik Ā· 4change background block +Ā· 22Change passwordā€¦ option Ā· 113change pen block Ā· 24, 29, 117, +140child class Ā· 87children (in my block) Ā· 78Church, Alonzo Ā· 9class Ā· +85class/instance Ā· 76clean up option Ā· 125clear button Ā· 129clicking on +a script Ā· 122Clicking sound option Ā· 116clone: permanent Ā· 74; +temporary Ā· 74clone of block Ā· 89clones (in my block) Ā· 78cloud (startup +option) Ā· 136Cloud button Ā· 37, 108cloud icon Ā· 113cloud storage Ā· 37CMY +Ā· 138CMYK Ā· 138codification support option Ā· 117color at weight block Ā· +145color block Ā· 140color chart Ā· 147color from block Ā· 29, 140color +nerds Ā· 145color numbers Ā· 29, 138, 139color of blocks Ā· 40color palette +Ā· 128color picker Ā· 143color scales Ā· 141color space Ā· 138color theory Ā· +138Colors and Crayons library Ā· 138colors library Ā· 29columns of block Ā· +57combine block Ā· 50combine block (APL) Ā· 157command block Ā· 6comment +box Ā· 125compile menu option Ā· 123compose block Ā· 26compress block Ā· +156Computer Science Principles Ā· 110cond in Lisp Ā· 28conditional +library: multiple-branch Ā· 28constant functions Ā· 71constructors Ā· +47contained in block Ā· 153context menu Ā· 119context menu for the palette +background Ā· 120context menus for palette blocks Ā· 119continuation Ā· +93continuation passing style Ā· 94Control palette Ā· 7controls in the +Costumes tab Ā· 126controls in the Sounds tab Ā· 130controls on the stage +Ā· 132control-shift-enter (keyboard editor) Ā· 132copy of a list Ā· 50CORS +Ā· 92cors proxies Ā· 92costume Ā· 6, 8costume from text block Ā· 31costume +with background block Ā· 31costumes (in my block) Ā· 78Costumes tab Ā· 9, +126costumes, first class Ā· 79Costumesā€¦ option Ā· 112counter class Ā· +85CPS Ā· 96crayon library Ā· 31crayons Ā· 29, 138, 139create var block Ā· +32create variables library Ā· 32Cross-Origin Resource Sharing Ā· +92crossproduct Ā· 70cs10.org Ā· 137C-shaped block Ā· 7, 67C-shaped slot Ā· +72CSV (comma-separated values) Ā· 54CSV format Ā· 20csv of block Ā· +57current block Ā· 92current date or time Ā· 92current location block Ā· +34current sprite Ā· 122custom block in a script Ā· 124custom? of block +block Ā· 102cyan Ā· 142Ddangling rotation Ā· 10dangling? (in my block) Ā· +78dark candy apple red Ā· 141data hiding Ā· 73data structure Ā· 47data +table Ā· 88data type Ā· 19, 59database library Ā· 34date Ā· 92Dave, Achal Ā· +4deal block Ā· 150debugging Ā· 118Debugging Ā· 17deep copy of a list Ā· +50default value Ā· 63define block Ā· 102define of recursive procedure Ā· +104definition (of block) Ā· 102definition of block Ā· 101delegation Ā· +87Delete a variable Ā· 14delete block definitionā€¦ option Ā· 120delete +option Ā· 124, 128, 133delete var block Ā· 32denim Ā· 139design principle Ā· +46, 77devices Ā· 91, 92dialog, input name Ā· 42dimensions of block Ā· +57Dinsmore, Nathan Ā· 4direction to block Ā· 22Disable click-to-run option +Ā· 117dispatch procedure Ā· 85, 86, 88distance to block Ā· 22dl (startup +option) Ā· 136do in parallel block Ā· 31does var exist block Ā· 32down +arrow (keyboard editor) Ā· 131Download source option Ā· 108drag from +prototype Ā· 43draggable checkbox Ā· 122, 132dragging onto the arrowheads +Ā· 69drop block Ā· 155duplicate block definitionā€¦ option Ā· 120duplicate +option Ā· 124, 128, 132dynamic array Ā· 49Eeasing block Ā· 33easing +function Ā· 33edge color Ā· 129edit option Ā· 128, 133, 135editā€¦ option Ā· +120editMode (startup option) Ā· 137effect block Ā· 19ellipse tool Ā· 128, +129ellipsis Ā· 63else block Ā· 28else if block Ā· 28empty input slots, +filling Ā· 66, 68, 70enter key (keyboard editor) Ā· 131equality of +complete structures Ā· 149eraser tool Ā· 128error block Ā· 31error catching +library Ā· 31escape key (keyboard editor) Ā· 130Examples button Ā· +108Execute on slider change option Ā· 115export block definitionā€¦ +option Ā· 120Export blocksā€¦ option Ā· 110export option Ā· 128, 133Export +projectā€¦ option Ā· 110exportā€¦ option Ā· 134, 136expression Ā· +11Extension blocks option Ā· 115extract option Ā· 124eyedropper tool Ā· +128, 129Ffactorial Ā· 44, 71factorial Ā· 32Fade blocksā€¦ option Ā· 114fair +HSL Ā· 145fair hue Ā· 29, 141, 143, 146fair hue table Ā· 146fair saturation +Ā· 146fair value Ā· 146Falkoff, Adin Ā· 148false block Ā· 19file icon menu Ā· +108fill color Ā· 129Finch Ā· 92find blocksā€¦ option Ā· 120find first Ā· +50first class data Ā· 148first class data type Ā· 46ļ¬rst class procedures +Ā· 65ļ¬rst class sprites Ā· 73first word block Ā· 27flag, green Ā· 6Flat +design option Ā· 116flat line ends option Ā· 117flatten block Ā· 152flatten +of block Ā· 57floodfill tool, Ā· 128focus (keyboard editor) Ā· 131footprint +button Ā· 117for block Ā· 13, 19, 26, 64, 65for each block Ā· 20for each +item block Ā· 25For this sprite only Ā· 15formal parameters Ā· 69frequency +distribution analysis library Ā· 34from color block Ā· 29, 140, +142function, associative Ā· 51function, higher order Ā· 49, 148function, +mixed Ā· 148, 151function, scalar Ā· 55, 148functional programming style Ā· +48
+Ggeneric hat block Ā· 6generic when Ā· 6get blocks option Ā· 128getter Ā· +76getter/setter library Ā· 32glide block Ā· 115global variable Ā· 14, 15go +to block Ā· 22grade down block Ā· 154grade up block Ā· 154graphics effect Ā· +19gray Ā· 139, 141green flag Ā· 6green flag button Ā· 118green halo Ā· +123GuillĆ©n i Pelegay, Joan Ā· 4Hhalo Ā· 11, 123; red Ā· 69hat block Ā· 6, +41; generic Ā· 6helpā€¦ option Ā· 119, 123helpā€¦ option for custom block +Ā· 119hexagonal blocks Ā· 41, 60hexagonal shape Ā· 12hide and show +primitives Ā· 17hide blocks option Ā· 120Hide blocksā€¦ option Ā· 111hide +var block Ā· 32hide variable block Ā· 17hideControls (startup option) Ā· +137higher order function Ā· 49, 70, 148, 157higher order procedure Ā· +66histogram Ā· 34Hotchkiss. Kyle Ā· 4HSL Ā· 138, 143HSL color Ā· 29HSL pen +color model option Ā· 117HSV Ā· 138, 142HTML (HyperText Markup Language) Ā· +91HTTP Ā· 92HTTPS Ā· 92, 126Hudson, Connor Ā· 4hue Ā· 141Huegle, Jadga Ā· +4Hummingbird Ā· 92hyperblocks Ā· 148Hyperblocks Ā· 55Hz for block Ā· 34IIBM +System/360 Ā· 148ice cream Ā· 109icons in title text Ā· 64id block Ā· 71id +option Ā· 22identical to Ā· 20identity function Ā· 71if block Ā· 12if do and +pause all block Ā· 26if else block Ā· 71if else reporter block Ā· 19ignore +block Ā· 26imperative programming style Ā· 48importā€¦ option Ā· +134Importā€¦ option Ā· 110in front of block Ā· 49in front of stream block +Ā· 26index of block (APL) Ā· 152index variable Ā· 19indigo Ā· 141infinite +precision integer library Ā· 32Ingalls, Dan Ā· 4inherit block Ā· +77inheritance Ā· 73, 87inner product block Ā· 158input Ā· 6input list Ā· 68, +69input name Ā· 69input name dialog Ā· 42, 59Input sliders option Ā· +115input-type shapes Ā· 59instance Ā· 85integers block Ā· 152interaction Ā· +15internal variable Ā· 63iota block Ā· 152is _ a _ ? block Ā· 19is flag +block Ā· 20is identical to Ā· 20item 1 of block Ā· 49item 1 of stream block +Ā· 26item block Ā· 148item of block Ā· 56iteration library Ā· 26Iverson, +Kenneth E. Ā· 4, 148Jjaggies Ā· 79Java programming language Ā· 68JavaScript +Ā· 19, 143JavaScript extensions option Ā· 115JavaScript function block Ā· +115jigsaw-piece blocks Ā· 40, 60join block Ā· 102JSON (JavaScript Object +Notation) file Ā· 54JSON format Ā· 20json of block Ā· 57jukebox Ā· 9KKay, +Alan Ā· 4key:value: block Ā· 34keyboard editing button Ā· 123keyboard +editor Ā· 130keyboard shortcuts Ā· 108key-value pair Ā· 88LL*a*b* Ā· +143L*u*v* Ā· 143label, block Ā· 102lambda Ā· 67lang= (startup option) Ā· +137Languageā€¦ option Ā· 114large option Ā· 134last blocks Ā· 27layout, +window Ā· 5Leap Motion Ā· 92left arrow (keyboard editor) Ā· 131Lego NXT Ā· +92length block Ā· 148length of block Ā· 57length of text block Ā· 22letter +(1) of (world) block Ā· 27lexical scope Ā· 85lg option Ā· 22Librariesā€¦ +option Ā· 25, 111library: block Ā· 45license Ā· 107Lieberman, Henry Ā· +77Lifelong Kindergarten Group Ā· 4lightness Ā· 143lightness option Ā· +117lightning bolt symbol Ā· 25, 123line break in block Ā· 64line drawing +tool Ā· 128lines of block Ā· 57linked list Ā· 49Lisp Ā· 58list āž” sentence +block Ā· 27list āž” word block Ā· 27list block Ā· 46list comprehension +library Ā· 35list copy Ā· 50list library Ā· 25list of procedures Ā· 70List +type Ā· 60list view Ā· 51list, linked Ā· 49list, multi-dimensional Ā· +55listify block Ā· 34lists of lists Ā· 47little people Ā· 44, 96loading +saved projects Ā· 38local state Ā· 73local variables Ā· 19location-pin Ā· +15Loginā€¦ option Ā· 113Logo tradition Ā· 27Logout option Ā· 113Long form +input dialog option Ā· 116long input name dialog Ā· 59Mmacros Ā· 105magenta +Ā· 141, 142Make a block Ā· 40Make a block button Ā· 119make a blockā€¦ +option Ā· 126Make a list Ā· 46Make a variable Ā· 14make internal variable +visible Ā· 63Maloney, John Ā· 4map block Ā· 50, 65map library Ā· 35map over +stream block Ā· 26map to code block Ā· 117map-pin symbol Ā· 75maroon Ā· +141Massachusetts Institute of Technology Ā· 4mathematicians Ā· 148matrices +Ā· 148matrix multiplication Ā· 158max block Ā· 20McCarthy, John Ā· 4media +computation Ā· 55, 149Media Lab Ā· 4memory Ā· 16menus library Ā· 36message Ā· +73message passing Ā· 73, 86method Ā· 73, 75, 86methods table Ā· +88microphone Ā· 82microphone block Ā· 82middle option Ā· 127min block Ā· +20mirror sites Ā· 137MIT Artificial Intelligence Lab Ā· 4MIT Media Lab Ā· +4mix block Ā· 140mix colors block Ā· 29mixed function Ā· 148, 151mixing +paints Ā· 144Modrow, Eckart Ā· 121monadic negation operator Ā· 22Morphic Ā· +4Motyashov, Ivan Ā· 4mouse position block Ā· 21move option Ā· 133MQTT +library Ā· 36multiline block Ā· 33multimap block Ā· 25multiple input Ā· +63multiple-branch conditional library Ā· 28multiplication table Ā· +158multiplication, matrix Ā· 158mutation Ā· 48mutators Ā· 47my block Ā· 73, +76my blocks block Ā· 102my categories block Ā· 102Nname (in my block) Ā· +78name box Ā· 122name, input Ā· 69nearest color number Ā· 142neg option Ā· +22negation operator Ā· 22neighbors (in my block) Ā· 78nested calls Ā· +70Nesting Sprites Ā· 10New categoryā€¦ option Ā· 111new costume block Ā· +80new line character Ā· 64New option Ā· 108New scene option Ā· 111new sound +block Ā· 84new sprite button Ā· 8newline character Ā· 20Nintendo Ā· +92noExitWarning (startup option) Ā· 137nonlocal exit Ā· 99normal option Ā· +134normal people Ā· 145noRun (startup option) Ā· 137Number type Ā· +60numbers from block Ā· 20Oobject block Ā· 73Object Logo Ā· 77object +oriented programming Ā· 73, 85Object type Ā· 60objects, building +explicitly Ā· 85of block (operators) Ā· 22of block (sensing) Ā· 24, 106of +costume block Ā· 79open (startup option) Ā· 136Open in Community Site +option Ā· 113Openā€¦ option Ā· 108operator (APL) Ā· 148, 157orange oval Ā· +13other clones (in my block) Ā· 78other sprites (in my block) Ā· 78outer +product block Ā· 158outlined ellipse tool Ā· 128outlined rectangle tool Ā· +128oval blocks Ā· 40, 60Ppaint brush icon Ā· 126Paint Editor Ā· 126Paint +Editor window Ā· 128paintbrush tool Ā· 128paints Ā· 144Paleolithic Ā· +150palette Ā· 6palette area Ā· 119palette background Ā· 120Parallax S2 Ā· +92parallelism Ā· 8, 48parallelization library Ā· 31parent (in my block) Ā· +78parent attribute Ā· 77parent class Ā· 87parentā€¦ option Ā· 136Parsons +problems Ā· 117parts (in my block) Ā· 78parts (of nested sprite) Ā· +10pause all block Ā· 17, 118pause button Ā· 17, 118pen block Ā· 24, 29, +117, 140pen down? block Ā· 19pen trails block Ā· 18pen trails option Ā· +135pen vectors block Ā· 18permanent clone Ā· 74, 136physical devices Ā· +91picā€¦ option Ā· 135, 136picture of script Ā· 124picture with speech +balloon Ā· 124picture, smart Ā· 124pink Ā· 141pivot option Ā· 133pixel Ā· +79pixel, screen Ā· 19pixels library Ā· 27Plain prototype labels option Ā· +116play block Ā· 34play sound block Ā· 9playing sounds Ā· 9plot bar chart +block Ā· 28plot sound block Ā· 34point towards block Ā· 22points as inputs +Ā· 22polymorphism Ā· 75position block Ā· 21, 33Predicate block Ā· +12preloading a project Ā· 136present (startup option) Ā· 136presentation +mode button Ā· 118primitive block within a script Ā· 123printable block Ā· +27, 158procedure Ā· 12, 66Procedure type Ā· 72procedures as data Ā· +9product block Ā· 22, 28project control buttons Ā· 118Project notes option +Ā· 108Prolog Ā· 58prototype Ā· 41prototyping Ā· 76, 88pulldown input Ā· +61pumpkin Ā· 139purple Ā· 142Rrainbow Ā· 141rank Ā· 148rank of block Ā· 57, +151ravel block Ā· 149raw dataā€¦ option Ā· 134ray length block Ā· +22read-only pulldown input Ā· 61receiversā€¦ option Ā· 125recover button Ā· +39rectangle tool Ā· 128recursion Ā· 43recursive call Ā· 68recursive +operator Ā· 71recursive procedure using define Ā· 104red halo Ā· 68, 69, +123redo button Ā· 123redrop option Ā· 125reduce block Ā· 156, 157Reference +manual option Ā· 108reflectance graph Ā· 144relabel option Ā· 20relabelā€¦ +option Ā· 123, 124release option Ā· 136Remove a categoryā€¦ option Ā· +111remove duplicates from block Ā· 25rename option Ā· 128renaming +variables Ā· 15repeat block Ā· 7, 67repeat blocks Ā· 26repeat until +block Ā· 12report block Ā· 44Reporter block Ā· 10reporter if block Ā· +12reporter if else block Ā· 19reporters, recursive Ā· 44Reset Passwordā€¦ +option Ā· 113reshape block Ā· 56, 148, 151Restore unsaved project option Ā· +39result picā€¦ option Ā· 124, 125reverse block Ā· 156reverse columns +block Ā· 156Reynolds, Ian Ā· 4RGB Ā· 138RGBA option Ā· 19right arrow +(keyboard editor) Ā· 131ring, gray Ā· 49, 66, 68ringify Ā· 66ringify option +Ā· 124Roberts, Eric Ā· 44robots Ā· 91, 92rods and cones Ā· 141roll block Ā· +150Romagosa, Bernat Ā· 4rotation buttons Ā· 122rotation point tool Ā· 128, +129rotation x (in my block) Ā· 78rotation y (in my block) Ā· 78run +(startup option) Ā· 136run block Ā· 65, 68run w/continuation Ā· 99Ssafely +try block Ā· 31sample Ā· 82saturation Ā· 143Save asā€¦ option Ā· 110Save +option Ā· 110save your project in the cloud Ā· 37scalar = block Ā· +150scalar function Ā· 55, 148, 150scalar join block Ā· 150scenes Ā· 111, +136Scenesā€¦ option Ā· 111Scheme Ā· 4Scheme number block Ā· 32SciSnap! Ā· +121SciSnap! library Ā· 36scope: lexical Ā· 85Scratch Ā· 5, 9, 40, 46, 47, +48, 59Scratch Team Ā· 4screen pixel Ā· 19script Ā· 5script pic Ā· 43script +picā€¦ option Ā· 124script variables block Ā· 15, 19, 86scripting area +Ā· 6, 122scripting area background context menu Ā· 125scripts picā€¦ +option Ā· 126search bar Ā· 109search button Ā· 119secrets Ā· 107select block +Ā· 156selectors Ā· 47self (in my block) Ā· 78sendersā€¦ option Ā· 125sensors +Ā· 91sentence āž” list block Ā· 27sentence block Ā· 25sentence library Ā· +27sentenceāž”list block Ā· 25separator: menu Ā· 62sepia Ā· 139serial-ports +library Ā· 33Servilla, Deborah Ā· 4set _ of block _ to _ block Ā· 102set +background block Ā· 22set block Ā· 15set flag block Ā· 20, 32set pen +block Ā· 24, 29, 117, 139, 140set pen to crayon block Ā· 30, 139set value +block Ā· 32set var block Ā· 32setter Ā· 76setting block Ā· 32settings icon Ā· +114shade Ā· 141shallow copy of a list Ā· 50shape of block Ā· 151shapes of +blocks Ā· 40shift-arrow keys (keyboard editor) Ā· 131Shift-click (keyboard +editor) Ā· 130shift-click on block Ā· 124shift-clicking Ā· 107shift-enter +(keyboard editor) Ā· 130Shift-tab (keyboard editor) Ā· 130shortcut Ā· 126, +135shortcuts: keyboard Ā· 108show all option Ā· 135Show buttons option Ā· +117Show categories option Ā· 117show option Ā· 136show primitives option Ā· +121show stream block Ā· 26show var block Ā· 32show variable block Ā· +17shown? block Ā· 19shrink/grow button Ā· 118sieve block Ā· 26sign option Ā· +22Signada library Ā· 36signum block Ā· 150Signupā€¦ option Ā· 113simulation +Ā· 73sine wave Ā· 83Single palette option Ā· 117single stepping Ā· 18slider: +stepping speed Ā· 18slider maxā€¦ option Ā· 134slider minā€¦ option Ā· +134slider option Ā· 134Smalltalk Ā· 58smart picture Ā· 124snap block Ā· +27snap option Ā· 22Snap! logo menu Ā· 107Snap! manual Ā· 124Snap! +program Ā· 5Snap! website option Ā· 108snap.berkeley.edu Ā· 108solid +ellipse tool Ā· 128solid rectangle tool Ā· 128sophistication Ā· 72sort +block Ā· 25sound Ā· 82sound manipulation library Ā· 34sounds (in my block) +Ā· 78sounds, first class Ā· 79Soundsā€¦ option Ā· 113source files for +Snap! Ā· 108space key (keyboard editor) Ā· 131speak block Ā· 31special +form Ā· 72spectral colors Ā· 141speech balloon Ā· 124speech synthesis +library Ā· 31split block Ā· 20, 91split by blocks block Ā· 101split by line +block Ā· 57spreadsheet Ā· 149sprite Ā· 6, 73sprite appearance and behavior +controls Ā· 122sprite corral Ā· 8, 135sprite creation buttons Ā· 135sprite +nesting Ā· 10sprite-local block Ā· 75sprite-local variable Ā· 14, 15square +stop sign Ā· 6squiral Ā· 13stack of blocks Ā· 6stage Ā· 6, 73stage (in my +block) Ā· 78stage blocks Ā· 19Stage resizing buttons Ā· 118Stage sizeā€¦ +option Ā· 114Stanford Artificial Intelligence Lab Ā· 4starting Snap! Ā· +136Steele, Guy Ā· 4stop all block Ā· 118stop block Ā· 22stop block block Ā· +44stop button Ā· 118stop script block Ā· 44stop sign Ā· 8stop sign, square +Ā· 6Stream block Ā· 26stream library Ā· 26Stream with numbers from block Ā· +26stretch block Ā· 80string processing library Ā· 33Structure and +Interpretation of Computer Programs Ā· 4submenu Ā· 62substring block Ā· +33subtractive mixing Ā· 144sum block Ā· 22, 28Super-Awesome Sylvia Ā· +92Sussman, Gerald J. Ā· 4Sussman, Julie Ā· 4svgā€¦ option Ā· 135switch in C +Ā· 28symbols in title text Ā· 64synchronous rotation Ā· 10system +getter/setter library Ā· 32Ttab character Ā· 20tab key (keyboard editor) Ā· +130table Ā· 158table view Ā· 51take block Ā· 155teal Ā· 142temporary clone Ā· +74, 133Terms of Service Ā· 38termwise extension Ā· 148text costume library +Ā· 31text input Ā· 9Text type Ā· 60text-based language Ā· 117text-to-speech +library Ā· 31Thinking Recursively Ā· 44thread Ā· 100thread block Ā· +100Thread safe scripts option Ā· 116throw block Ā· 26thumbnail Ā· 122time Ā· +92tint Ā· 141tip option Ā· 127title text Ā· 42to block Ā· 22tool bar Ā· 6tool +bar features Ā· 107touching block Ā· 22transient variable Ā· 16translation +Ā· 114translations option Ā· 43transparency Ā· 30, 79, 140transparent paint +Ā· 129transpose block Ā· 156true block Ā· 19TuneScope library Ā· 36Turbo +mode option Ā· 115turtle costume Ā· 126Turtle costume Ā· 9turtleā€™s rotation +point Ā· 127two-item (x,y) lists Ā· 22type Ā· 19UUndefined! blocks Ā· +120Undelete spritesā€¦ option Ā· 113undo button Ā· 123, 129undrop option Ā· +125unevaluated procedure types Ā· 61unevaluated type Ā· 72Unicode Ā· +149Uniform Resource Locator Ā· 91unringify Ā· 66, 86unringify option Ā· +124Unused blocksā€¦ option Ā· 111up arrow (keyboard editor) Ā· 131upvar Ā· +64upward-pointing arrow Ā· 63url block Ā· 34, 91USE BIGNUMS block Ā· 32use +case-independent comparisons block Ā· 33user interface elements Ā· 107user +name Ā· 37Vvalue Ā· 143value at key block Ā· 34var block Ā· 32variable Ā· 13, +76; block Ā· 43; global Ā· 14; renaming Ā· 15; script-local Ā· 15; +sprite-local Ā· 14, 15; transient Ā· 16variable watcher Ā· 14variable-input +slot Ā· 68variables in ring slots Ā· 66variables library Ā· 32variables, +local Ā· 19variadic Ā· 22variadic input Ā· 46, 63variadic library Ā· +28vector Ā· 112vector editor Ā· 129vectors Ā· 148video block Ā· 22video on +block Ā· 80violet Ā· 142visible stepping Ā· 45, 117visible stepping button +Ā· 18visible stepping option Ā· 115visual representation of a sentence Ā· +27Wwardrobe Ā· 9warp block Ā· 19, 123watcher Ā· 15Water Color Bot Ā· 92web +services library Ā· 34when I am block Ā· 23when I am stopped script Ā· +23when I receive block Ā· 23when, generic Ā· 6white Ā· 142white background +Ā· 141whitespace Ā· 20Wiimote Ā· 92window layout Ā· 5with inputs Ā· 66word āž” +list block Ā· 27word and sentence library Ā· 27world map library Ā· 35World +Wide Web Ā· 91write block Ā· 18writeable pulldown inputs Ā· 61XX position Ā· +11X11/W3C color names Ā· 29Xerox PARC Ā· 4YY position Ā· 11yield block Ā· +100Yuan, Yuan Ā· 4Zzebra coloring Ā· 11Zoom blocks... option Ā· 114

+ +
+
    +
  1. +

    One of the hat blocks, the generic ā€œwhen anythingā€ block , is +subtly different from the others. When the stop sign is clicked, or +when a project or sprite is loaded, this block doesnā€™t test whether +the condition in its hexagonal input slot is true, so the script +beneath it will not run, until some other script in the project +runs (because, for example, you click the green flag). When generic +when blocks are disabled, the stop sign will be square instead of +octagonal.Ā 

    +
  2. +
  3. +

    The hide variable and show variable blocks can also be used to +hide and show primitives in the palette. The pulldown menu doesnā€™t +include primitive blocks, but thereā€™s a generally useful technique +to give a block input values it wasnā€™t expecting using run or +call:{width=ā€3.9375inā€ +height=ā€0.3888888888888889inā€}

    + +

    In order to use a block as an input this way, you must explicitly +put a ring around it, by right-clicking on it and choosing ringify. +More about rings in Chapter VI.Ā 

    +
  4. +
  5. +

    This use of the word ā€œprototypeā€ is unrelated to the prototyping +object oriented programming discussed later.Ā 

    +
  6. +
  7. +

    Note to users of earlier versions: From the beginning, there has +been a tension in our work between the desire to provide tools such +as for (used in this example) and the higher order functions +introduced on the next page as primitives, to be used as easily as +other primitives, and the desire to show how readily such tools can +be implemented in Snap! itself. This is one instance of our +general pedagogic understanding that learners should both use +abstractions and be permitted to see beneath the abstraction +barrier. Until version 5.0, we used the uneasy compromise of a +library of tools written in Snap! and easily, but not easily +enough, loaded into a project. By not loading the tools, users or +teachers could explore how to program them. In 5.0 we made them true +primitives, partly because thatā€™s what some of us wanted all along +and partly because of the increasing importance of fast performance +as we explore ā€œbig dataā€ and media computation. But this is not the +end of the story for us. In a later version, after we get the design +firmed up, we intend to introduce ā€œhybridā€ primitives, implemented +in high speed Javascript but with an ā€œEditā€ option that will open, +not the primitive implementation, but the version written in +Snap!. The trick is to ensure that this can be done without +dramatically slowing usersā€™ projects.Ā 

    +
  8. +
  9. +

    In Scratch, every block that takes a Text-type input has a default +value that makes the rectangles for text wider than tall. The blocks +that arenā€™t specifically about text either are of Number type or +have no default value, so those rectangles are taller than wide. At +ļ¬rst some of us (bh) thought that Text was a separate type that +always had a wide input slot; it turns out that this isnā€™t true in +Scratch (delete the default text and the rectangle narrows), but we +thought it a good idea anyway, so we allow Text-shaped boxes even +for empty input slots. (This is why Text comes just above Any in the +input type selection box.)Ā 

    +
  10. +
  11. +

    There is a primitive id function in the menu of the sqrt of block, +but we think seeing its (very simple) implementation will make this +example easier to understand.Ā 

    +
  12. +
  13. +

    Some languages popular in the ā€œreal worldā€ today, such as +JavaScript, claim to use prototyping, but their object system is +much more complicated than what we are describing (weā€™re guessing +itā€™s because they were designed by people too familiar with +class/instance programming); that has, in some circles, given +prototyping a bad name. Our prototyping design comes from Object +Logo, and before that, from Henry Lieberman. [Lieberman, H., Using +Prototypical Objects to Implement Shared Behavior in Object-Oriented +Systems, First Conference on Object-Oriented Programming Languages, +Systems, and Applications [OOPSLA-86], ACM SigCHI, Portland, OR, +September, 1986. Also in Object-Oriented Computing, Gerald +Peterson, Ed., IEEE Computer Society Press, 1987.]Ā 

    +
  14. +
  15. +

    Neighbors are all other sprites whose bounding boxes intersect +the doubled dimensions of the requesting sprite's bounds.Ā 

    +
  16. +
+
+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/b1/2bbda7eb533e54a3715c32e884412f2503abf2a7a210e4a814ecc9d9344ab7 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/b1/2bbda7eb533e54a3715c32e884412f2503abf2a7a210e4a814ecc9d9344ab7 new file mode 100644 index 0000000..94d344a --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/b1/2bbda7eb533e54a3715c32e884412f2503abf2a7a210e4a814ecc9d9344ab7 @@ -0,0 +1,2 @@ +I"

Metaprogramming

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/bd/b9377cb76b60b872e12f5491f2a4c1117ab233f42fdc84c8c69ccb103160f2 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/bd/b9377cb76b60b872e12f5491f2a4c1117ab233f42fdc84c8c69ccb103160f2 new file mode 100644 index 0000000..b0d9ac9 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/bd/b9377cb76b60b872e12f5491f2a4c1117ab233f42fdc84c8c69ccb103160f2 @@ -0,0 +1,2 @@ +I"

reference manual

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/cf/8b7a044d4c00cbcbd4af3e3d2c8dc88c2508c77335dda961e090f2e658cdd3 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/cf/8b7a044d4c00cbcbd4af3e3d2c8dc88c2508c77335dda961e090f2e658cdd3 new file mode 100644 index 0000000..4060b2b --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/cf/8b7a044d4c00cbcbd4af3e3d2c8dc88c2508c77335dda961e090f2e658cdd3 @@ -0,0 +1,2 @@ +I"#

Snap! Reference Manual

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/df/bc82aa2873f2939f5e88b3569b141240a8eaff9cf0a8566e6406c0d3f039c1 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/df/bc82aa2873f2939f5e88b3569b141240a8eaff9cf0a8566e6406c0d3f039c1 new file mode 100644 index 0000000..a8cb202 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/df/bc82aa2873f2939f5e88b3569b141240a8eaff9cf0a8566e6406c0d3f039c1 @@ -0,0 +1,2 @@ +I"

OOP with Procedures

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e1/4cc487a2af687a341cccb0ddcd0b952fc1a9f086b60980f77f5e36ffb9970b b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e1/4cc487a2af687a341cccb0ddcd0b952fc1a9f086b60980f77f5e36ffb9970b new file mode 100644 index 0000000..3a67017 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e1/4cc487a2af687a341cccb0ddcd0b952fc1a9f086b60980f77f5e36ffb9970b @@ -0,0 +1,2 @@ +I"$

User Interface Elements

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e2/7b09b63e1dbdb1232c1ca414f4af2d46e15e0efdd878d54be937606e23c156 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e2/7b09b63e1dbdb1232c1ca414f4af2d46e15e0efdd878d54be937606e23c156 new file mode 100644 index 0000000..2dda1cd --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e2/7b09b63e1dbdb1232c1ca414f4af2d46e15e0efdd878d54be937606e23c156 @@ -0,0 +1,2 @@ +I"

Building a Block

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 new file mode 100644 index 0000000..e135808 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 @@ -0,0 +1,2 @@ +I" +:EF \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/f5594703486f7a696894563a7e74dade92ef41a6717f30db6283150833dc86 b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/f5594703486f7a696894563a7e74dade92ef41a6717f30db6283150833dc86 new file mode 100644 index 0000000..b67f132 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/f2/f5594703486f7a696894563a7e74dade92ef41a6717f30db6283150833dc86 @@ -0,0 +1,2 @@ +I",

Appendix A. Snap! Color Library

+:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Module/1a/5068b93114de8206f065d3736f2b4b72f74e80fcf8e4779773e8204230618b b/.jekyll-cache/Jekyll/Cache/Module/1a/5068b93114de8206f065d3736f2b4b72f74e80fcf8e4779773e8204230618b new file mode 100644 index 0000000..845e216 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Module/1a/5068b93114de8206f065d3736f2b4b72f74e80fcf8e4779773e8204230618b @@ -0,0 +1,42 @@ +I"™ +:ET \ No newline at end of file diff --git a/.jekyll-cache/Jekyll/Cache/Module/61/4f14a90c1f22d251bd66e0dbb7402ba9a700f6f673d8a950148756a21e7666 b/.jekyll-cache/Jekyll/Cache/Module/61/4f14a90c1f22d251bd66e0dbb7402ba9a700f6f673d8a950148756a21e7666 new file mode 100644 index 0000000..088cbd0 --- /dev/null +++ b/.jekyll-cache/Jekyll/Cache/Module/61/4f14a90c1f22d251bd66e0dbb7402ba9a700f6f673d8a950148756a21e7666 @@ -0,0 +1,3 @@ +I" + +:ET \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..5f534f8 --- /dev/null +++ b/_config.yml @@ -0,0 +1,32 @@ +# Book settings +# Learn more at https://jupyterbook.org/customize/config.html + +title: My sample book +author: The Jupyter Book Community +logo: logo.png + +# Force re-execution of notebooks on each build. +# See https://jupyterbook.org/content/execute.html +execute: + execute_notebooks: force + +# Define the name of the latex output file for PDF builds +latex: + latex_documents: + targetname: book.tex + +# Add a bibtex file so that we can create citations +bibtex_bibfiles: + - references.bib + +# Information about where the book exists on the web +repository: + url: https://github.com/executablebooks/jupyter-book # Online location of your book + path_to_book: docs # Optional path to your book, relative to the repository root + branch: master # Which branch of the repository should be used when creating links (optional) + +# Add GitHub buttons to your book +# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository +html: + use_issues_button: true + use_repository_button: true diff --git a/_toc.yml b/_toc.yml new file mode 100644 index 0000000..74d5c71 --- /dev/null +++ b/_toc.yml @@ -0,0 +1,9 @@ +# Table of contents +# Learn more at https://jupyterbook.org/customize/toc.html + +format: jb-book +root: intro +chapters: +- file: markdown +- file: notebooks +- file: markdown-notebooks diff --git a/intro.md b/intro.md new file mode 100644 index 0000000..f8cdc73 --- /dev/null +++ b/intro.md @@ -0,0 +1,11 @@ +# Welcome to your Jupyter Book + +This is a small sample book to give you a feel for how book content is +structured. +It shows off a few of the major file types, as well as some sample content. +It does not go in-depth into any particular topic - check out [the Jupyter Book documentation](https://jupyterbook.org) for more information. + +Check out the content pages bundled with this sample book to see more. + +```{tableofcontents} +``` diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..06d56f40c838b64eb048a63e036125964a069a3a GIT binary patch literal 9854 zcmcJ#_ghoX7cGn*K?4W`P^xr9dX-2=s)7_L0g)Pd2}GoYu8}Goq=uqY=^(vJ3q7D9 zgx&ncihTY58>yQhyHVAq6+lGO~MVagOauq5m9v<`6Yyea8LU7g^33d5#6JIpIaLG z-1|gCJhU3BN``QY-K@=)`@JW9M^t~b7uLWQYei|mDOJQ5UUg0~vIqbGt~C8wn@$P% z5pl~zRjG%ihlB(HjNnDEe-dDz2JixSk(`6?==a`q;3sz5kB=vYkB^Usv)VI9k21rD zJiTz9qguh+nKE8m#+pE4C16PIb7Iqf7uN3q_3Quydk+ycREf|Kaf=g!AT$7Pt5%T^ z8aVDmSdkMNlHc+OU`GfMo(G6M`@b>}|7lC2WNZAX;dG{O$?=D%iOq{^-7HrB zcK+ZB)!$jy15VseoVKDTyWDkjAxOOZ*QX8d#=@20sP;i@Xow95<_tP$?zwjiu96e z>w=n(W1oxV>vfZL+?;M$rHrbr-j~Q4Z0#f{{?B_kL)V~b;Ypj(r`bl+t51=jl6us% zisP0c%+gd*@NjHx-9P?#e$1%)t<{43ZZ7psNeO=)Y*C@keuU`+V-r`LF5ytZC}IBu zbG$h|;({qNsYw+4y*-`g9}w-)-1o;4J-XQ1@Hi(x-*u)|Ne#p@^B%N%Ah2Q;LCG(ZHBQFL?Li-e*gAW=zAB)SnqFmSqA*R7HO(vfNpkV`XWrI=Kemp{ z`XTgmXPPHd1fbknj1MsBI};8fOdfpI;lh4^A@)#qeVu zJb2)IeR*!gAy`Wti~X5b#3bXH#-tDsvNcs{`2~3O>45+@w=lsB@yx}N+7A*AT1iWo zCLk(xWbfP7ppKMjUV$FTMNv+WKG*ZuS~AGj-P2i^ah`gNkqv6jA-Y4>M+bYJ1ouAM zhio_#B1U3u6!)N$?mJ2ZbANVV>Xl|5+3DVVOU$d89?>$dF>ix#X2Zv>SuCqqWS!S> zomY&g)au`g*ER&}`dKnw-|KyL(Xv>>BAvCz#~c7<2z4i2S3Ea{s$tl4;Fmfrw5uQ6 zdZdFouB9Zn$Ox^;m&3&jBs=B z%AGu-+-3>0hu*7*Go%ig0F*a+}bQ z8Cc)R_4Xa}T)gvvu4H@GAS#AA)o|_JsNW8zdTY`Y2EMw$8M6iKf6zLo2}vX5#E`E8 zLfTXySbqo;)cm*vz`Y<&q8-QUpyBxlw(wEG~e8ar+}fF-S+sb& zDz})rHK~=qsT-W;2Plhi{U0Y!6S$rmj%Lf#_6Q{}o9ON=pa2rAPpn&9&e(qYe-t*V z@vGCn-F!I$@0)jPw(#1-v_r^JT~5YZW{`r1+085#GB%6IJC?RRv%5q~F>%c&OxynZ z%xYjt7MVY0BPNAf>4{^p{XbrcwEclTApV;6FC515Ns#UfLZ z2YrA=|5>ly8F0Bp+l*6!<>1heHsIR01D`C08YNKz!~*JpVLU<@0QpHnTUW{;>sYp= z#eU02VX*}f3vp`~7iJXDzx9yXd^Up*0-yHrbarsvW*UH%P49|4$4@)tJgR$?6o6f5 z(}}v|BxI|mgea@2>qg^b#ozLf17HU@5Fa-Fraz@QN%7lZ5lq)Vn7Q=hZ-RdZ+wFlD zJdw!7J1*GND#_)ys*=%^U*Zr0;^&s<^_q%ds6d3-IC~_amnNV&0xM^1;`=@1xFn zORQ(tnI35sf7lD%W&%N9E6Y~6qoNr#BAw2aiDiR!7CS8KoW|9)GoJAAS##ZIrQTUl zBW}q?kb$Tk4JP=7j@W0(Ea^R`$D>gU%nfa^3Dwub5~JS+2Q@c7Z9!yGJ7`P^5kIj$ zg3O{je@?Kt&v;;R&~$K48WR=L6GcxNIc4yw)BgJ8Bb7oLJ2X_3X0F)>>o%A^0m7n(dq+!+P%cBi)cl|I6CzcZF{kC1jgSv|j(+zAw~tn#IxO6lUd zj3V;e_C=~at8H=>ZGE#9<8QfP>BH9b3(Dp1zuXnN-uc&csJ#%8Q4@!2to4XneWRff zIaA{h=OO9fyAt`B20gSGZE0+5EGtCJ!AS6zFb)b4RvV0{cMY(`Y<6f+_ign{;I9w2 z?`CxPvQXRE34SVHT0>{c&%(Dx6)wu&)H)_KU+lGLizO9h`wd3$Z?JRA2VVyyEvYkH zj67X5JX#+y_;{BJ&ZZ+qCX?k*~w*V_4;9w2D`5E~7T0 zi3~~~jxu(te?CA<_w_{5#uzKO&O9+lj}F{x+F-4r%K9((FwF&kFVse6mP!vDt_>x9 zUx>VaMt_HzSdkN>rs`F|pR*{TM8rR(unZk0EXqrLLqyw#%|A#KhSQVT6e&4@$gbX?Lg3SMXEj8wDG)D;FDQ8q8%^qqz=<=X1rcVpN?A{w?-*WMkRlJWw z3+-+`iUdC0c&rucqhLSGU;|L-v$MoCUgN^3b8#YnlqTL^wOuSldYIkFOhc9*s!|7C zZCfJ4{p-Vci9_o*vV1IliLv_qg!ONlaCFU*O(&by>`lq|I z4hpOFuCt)IyVtJs&2^hgfhWI>P3B?isG8c+o4E?=CTZWp{P7tyGpzM%&=GR+HEzQq z;QD++XUMPpY$fV5j+c40`CQ?TIK@slTaYNrn;_-|+;Pj|71}f4JSG4)@AI{Y``0;x zLIAw$!n>UCW{q*q4}sT5IX7vGytw4;e6H4@D|~;@%gt~92mAUO5uvgxOB5{Ep(ELz z2y^2geQ@Ae;wJm&>(%ce!yCWuih%7rn$vb`hZwIICxbe)vwUsJ`2COHc=-h!)ol1J zae_fdeqQ#!4Z#;G@7#18om~t^Dkw@;k|8CYnl4`WYjT=O>;V$I*8CVeKahu}oThzI zby8mM|V!o$r$h~2x@YYgecvv)44 zVEmn@-71;kO#&Fe!dj}OTkMCigz^2|hDFfuhsUY!IpqW^Rup!q8D*X-)f`dZYB%V( z+J*fl9B5WrGvpO-E^E$NZT%lAFfaIUD6e?hS2V7Wc__#^DX?+UE*yzRce_CIV*Ig- z{@Au>EMGnM(+{WpNRX7+Z+dydzM}QZc1KP7jO|yav-WKD37#31CiIdmppsvasoZjJ zhjMmpSbHGVq~5PpJY6V>>3^|%q!?r@6j>j<0Q>N?Q0ng{%+Hv@V2buU<19&o4fYJ3 zRGPrfikVAIeWWMdn<`28#Px;wwVB2fJsK(!YG{yS2zy&s*m4tR82lID$;!4LN{)!y zpw)6_si`@A8LBejn^g}GjhqlZDAg{@exDRYNd-JHnKP1SG{R>+AL4dGabfD5bgVHmK*ej73ye~XLd@pb%2zq%8KX$Hu7^Z0-YJ;>P` zMz#ko5|<$pp_sI$-oYj5Rh=9)S^tdB2NesZ#!D?}dqn52D&U`j+g9hxWVkkYBdn4% zc1N30W|e88l8+P(9tA)ET&$81!y6FlDYdS0di~KK=i%a0-3?AToyPe^X?C+|Opi&` zbYC5`m0#x7y;R^{@3?t`@KHC#yOZy27qg$X^7DX*k*Y3=r*l?48H^0m@Zwspa2w!= z8Rzo~D@*^~I(w;37S?CAu65^aOXttu1t0tLL~jVQR1W5BCjS95x7_>(Zn95tLXtC* zAm8pA%*Ozxz$w46`Mo9f*vB&x+b$=u+Rs;z6TfMxU!%gWE+ByCzxygTL4BDhyv1d} zD{w^)?0bgm#ph9M!q4%-kFW6k$paVLINgXgd}#yNe44b#J%%(m=NxxGP{<*vw)MiW z6(l~^rYnHK%O&5WXN!98Ny<2ab6T^H9CrHXik+$sMot2o2Lo_hnsKuJwz^8h{%eED zr2qYWAmxXK|7vS?)YGY#yL&+^&tb?CV%7@vu~e0v#UWvx>Telu)*eDs26wvKAAXce ztkMG*S4qdZc!ua^$*k4(E6U{?$oIskaZkqURK+y3u8q`gKrVl;*Kr~!{`;%OR=SeB ztg)-z=sVw9%gUM?9nbAWb9|%m;w8yNvf{LmJDY1OcB@=q+=4Avtsm1NlJkLj{9Zl{ zRC#RkkoY@`MSlwW&pUEARg2XK0BFF<0#Y;GEnlJE-CR#m7hqrV%3DU|i@%R^k^PBt zL9=sbeO)J@Xjbkq>qG>iL5LcW_dHMcNq-6n&mRKy6!O?ZPQK4yWR5ho z{xPlMGn^?DBvWZmb@A?AY_C}N(gWxoy$S=QS5eTZZNYtHt5=3oKWhj+ zaI1UQC{CL^LFo3hB0Yv-r9m2lrMlI5bVANzvQRAEKf+Mm4kO*IX;k1Odq94dXD2Rs zWX}=%8D2#S>f=WSng80ZNRQ|oV9VtCLzT;8yEMCSo9+)@Kf$MS9rA)R#TWwx9jD+W zi=Qw0Y3I9G%tn(aT>or~nGrp+uA%epd$M7pH7C*qpS6v-koOaxCl@1mMC(q!bC(s) zUgY#LBuJW)rT0r8sRU(ABiG>{p%6yPkp?S?iJpV=r}PnKq7z9&)n=Xca+&dPn@b(& ze@Ry7r&SX0G7$e$1tfQ_eZVwx$s~3PWZ`c=&{$USD7g>1-9MIsOBgfi&|QFmfGN66 z9#c7bCn;+>Nxde;IuKZxgr+*ZjS~=78Slptsx0B zC(yjsMZl}YK{pqR$m-cI5O-qwWr{63uC0&=YTvT9y zqo$r(5f9TobpUqSOOL1pntof&8#PdLxxmJ+JLjGv#)W(sdt|m&Pg~Ei>X{9WRM-FL z1ug=$A>CFfx;j-KXvS4L_(V+6QyE%^N?!-xBP2BBQ&_ebDIcw^RMMR1W|7&hYIg>2|Km|AZ``=`r~-Lr_^!%2k1B)uvrP6qZ4d`6mPBN>!xZ zJk**bYPy$w%2j60-W`={AU!!oHcBpiucFvTp~*34H)rMJxvaCFizQ$>@9ORE9?hrY z_T-JG%a{$#O{{Y(Q@I#^@Irxli=@R7a-z_}8Dgl&lu4==oQh=QPkJP(*KtS8U5075dF7 zk<6-UO^#Ci_8qvBD}L=^EXWWqC7Ki;}V;^B#BGlT;7cAwRaC& zbWyAQj{@gNy2Gix);R!v_O^)R%4Ip-S@)aIy3x`iPB(2_!mn0a%vs>k4@ENe8|dXK zHIjH9)!DsyQ_armEk(s_CL(LDUW*)7qrAO%P<3Cqijj$(X$*6}#_C8^v1VmCWJ3)T z|NZ4>M2bedT9pKY4Q7bvkLx|;@_%6ztsBvH1rl^a`}A}Jw($PS)0VjqRNGVbvSsj1 zeq5c?zFG;a$eXVSb{-Qhrt$Ln4+G5@1M_i1Fd>I!(Z%Ryk{|<_Z0^nWo_yDc#qZRN zW*Uzoe6ISr;?i&$?@WdN7*w?_e&Bt%7FO_$#Pp-o%+Bmb?YO52TFJ_X=Y` zB79{;AGE8w(H+`M-ReL&@+8qpOiubk(5AfNWE$Iqg?mQ0-sS zlV5}N6=QWM-DmG5T$?m-d0zL9tvkD61+==-ZvvE}&!_HEa);T%|5iUNQgr??Arj2v zYeVDHiT2)^j`CqWEdiHi8rN_or|xDgsM^V2=a8S%L1RY)zkF1Bo+rlV-5C~88P38p z>}G^G6k1xQ5BXO3n!~$(MW8-5Y&VdjIRXZ``{U*C+40wek?4&Psi$FSNhg8N zU>DZ?ITJ2d!p5txmKpAB-_hjqgY3%%Myhw3#rRoHotWKDxD&LqP=@Yh^miCTC#uU( z=E!Jmu<%zp1u}I+JV)@$hXbDq!nQdddw1iD+p{!H2R#miIqW_TAeZvSG>?CwQDl<= zq&r!EMjYv>v=zr(%WfQ4B|0sk7UEOk!}O@D@vX9{>t{X+!7w~tYw!I{;N8C%TN>!M z>7xX?(GH%vZg|!Xp4X8E(FQ-T=0g3Wlt`Tf|0;>yF&gVyM`s}om7?7plxL!q;@a!V z{l4{qolEEroMw2oJNmp@)G2ljpK|T#-8cW*{bS2K$Q!%h%5Qx>Yp}*|3=`1IrGYA_ z#3pFJc%b*?vw(G9JA{OJs6Iu?03Z#!9|dMV4WKd?L9VWXkJ|UY=bg3AH;sIrwQD;I zc&6=zrtXy=AOQHjS}Aa=9}Kkvkysnn7oOmLzpHuu&^6N3?IQXpetcqqXIvVbh9q;e zZ*y5xQ0j@_UR5}&q#}Q}_z?g~1NZ0~DoWtg{a2c3{5#i|(VB{zs7lh{ns-0}39+eZ zmuodiGS}9p!Cll;j;+GMld@E%{}vT(vQ^7~sZyUydd{}xs*Gvp`d6JIiVu(*_EN9q z$Qn5T>zL^jWs2J*dS)WbaTymtJNWt7SCtZNBxs!#HlJZ0Xj4IzF#0FmKaa9WFj*t^ z4$IrEQwQer_l3e3LFZ0uR?w~Qj8tBUW5aL8_8yvFiQH_QgmCjr9apD6&DIQX(SNWv zb|F@%eNq*cn1*MdhziznN^XqbD54Rd`f42e z%dkRxE0pw|k;g*Kxz=~~Q^d%iQS|mdZfV%PFuTgKOoQQ2B*Db7CQ{U+%(vqjr2@+)eLf{cZscW-ddJS@qnyU6i*!6DF%fms`AZv@>Z`K>M^jl7)Jy^-; z(0WW!4OGD=qRpx%OsLesm*9)M|LH&G?IjJgE9N?vI~25Tc)^B;`$p7s5P+z)rqsu8 z#LN*-*k4E7rlzJtJp0n5I7ds<0+d9DE{E_46|Ejr244-$k>h0krj6YhP4oX0jS7JghDO3@cFKC#AZ`8L30t0U8)M^2*m&M6}$Qp~Q_wmx(G zn(!n3Y)O0=4MK=5P0>QQfvJ@cAL_pnWzfF4g)K|wu=I~FYX(3W-2 zf|@^YU!Ut&*_K+D;p+qF5BVv9?k(CLxvwrM?*$1Y8Q1rO%po-&x{`*9F<>gKc8C(qtBR&?*4F>(;9=xmQap z#=6YaIOw962LhIK=$)s(7ibVg-6j|qt}Gf?spXuC?|60jPfUv_x01+;B7RU=)jPnT zh|?|SxQAbf65$EmPTvdZzt8N+PABxnwrkm)Y?Tga)nYIMgoc7w4XzRV2$`%ex6z9bNU zTv2t^8?QF3hskl_jm7(RNCWicsx?yw57HN%DNW%~m{)QN=KZ8m6{!i#T2h!Xg3@O2 zaAK4htobm}2YP9pB2afR<%OFoY%oDA4Bs?^mtDV=I(pY}zRp|(4qBFfrFG}vZP7x$ zMB$pC$#-tpQDWYIddI0^+71N$Q1U1_4^iys=?2}s!KPO2!JcD*HVg#F{oEWIe*nU-%yV<;YJz}09_`Dz?AWLlKA$!=5B7tkp z9_Ihe&3$NL+wtF@TpDvLR)ihayRpLvH0}o-Zvte|uU@(+0lWT*aU3ZK?GKTLYcJCO zQ~U7QT6{r3c?3TzU|gX^V}%M%XI;xd_qK-&M9KdV1Sos|8}%17JACDbM!iDforMt* z7Auxhgv1PQq~6FDWuVifhd=4`Vl2Xr#vI%}S{cQRAwGNOF9zF0RTH&w_q#Z%t4 zGx*92|7e3Cd$W~Y2_l4SU!I)$Ol%$mL(dkfgnhfk3#n<-t!kX(JFLhS_|%>=Fst7u zheXTT)Vo^bsf*`klEo@*>S0f;%3gz^+m_^rcv(QLan(?cKx9RG{g^Ez;QtBl6Ph+saou0`c!| zI8XcO^OnR(X{|3YvOxJr%@#4@tTR!0O7_qzZS`-=iZ3mwL3@LwASi z(QvV}`KN5>8$=N+@p9IR8VfQdvSZ+Lf{Fv;$%v%_0s%+RBoafg; zB^upVY;ewq1QLHeD4y<6Oa4d6hgbOmM;(hw8Y(3@UM)XV_nC91+I{svghGcwL9DQC zyM&5PhT=%Y7C{j)JyC3slsF1h)J!2ju6cNc?HhXJLHl25entk$v!XYOzK=(rP~Rh! z*p(T?yl4h)l~Mkkoa1>4%y{DERdSd$UE=vGXLs>#A3q)Cuz$F)ey2S&b!HYf=Mm@i z$vBfjX|diF=}~}Se`0d%u`^s!Jiz*S>KK$b5mKnTyL{tReI0e>|9%tuAFB^Xu1EqI z2*~6xoM8t-esZMcNE3x1OqyN-Lp+FtX23bZdIhv1I_L3poeEE12w+x`r3BtK?UgS_ zgjv%6!;CN9dDzM}v3-DxU~SIgW9;-IvqR%OnBm4Ejqg0G}YnQC~*J|RZ=pB5-~vu$W~ z)Un>6^zlydKLzhIZ?b;=zuG68MC1PzKM`{<{lBe>Vh5EBTCLDuB`X-584ml0{G L>8MsHTOs~GC;Fmw literal 0 HcmV?d00001 diff --git a/markdown-notebooks.md b/markdown-notebooks.md new file mode 100644 index 0000000..a057a32 --- /dev/null +++ b/markdown-notebooks.md @@ -0,0 +1,53 @@ +--- +jupytext: + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.11.5 +kernelspec: + display_name: Python 3 + language: python + name: python3 +--- + +# Notebooks with MyST Markdown + +Jupyter Book also lets you write text-based notebooks using MyST Markdown. +See [the Notebooks with MyST Markdown documentation](https://jupyterbook.org/file-types/myst-notebooks.html) for more detailed instructions. +This page shows off a notebook written in MyST Markdown. + +## An example cell + +With MyST Markdown, you can define code cells with a directive like so: + +```{code-cell} +print(2 + 2) +``` + +When your book is built, the contents of any `{code-cell}` blocks will be +executed with your default Jupyter kernel, and their outputs will be displayed +in-line with the rest of your content. + +```{seealso} +Jupyter Book uses [Jupytext](https://jupytext.readthedocs.io/en/latest/) to convert text-based files to notebooks, and can support [many other text-based notebook files](https://jupyterbook.org/file-types/jupytext.html). +``` + +## Create a notebook with MyST Markdown + +MyST Markdown notebooks are defined by two things: + +1. YAML metadata that is needed to understand if / how it should convert text files to notebooks (including information about the kernel needed). + See the YAML at the top of this page for example. +2. The presence of `{code-cell}` directives, which will be executed with your book. + +That's all that is needed to get started! + +## Quickly add YAML metadata for MyST Notebooks + +If you have a markdown file and you'd like to quickly add YAML metadata to it, so that Jupyter Book will treat it as a MyST Markdown Notebook, run the following command: + +``` +jupyter-book myst init path/to/markdownfile.md +``` diff --git a/markdown.md b/markdown.md new file mode 100644 index 0000000..faeea60 --- /dev/null +++ b/markdown.md @@ -0,0 +1,55 @@ +# Markdown Files + +Whether you write your book's content in Jupyter Notebooks (`.ipynb`) or +in regular markdown files (`.md`), you'll write in the same flavor of markdown +called **MyST Markdown**. +This is a simple file to help you get started and show off some syntax. + +## What is MyST? + +MyST stands for "Markedly Structured Text". It +is a slight variation on a flavor of markdown called "CommonMark" markdown, +with small syntax extensions to allow you to write **roles** and **directives** +in the Sphinx ecosystem. + +For more about MyST, see [the MyST Markdown Overview](https://jupyterbook.org/content/myst.html). + +## Sample Roles and Directives + +Roles and directives are two of the most powerful tools in Jupyter Book. They +are like functions, but written in a markup language. They both +serve a similar purpose, but **roles are written in one line**, whereas +**directives span many lines**. They both accept different kinds of inputs, +and what they do with those inputs depends on the specific role or directive +that is being called. + +Here is a "note" directive: + +```{note} +Here is a note +``` + +It will be rendered in a special box when you build your book. + +Here is an inline directive to refer to a document: {doc}`markdown-notebooks`. + + +## Citations + +You can also cite references that are stored in a `bibtex` file. For example, +the following syntax: `` {cite}`holdgraf_evidence_2014` `` will render like +this: {cite}`holdgraf_evidence_2014`. + +Moreover, you can insert a bibliography into your page with this syntax: +The `{bibliography}` directive must be used for all the `{cite}` roles to +render properly. +For example, if the references for your book are stored in `references.bib`, +then the bibliography is inserted with: + +```{bibliography} +``` + +## Learn more + +This is just a simple starter to get you started. +You can learn a lot more at [jupyterbook.org](https://jupyterbook.org). diff --git a/notebooks.ipynb b/notebooks.ipynb new file mode 100644 index 0000000..fdb7176 --- /dev/null +++ b/notebooks.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Content with notebooks\n", + "\n", + "You can also create content with Jupyter Notebooks. This means that you can include\n", + "code blocks and their outputs in your book.\n", + "\n", + "## Markdown + notebooks\n", + "\n", + "As it is markdown, you can embed images, HTML, etc into your posts!\n", + "\n", + "![](https://myst-parser.readthedocs.io/en/latest/_static/logo-wide.svg)\n", + "\n", + "You can also $add_{math}$ and\n", + "\n", + "$$\n", + "math^{blocks}\n", + "$$\n", + "\n", + "or\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\mbox{mean} la_{tex} \\\\ \\\\\n", + "math blocks\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "But make sure you \\$Escape \\$your \\$dollar signs \\$you want to keep!\n", + "\n", + "## MyST markdown\n", + "\n", + "MyST markdown works in Jupyter Notebooks as well. For more information about MyST markdown, check\n", + "out [the MyST guide in Jupyter Book](https://jupyterbook.org/content/myst.html),\n", + "or see [the MyST markdown documentation](https://myst-parser.readthedocs.io/en/latest/).\n", + "\n", + "## Code blocks and outputs\n", + "\n", + "Jupyter Book will also embed your code blocks and output in your book.\n", + "For example, here's some sample Matplotlib code:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib import rcParams, cycler\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "plt.ion()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Fixing random state for reproducibility\n", + "np.random.seed(19680801)\n", + "\n", + "N = 10\n", + "data = [np.logspace(0, 1, 100) + np.random.randn(100) + ii for ii in range(N)]\n", + "data = np.array(data).T\n", + "cmap = plt.cm.coolwarm\n", + "rcParams['axes.prop_cycle'] = cycler(color=cmap(np.linspace(0, 1, N)))\n", + "\n", + "\n", + "from matplotlib.lines import Line2D\n", + "custom_lines = [Line2D([0], [0], color=cmap(0.), lw=4),\n", + " Line2D([0], [0], color=cmap(.5), lw=4),\n", + " Line2D([0], [0], color=cmap(1.), lw=4)]\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 5))\n", + "lines = ax.plot(data)\n", + "ax.legend(custom_lines, ['Cold', 'Medium', 'Hot']);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is a lot more that you can do with outputs (such as including interactive outputs)\n", + "with your book. For more information about this, see [the Jupyter Book documentation](https://jupyterbook.org)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.0" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/references.bib b/references.bib new file mode 100644 index 0000000..783ec6a --- /dev/null +++ b/references.bib @@ -0,0 +1,56 @@ +--- +--- + +@inproceedings{holdgraf_evidence_2014, + address = {Brisbane, Australia, Australia}, + title = {Evidence for {Predictive} {Coding} in {Human} {Auditory} {Cortex}}, + booktitle = {International {Conference} on {Cognitive} {Neuroscience}}, + publisher = {Frontiers in Neuroscience}, + author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Knight, Robert T.}, + year = {2014} +} + +@article{holdgraf_rapid_2016, + title = {Rapid tuning shifts in human auditory cortex enhance speech intelligibility}, + volume = {7}, + issn = {2041-1723}, + url = {http://www.nature.com/doifinder/10.1038/ncomms13654}, + doi = {10.1038/ncomms13654}, + number = {May}, + journal = {Nature Communications}, + author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Rieger, Jochem W. and Crone, Nathan and Lin, Jack J. and Knight, Robert T. and Theunissen, FrĆ©dĆ©ric E.}, + year = {2016}, + pages = {13654}, + file = {Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:C\:\\Users\\chold\\Zotero\\storage\\MDQP3JWE\\Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:application/pdf} +} + +@inproceedings{holdgraf_portable_2017, + title = {Portable learning environments for hands-on computational instruction using container-and cloud-based technology to teach data science}, + volume = {Part F1287}, + isbn = {978-1-4503-5272-7}, + doi = {10.1145/3093338.3093370}, + abstract = {Ā© 2017 ACM. There is an increasing interest in learning outside of the traditional classroom setting. This is especially true for topics covering computational tools and data science, as both are challenging to incorporate in the standard curriculum. These atypical learning environments offer new opportunities for teaching, particularly when it comes to combining conceptual knowledge with hands-on experience/expertise with methods and skills. Advances in cloud computing and containerized environments provide an attractive opportunity to improve the effciency and ease with which students can learn. This manuscript details recent advances towards using commonly-Available cloud computing services and advanced cyberinfrastructure support for improving the learning experience in bootcamp-style events. We cover the benets (and challenges) of using a server hosted remotely instead of relying on student laptops, discuss the technology that was used in order to make this possible, and give suggestions for how others could implement and improve upon this model for pedagogy and reproducibility.}, + booktitle = {{ACM} {International} {Conference} {Proceeding} {Series}}, + author = {Holdgraf, Christopher Ramsay and Culich, A. and Rokem, A. and Deniz, F. and Alegro, M. and Ushizima, D.}, + year = {2017}, + keywords = {Teaching, Bootcamps, Cloud computing, Data science, Docker, Pedagogy} +} + +@article{holdgraf_encoding_2017, + title = {Encoding and decoding models in cognitive electrophysiology}, + volume = {11}, + issn = {16625137}, + doi = {10.3389/fnsys.2017.00061}, + abstract = {Ā© 2017 Holdgraf, Rieger, Micheli, Martin, Knight and Theunissen. Cognitive neuroscience has seen rapid growth in the size and complexity of data recorded from the human brain as well as in the computational tools available to analyze this data. This data explosion has resulted in an increased use of multivariate, model-based methods for asking neuroscience questions, allowing scientists to investigate multiple hypotheses with a single dataset, to use complex, time-varying stimuli, and to study the human brain under more naturalistic conditions. These tools come in the form of ā€œEncodingā€ models, in which stimulus features are used to model brain activity, and ā€œDecodingā€ models, in which neural features are used to generated a stimulus output. Here we review the current state of encoding and decoding models in cognitive electrophysiology and provide a practical guide toward conducting experiments and analyses in this emerging field. Our examples focus on using linear models in the study of human language and audition. We show how to calculate auditory receptive fields from natural sounds as well as how to decode neural recordings to predict speech. The paper aims to be a useful tutorial to these approaches, and a practical introduction to using machine learning and applied statistics to build models of neural activity. The data analytic approaches we discuss may also be applied to other sensory modalities, motor systems, and cognitive systems, and we cover some examples in these areas. In addition, a collection of Jupyter notebooks is publicly available as a complement to the material covered in this paper, providing code examples and tutorials for predictive modeling in python. The aimis to provide a practical understanding of predictivemodeling of human brain data and to propose best-practices in conducting these analyses.}, + journal = {Frontiers in Systems Neuroscience}, + author = {Holdgraf, Christopher Ramsay and Rieger, J.W. and Micheli, C. and Martin, S. and Knight, R.T. and Theunissen, F.E.}, + year = {2017}, + keywords = {Decoding models, Encoding models, Electrocorticography (ECoG), Electrophysiology/evoked potentials, Machine learning applied to neuroscience, Natural stimuli, Predictive modeling, Tutorials} +} + +@book{ruby, + title = {The Ruby Programming Language}, + author = {Flanagan, David and Matsumoto, Yukihiro}, + year = {2008}, + publisher = {O'Reilly Media} +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7e821e4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +jupyter-book +matplotlib +numpy