7.1
Chapter 7: Learning A Second Language: JavaScript
Block Mode CoffeeScript JavaScript
7.0.1 Objectives
The same fundamental programming concepts apply across different programming languages.
Exposure to a second programming language allows students to understand that the programming
concepts they learn as beginners are the same concepts used by professionals. This unit introduces
JavaScript, which is a very close cousin of CoffeeScript, and one of the most widely used languages used
by professionals today. In this unit, students will use blocks to learn JavaScript syntax, and to see how
the syntax of JavaScript and CoffeeScript have many similarities, and they will transition from blocks to
programming directly in JavaScript text code.
7.0.2 Topic Outline
7.0 Chapter Introduction
7.0.1 Objectives
7.0.2 Topic Outlines
7.0.3 Key Terms
7.0.4 Key Concepts
7.1 Lesson Plans
7.1.1 Suggested Timeline
7.1.2 CSTA Standards
7.1.3 Teaching Notes
7.1.4 Lesson Plan I to use blocks to code in JavaScript mode.
7.1.5 Lesson Plan II to recreate the Broken Scene program demonstrating the iterative
development model.
7.0.3 Key Terms:
Websites
Block-mode
JavaScript
Text-mode
Scripting Language
Settings box in Pencil Code
Programming Language
7.0.4 Key Concepts
Languages in Pencil Code
Every programming language has its own syntax, that is, has a specific set of patterns of words and
punctuation allowed in the language. As shown in previous chapters, using a block editor view gives
students a view of the syntax for a language.
For a sense for how JavaScript differs from CoffeeScript, see the two function definitions below, one
written in CoffeeScript, and the other in JavaScript. Both text code and blocks are shown.
7.2
CoffeeScript Text
tri = (n) ->
total = 0
for x in [1..5]
total += x
return total
write 'sum up to 10:', tri(10)
CoffeeScript Blocks
JavaScript Text
function tri(n) {
var total = 0;
for (x = 1; x <= 5; x++) {
total += x;
}
return total;
}
write('sum up to 10:', tri(10));
JavaScript Blocks
Although looking at the text makes the languages seem very different, looking at the blocks reveals that
JavaScript and CoffeeScript are closely related languages. Generally, JavaScript requires more
punctuation, but the structure of most code is essentially identical between the two languages.
Choosing between JavaScript and CoffeeScript
In Pencil Code, a project can be switched between JavaScript and CoffeeScript by clicking on the “gear”
button in the blue bar. When you choose JavaScript, it is run directly by your browser. When you choose
CoffeeScript, the CoffeeScript compiler compiles the program into JavaScript before it is run.
CoffeeScript and JavaScript are closely related. They operate on the same objects and they have the
same level of speed and power when they run. CoffeeScript was designed after JavaScript, so the
CoffeeScript syntax has several advantages:
CoffeeScript syntax requires less punctuation than JavaScript, so it is easier to type without
syntax errors.
CoffeeScript directly supports more programming concepts; for example, it has syntax for classes
and await.
CoffeeScript uses meaningful indents, which means it is impossible to hide nesting mistakes with
deceptive indenting.
CoffeeScript avoids common mistakes in JavaScript such as approximate-zero-equality and
accidental global variables.
The default language in Pencil Code is CoffeeScript, because it is easier to learn how to read and write
text code in CoffeeScript. Why would a programmer choose to program in JavaScript? Because
JavaScript has three significant advantages:
JavaScript is an official standard designed by an international committee, and it runs in Web
browsers without translation.
7.3
The community of programmers who know JavaScript is larger than the CoffeeScript community.
Many people are working on improving future versions of JavaScript, and they are aware of the
good things in CoffeeScript.
JavaScript continues to evolve, and future versions of JavaScript will incorporate some of the innovations
in CoffeeScript. So even for JavaScript aficionados, it is worth knowing CoffeeScript because many of its
ideas represent the future of JavaScript.
And for fans of CoffeeScript, it is worth knowing JavaScript because there are benefits its larger
community.
Differences between CoffeeScript and JavaScript
JavaScript and CoffeeScript are closely related languages, and by understanding where some additional
punctuation is required, you can translate directly from one to the other. Here is a summary of a few
differences between CoffeeScript and JavaScript, showing how equivalent code would be written in each
language. We discuss these in detail below.
CoffeeScript
JavaScript
fd 100
fd(100);
if pressed('up') and not pressed('shift')
tone 440
if (pressed('up') && !pressed('shift')) {
tone(440);
}
for x in [0...10]
write x
for (var x = 0; x < 10; ++x) {
write(x);
}
for c in [red, orange, yellow]
dot c, 100
fd 100
var colors = [red, orange, yellow];
for (var j = 0; j < colors.length; ++j) {
var c = colors[j];
dot(c, 100);
fd(100);
}
button 'doorbell', ->
write 'ding dong'
play 'C'
button('doorbell', function() {
write('ding dong');
play('C');
});
sq = (x) -> x * x
write sq(5)
function sq(x) {
return x * x;
}
write(sq(5));
Parentheses and Semicolons
JavaScript requires parentheses after a function name in order to run a function call. These same
parentheses are optional in CoffeeScript, but are required in JavaScript.
CoffeeScript
dot red, 100
7.4
JavaScript also recommends a semicolon at the end of every complete statement (including function
calls, return statements, and break and continue statements). Not every line of code, however, is a
complete statement. For example, the first line of an if is not a complete statement and should not be
separated from the body of the if by a semicolon.
Punctuation for Boolean Expressions
JavaScript also requires parentheses after the words if, while, and switch to surround the tested
expression. CoffeeScript, does not require these parentheses.
CoffeeScript
JavaScript
if pressed('X') and not pressed('Z')
tone 440
if (pressed('X') && !pressed('Z')) {
tone(440);
}
The words and, or, not, is and isnt in CoffeeScript are not supported in JavaScript. Instead, JavaScript
uses punctuation for these Boolean expressions. The corresponding punctuation has exactly the same
meaning as the spelled-out words in CoffeeScript.
CoffeeScript
x and y
x or y
not x
x is y
x isnt y
JavaScript
x && y
x || y
!x
x === y
x != y
CoffeeScript allows the JavaScript punctuation for all these operators, but when programming in
CoffeeScript, it is conventional to use the spelled-out English words to improve readability.
Indents versus Curly Braces
JavaScript uses curly braces to indicate nesting. While indents are allowed, they do not mean anything to
the JavaScript interpreter. It important to use curly braces and make sure they match the indenting.
CoffeeScript
if x < 0
write 'x is negative'
write 'This is inside the if'
write 'This is outside the if'
JavaScript
Equivalent, but
bad style
if (x < 0) {
write('x is negative');
write('This is inside the if');
}
write('This is outside the if');
JavaScript
Good style
if (x < 0) {
write('x is negative');
write('This is inside the if');
}
write('This is outside the if');
Some beginners, when discovering that JavaScript is not sensitive to indenting, will write JavaScript code
with no indenting at all. This is a terrible idea, because it leads to confusing code like the example above.
Good code is not just functional, but readable.
7.5
If the curly braces are omitted in JavaScript, a control flow statement such as if, while, or for will only
apply to the single line of code after the condition. The red line in the JavaScript below will print “This is
not in the if!” regardless of the value of x. The correct way to write the equivalent JavaScript is with curly
braces, as in the last row.
CoffeeScript
if x == 0
write 'x is zero'
write 'This is inside the if'
JavaScript
Not equivalent!
if (x === 0)
write('x is zero');
write('This is not in the if!');
JavaScript
Correct; always
include braces
if (x === 0) {
write('is zero');
write('This is inside the if');
}
Never omit the curly braces in JavaScript! The JavaScript interpreter will not pay attention to indenting, so
omitting curly braces is an invitation to have errors like the one above.
It is important to help students understand that good style in a JavaScript program requires consistent
use of curly braces and indenting. Programs should always be written with curly braces after conditionals
and loops and indents must match with curly braces so that other programmers can read and understood
them. The number of indents should match the number of nested curly braces.
Understanding the Three-Clause for Loop
The current version of JavaScript does not have an array-based for loop like CoffeeScript. Instead,
JavaScript supports a “three part for loop”. This type of for loop is just an abbreviation for three lines of a
while loop on a single line. The following three are equivalent:
CoffeeScript
for x in [0...10]
write x
JavaScript
using while
var x = 0;
while (x < 10) {
write(x);
}
JavaScript
using for
for (var x = 0; x < 10; ++x) {
write(x);
}
The three-part for loop in the last row of the table contains three statements in the parentheses.
1. The loop initializer, such as var x = 0 here. This statement is run once, before the loop begins.
2. The loop condition, here x < 10. This statement is run before each repetition of the loop,
including before the first one. If it is ever false, the loop skips to the end and stops running.
3. The loop incrementer, here ++x. This statement runs after the execution of each iteration of the
loop, right before going back to test the condition again.
7.6
Although there can be 10 or more pieces of punctuation on the line of a three-part “for” loop, they usually
follow the same pattern, counting up from zero to some number.
Declaring Functions Using the Word “function”
Functions in JavaScript are always written out with the special word “function,” and functions that return a
value must contain an explicit return statement (whereas in CoffeeScript, the last value computed is
automatically the value returned). Here is a named function declaration in JavaScript:
CoffeeScript
square = (x) ->
write 'the input was ' + x
return x * x
JavaScript
function square(x) {
write('the input was ' + x);
return x * x;
}
In CoffeeScript, functions must be defined before they are called while in JavaScript named functions can
be declared out-of-order. JavaScript named function declarations are implicitly bound to their names
before any other code runs.
Unnamed functions such as function callbacks from buttons or inputs, still use the word “function” but
without the name, like this:
CoffeeScript
button 'get started', ->
write 'starting now!'
JavaScript
button('get started', function() {
write('starting now!');
});
When an anonymous function is defined inline and passed as the last argument to an event binding
function such as “button”, the program ends up including a curious series of punctuation at the end (a
closing curly brace, a closing smooth parentheses, and a semicolon). This sequence of punctuation is
very common in JavaScript code.
Waiting on Input Without “await”
Unlike CoffeeScript, the current version of JavaScript does not support the “await” keyword or concept.
That means that if you wish to write a program that waits on input, you must arrange function callbacks to
produced the desired effect.
Arranging any sequence of execution is possible, but it requires planning.
The table below contains a simple program to total up numbers. The program on the right is written
JavaScript using only function definitions while the program on the left uses the equivalent CoffeeScript
with “await/defer”.
Getting a loop effect requires the programmer to define a function that sets up a callback that causes its
own execution again. This is a form of looping through recursion. (Recursion will be discuss in more detail
in Chapter 9.)
7.7
CoffeeScript
JavaScript
await readnum 'How many nums?', defer n
total = 0
for j in [1..n]
await readnum 'Enter #' + j, defer x
total += x
write 'Average is ' + (total / n)
readnum('How many nums?', function(n) {
var total = 0;
var j = 1;
nextnumber();
function nextnumber() {
readnum('Enter #' + j, function() {
total += x;
j += 1;
if (j === n) {
write 'Average is ' + (total / n);
} else {
nextnumber();
}
});
}
});
The people that oversee the ongoing design of JavaScript are aware that the code on the right is more
difficult to write than the code on the left, and the standards committee is considering adding “await” to a
future version of JavaScript. Until that happens, the code on the right is what is needed to write this type
of program in JavaScript.
Common Syntax Pitfalls in JavaScript
JavaScript has more punctuation than CoffeeScript, so there are additional syntax errors to watch out for
when coding in JavaScript in text-mode. Here are a few forms to watch out for:
Issue
Code with syntax error
Fixed code
Mismatched curly
braces
click(function() {
write('clicked');
);
click(function() {
write('clicked');
});
Misspelling a keyword
funtion s(x) { return x * x; }
function s(x) { return x * x; }
Missing parentheses
after “if”
if x < 2 {
write('try again');
}
if (x < 2) {
write('try again');
}
Missing clauses after
“for” (JavaScript)
for (var j = 0; j < 10) {
write(j);
}
for (var j = 0; j < 10; ++j) {
write(j);
}
Mismatched curly
braces, hidden by
deceptive indenting
(JavaScript)
for (var j = 0; j < 10; ++j) {
if (j > 8) {
write('and finally');
write(j);
}
for (var j = 0; j < 10; ++j) {
if (j > 8) {
write('and finally');
}
write(j);
}
7.8
When getting used to JavaScript syntax, it is helpful for the student to get some practice reading
JavaScript punctuation so that they can quickly identify errors such as the ones above.
7.1.1 Suggested Time-line: 1 55-minute class period
Instructional
Day
Topic
1 Day
Lesson Plan I: Creating a Random spiral program using blocks and
JavaScript
2 Day
Lesson Plan II: Iterative Development Cycle
7.1.2 Standards
CSTA
Standards
CSTA Strand
CSTA Learning Objectives Covered
Level 3 A
(Grades 9 12)
Computational
Thinking (CT)
Describe a variety of programming languages available to
solve problems and develop systems.
Level 3 A
(Grades 9 12)
Computing Practice
& Programming
(CPP)
Apply analysis, design, and implementation techniques to
solve problems (e.g., use one or more software lifecycle
models).
Level 3 B
(Grades 9 12)
CPP
Classify programming languages based on their level and
application domain
Level 3 A
(Grades 9 12)
CPP
Use various debugging and testing methods to ensure
program correctness (e.g., test cases, unit testing, white
box, black box, integration testing)
7.1.3 Teaching Notes
Mastering these concepts and practices requires student to make several transitions. Students are
required to move from using blocks to text. In addition, they will now need to begin programming in
JavaScript which is harder programming language to program in as compared to CoffeeScript. Here are a
series of steps that will facilitate this new learning.
Step 1: Have the students to choose a program that they have already coded and analyzed in block-
mode and text-mode.
Step 2: Have the students begin pulling the blocks and arranging them (copying from an existing lab) and
then have then switch to text-mode.
Step 3: Ask the students to add a new construct to the program that adds a small feature by typing it in
the text editor and have them run the program.
Step 4: Encourage the students to keep adding small constructs and watching how the program
responds. Encourage students to switch to block-mode and add a block if that would make them more
adventurous and ready to try modifying the program; then switch back to text mode to become familiar
with text syntax.
7.1.4 Lesson Plan I
Note: For this lesson, make sure you are in block mode. Type in the code (switch to block-mode if
needed) and click the play arrow to demonstrate the results.
7.9
Content details
Teaching Suggestions
Time
Code:
speed(100);
pen(purple, 2);
for (var j = 0; j < 50; ++j)
{
rt(30, j);
}
Take the spiral program used the
Loops chapter.
Or this program.
Ask the students to use block-mode
with settings in JavaScript mode.
Demonstration:
10 minutes
Code:
speed(100);
for(var i=0;i<6;i++)
{
pen(random(color), 2);
for (var j = 0; j < 50;
++j)
{
rt(30, j);
}
}
Switch to text-mode.
Add an external loop to build 3
spirals.
Teaching Tip: Change the number
of iterations to 6, 8, and 12 and
show how the patterns change.
Talk about indentation, especially
the opening and closing of curly
braces.
Program code here.
Demonstration:
10 minutes
7.10
7.1.5 Lesson Plan II
This lesson uses the Broken Sample Scene program. Having already worked on functions, students
should now be ready to read code, isolate small snippets of code, and make the entire program work.
This lesson helps students understand the iterative development cycle, that is, the process of adding
small pieces of code to a large program.
Content Details
Teaching Suggestions
Time
Code
function mouse()
{
dot(gray, 50);
fd(15);
rt(45);
box(gray, 30);
rt(135);
label('..',30);
fd(30);
pen(black, 5);
rt(100,30);
}
// MAIN PROGRAM STARTS HERE
speed(10);
dot(cyan, 1000);
bk(1000);
box(green, 2000);
moveto(250, -70);
mouse();
/*moveto (-300, -150);
turnto (90);
road (600);
*/
Give the students the broken
sample scene program. Remind
students to be in JavaScript mode
and to stay in text-mode.
Ask the students to run the
program and fix the bugs in the
code.
Encourage the students to stay in
text-mode while fixing the bugs.
Provide the students with the
movie to demonstrate the running
of the program.
Teaching tips:
Teach students to debug by
adding one function at a time.
Step 1: Only have the code to
create the background, a call to
the user-defined mouse function
and the code for the mouse
function. Run the code and have it
work as desired.
Step 2: Add the road () function.
Show students how to comment
code that is not being used so that
it is available for future inclusion.
(See sample code in the left
column.)
Step 3: Students can now keep
un- commenting code and adding
pieces to get the entire scene to
work.
Demonstration:
30 minutes
Student Practice:
1 class period.