# Vassar Science Scholars Lecture/Lab

Saturday, March 26, 2011
9:30am–12pm
Sci Vis Lab, 3rd Floor Mudd Chemistry

We will explore selected parts of the Scheme programming language using WeScheme, a browser–based programming environment. We will discover that algebra provides the foundation we need for learning how to design programs. The concepts of variables and functions you learned in algebra carry over to designing programs, with an important difference: variables can represent more than numbers. For example, Scheme variables can represent text, images, and composite data too (for example, `(x, y)` coordinates). Similarly, Scheme functions can consume and produce these additional types of data, in addition to numbers. We will write programs that permit us to play with numbers, text, images, and even produce some animations—all from the WeScheme programming environment in our web browsers!

### Numbers and Functions

We will be writing programs in the Scheme programming language.

A number is a simple Scheme expression that evaluates to itself in the WeScheme's Interactions pane. Type in some numbers (one at a time, then hit Enter):

• big numbers, little numbers (really big, really little—try it, go crazy!)
• positive numbers, negative numbers, zero
• integers, decimal numbers
• special constants: pi, e

Scheme has many built-in mathematical functions.
The most common functions are: `+`, `-`, `*`, and `/`

Once again in the Interactions pane, type in some Scheme expressions (and hit enter to evaluate):

• `(+ 1 2)`
• `(- 10 1)`
• `(* 2 3)`
• `(/ 8 4)`

Notice two things about these expressions:

• they are parenthesized
• they use prefix notation, not infix notation (the operator comes before the operands, not between the operands)

Challenge: try to convert each of these expressions into Scheme expressions (parenthesized, prefix notation)

• (1 + 2) - (3 * 7)
• I'll do the first one for you, as an example:
• `(- (+ 1 2) (* 3 7))`
• 3 - (1 + 2)
• 3 - (1 + (5 * 6))
• (1 + (5 * 6)) - 3

### More Interesting Functions

If Scheme were just about evaluating numbers, it would be pretty boring! Scheme also supports strings of text and images, and functions that work these types of data. Evaluate these expressions in the Interactions pane:

• String functions
• (string-length “hello”)
• (string-append “hello” “world”)
• Image functions
• (circle 50 “solid” “red”)
• (rectangle 40 20 “outline” “blue”)
• (ellipse 20 40 “solid” “purple”)
• (triangle 50 “outline” “black”)
• (star 20 30 40 “solid” “magenta”)
• Boolean functions (true/false)
• (string? “Scheme”)
• (string? 42)
• (number? “Scheme”)
• (number? 42)
• (string⇐? “apple” “banana”)
• (>= 50 42)

Many functions are provided by WeScheme. To see more functions, click on the “API” link in the upper right corner. API stands for Application Programming Interface—a library of functions available for programmers to use.

There are more functions in the API than we have time to learn how to use this morning, but we'll have a lot of fun with the ones we choose to play with!

### Definitions

The Interactions pane is great for experimenting with new functions and expressions, and figuring what works, but…

After a few times of typing expressions over an over, you might start to think: “Wouldn't it be great if I could name my expressions, so instead of typing in my expressions from scratch every time, I could just type in their names?”

We've been ignoring half of the WeScheme page: the Definitions Pane!

Data
Here's how to define (name) expressions:

```(define red-circle (circle 50 "solid" "red")
(define my-desire "I want to be a Computer Scientist!")```

If you type these definitions into the Definitions pane, you can type the names you just defined in the interactions pane, and see what you get:

• red-circle
• my-desire

Functions
No matter how many functions are in the API, it's never enough! Programmers need to define their own functions. Here's how:

```(define (green-circle r)
(circle r "solid" "green"))```

This defines a function that draws a green circle with radius r, where r is whatever value you specify when you call the function. The first line is the function header, the next line is the function body. Here's how to call the function:

```(green-circle 10)
(green-circle 30)
(green-circle 50)```

Notice we call our green-circle function the same way we call other Scheme functions. By writing functions, we extend the capabilities of the programming language we're using. Very cool!

Once we start writing our own functions, it's helpful to document how they work. Otherwise, you end up with a bunch of functions you don't remember how to use, and other programmers have even less hope of being able to use your functions. Just think how much more useful the API would've been with descriptions and examples of all the functions in that big list!

Here's one way to document our green circle function:

```;; green-circle: number -> image
;; draws a solid green circle with given radius r
(define (green-circle r)
(circle r "solid" "green"))```

The two lines that begin with semicolons are comment lines. Comments are read by people, and ignored by WeScheme when we run the program:

• The first comment line is a contract. It specifies what the name of the function is, the type of data it expects, and the type of data it returns. In this case, green-circle expects a number, and returns an image.
• The second comment line is a purpose statement. It describes the behavior of the function.
• When read together, the contract and purpose give us a way to describe what a function does, and how to use it.

Here's a mathematical function, that doubles whatever value is passed in to it:

```;; double: number -> number
;; computes a value that is twice the given number x
(define (double x)
(* 2 x))```

Type this function into the Definitions pane and test it in the Interactions pane. Be sure to Run the program before you try to test it!

Exercise

Write two more functions on your own or in pairs. One function should draw an image with different colors, depending on what color you pass in. The other function should be named hello, and return a string that says hello to whatever name was passed into it. For each functions you write, be sure to document them. Include:

• a contract
• a purpose statement.

When you're ready, demonstrate to us the functions you wrote.

### Animations

By now you're probably wondering about the animations I promised I'd show you how to create. Well, now we're ready!

WeScheme has a built-in function named big-bang (it refers to the beginning of time and our universe). For example, type in the following expression at the bottom of your Interactions pane:

```(big-bang
1
(on-tick double 1)
)```

You should see a number, starting at 1, double each second. I know, that doesn't count as animation. But wait…

…what can we do with a number that doubles every second? We could pass it into our green-circle function and let it draw a green circle whose radius doubles in size every second:

```(big-bang
1
(on-tick double 1)
(on-redraw green-circle)
)```

You might find it helpful to know that hitting the Escape key (upper left corner of your keyboard) will cancel the running program.

More compelling animation

Okay, we saw a green circle grow out of control, and had to cancel out of the running program, but what about something more compelling?

You know how movies work, right? Frame by frame, little changes in an image, but when those frames change 30 times per second, the illusion of motion is created for our eyes. If we can create an empty scene, and place an image in it, and repeat this procedure, placing our image in a slightly different position, and do this really fast, it will look like the image is moving on the screen!

Here's an expression to create an empty scene:

`(empty-scene 200 200)`

The values we pass into empty-scene specify the width and height of the scene in pixels. Pixels are the little dots of light that make up the images on our computer monitors. Pixels get their name from “PICture ELement”. Before we place an image into the empty scene, we need to talk about the coordinate system computers use:

• the upper left corner of the empty scene above is (x, y) position (0, 0)
• as you move to the right, the x value increases
• as you move down, the y value increases
• the lower right corner of this empty scene is (200, 200)
• the upper right corner of this empty scene is (200, 0)
• the lower left corner of this empty scene is (0, 200)
• this middle of this empty scene is (100, 100)

The Scheme function to place an image into a scene (any scene, not just an empty one), is called place-image.

```;; place-image: image number number scene -> scene

;; this expression places a green circle of radius 25 in the middle (100, 100)
;; of an empty scene with dimensions 200 x 200.
(place-image (green-circle 25) 100 100 (empty-scene 200 200))```

The name of a function that draws a frame in our animation is sometimes named render. We could write a render function in Scheme that moves the ball along the diagonal from the upper left to lower right of the scene:

```;; render: number -> scene
;; renders a green circle in an empty scene at coordinate (x, x)
(define (render x)
(place-image (green-circle 25)
x x
(empty-scene 200 200)
)
)```

Exercises

• change the shape we're animating to any shape you like
• modify the render function so that place-image changes the trajectory of the shape so it moves from
• lower right to upper left corner of the scene
• lower left to upper right corner of the scene
• upper right to lower left corner of the scene
• Time permitting:
• can you change the background of the scene from white to some other color? How?
• can you change the direction of the circle so it moves straight up? down? left? right?