Haskell For Kids: Week 3

Where We Are

We’ve gotten a lot done in just two weeks. To sum up, we’ve done all of these:

Learned how computer programming works: all about compilers, programming languages, and libraries, and how they work together.

Wrote computer programs to describe pictures. We described simple pictures like circles and rectangles. We modified other pictures by stretching, rotating, and moving them around. And most importantly, we combined smaller pictures into bigger and more complicated ones.

Used variables to give names to things in our program, like the individual parts of our pictures… like sun, elephant, and so on.

Saw for ourselves the importance of staying organized, giving things good names, keeping track of related ideas, and using comments (sections of your program that the compiler ignores) to make notes in your program.

If you like, you can review those ideas in Week 1 and Week 2. Go on, we’ll wait for you.

Lines and Polygons

So far, we’ve been spending a lot of time drawing with circles and rectangles. That’s been fun, but it’s also limiting. What if you wanted to draw a star? Maybe you could rig something up by stretching or rotating rectangles in the right ways, but it sure wouldn’t be easy! We spent our second class last week talking about how to do something more flexible: lines and polygons.

Cartesian Coordinates

To understand lines and polygons, we’ll need a way to talk about specific places on the drawing. We do that using something called cartesian coordinates. The idea is to talk about a point by giving two numbers:

How far from the middle of the painting, horizontally. We call this the x coordinate. Haw far from the middle of the painting, vertically. We call this the y coordinate.

Here’s a picture that might help (taken from Berkeley Science, here):

We write a point as (x,y) where x and y are the coordinates as above: x goes right or left, and y goes up or down. The point in the very middle of the picture is called (0,0) because it’s immediately in the center both horizontally and vertically. Other points can be found by following the x line (or “axis”) to the first coordinate, then moving up or down alongside the y line (the y “axis”) to the second coordinate. Notice that we use negative numbers to mean “left” or “down”.

Exercise: Take a few minutes to pick some more points on the diagram, and see if you can write down their coordinates — that is, write them as a pair of numbers in parentheses just like the points already labeled.

If you remember, we said earlier that the drawing area on the gloss-web web site is 500 by 500 in size. That means the center is still (0,0), but the numbers in your coordinates can range from -250 to 250. (Why? Because 250 is half of 500, and half of the size is on each side of the center.) It might help at this point to get out some graph paper, and draw yourself a square, and see if you can find some points… like (100,100) or (-200, 50). As a special bonus, you can also hover your mouse over the drawing area when you run your programs using gloss-web, and you’ll see a tool tip with the coordinates of the place your mouse pointer is.

Drawing Lines

Let’s use those coordinates to draw things. Try out this program:

import Graphics.Gloss

picture = line [ (-100, -100), (-200, 50) ]

Can you guess at what the result will be? Now run it, and see for yourself. It drew a line from one point to the other. You can also draw longer (jagged) lines by listing even more points.

import Graphics.Gloss

picture = line [ (-200, -200), ( 200, -200), ( 200, 200), (-200, 200), (-200, -200) ]

Try to see where those points will end up on the drawing screen, and then what the result will be. Now run it. Did it do what you expected?

Drawing Polygons

Not only can you draw lines, but you can draw filled-in shapes as well. These are called polygons, which are just a fancy word for shapes with straight edges as sides. We can turn the previous example into a filled in shape:

import Graphics.Gloss

picture = polygon [ (-200, -200), ( 200, -200), ( 200, 200), (-200, 200) ]

Notice that I didn’t need to repeat the last point like I did for the line. That’s because shapes have to be closed off, so Gloss assumes that we meant to add a line back to where we started. Of course, rectangles aren’t very exciting, so here’s a program that Ms. Sue wrote!

import Graphics.Gloss picture = stars stars = pictures [ translate ( 100) ( 100) (color blue star), translate (-100) (-100) (color yellow star), translate ( 0) ( 0) (color red star) ] star = polygon [ ( 0, 50), ( 10, 20), ( 40, 20), ( 20, 0), ( 30, -30), ( 0, -10), (-30, -30), (-20, 0), (-40, 20), (-10, 20), ( 0, 50) ]

Can you guess what that does? Here’s the result.

Thinking Like a Computer

That’s what we did last week. This week, we’re talking about how to think about computer programs from the computer’s perspective. We’re going back over everything we’ve learned, but this time we’re pretending to be a computer, reading the programs and trying to interpret them. Here’s what we’ve talked about so far:

Modules

When we write our computer programs in the web browser, we type everything into a text box and choose Run. The whole thing we type into our text box is called a module. So far, you can think of module as a word that means the entire program. (We talked a little bit about how programs can have more than one module, too. In fact, most programs in the world do! But it will be a while before we’ll really need to separate our programs into more than one module.)

Modules have two kinds of things in them that we’ve seen so far:

Imports . These always have to be at the beginning of the module, and they say what other modules (normally from libraries) we’re using. For example, we always start our programs by importing Graphics.Gloss, because that gives us all the Gloss stuff, like circles and colors and so on. We normally only import one library, but if you needed to, you could import more than thing.

. These always have to be at the beginning of the module, and they say what other modules (normally from libraries) we’re using. For example, we always start our programs by importing Graphics.Gloss, because that gives us all the Gloss stuff, like circles and colors and so on. We normally only import one library, but if you needed to, you could import more than thing. Definitions. A definition tells the computer what a word (called a variable) means. For example, if you look at the star program earlier, there are three definitions: for the words “picture”, “stars”, and “star”.

An import always starts with the special word “import”. A definition for a variable always has the name of the variable you’re defining, an equal sign, and the thing you’re defining it to mean. Sometimes in the past, we’ve seen people try to add other stuff to a module that are not imports or definitions. For example, maybe you’ve tried to write something like this:

import Graphics.Gloss

circle 80

If you’ve tried that, you know it doesn’t work! You can’t throw in a description of the circle just anywhere in your program. The error you’d get for that would say “Naked expression at top level”. When you see that, it means you forgot to say what variable you are defining!

How To Be A Compiler

Here’s what the compiler does: it reads your program, and remembers what words you’ve defined. Then it know a specific word it wants to look up the meaning of. For us, that specific word is “picture”. So it consults your program, and looks up the meaning of “picture”. Then, if there are any words that occur in there that the compiler doesn’t know, it tries to look those up, too. As long as there are words it doesn’t know, it keeps looking them up! Basically, when you write a computer program, you’re giving the compiler a dictionary to look up words in.

With that in mind, think about the next program.

import Graphics.Gloss picture = color myFavoriteColor (circle 100) myFavoriteColor = blue stars = pictures [ translate ( 100) ( 100) (color blue star), translate (-100) (-100) (color yellow star), translate ( 0) ( 0) (color red star) ] star = polygon [ ( 0, 50), ( 10, 20), ( 40, 20), ( 20, 0), ( 30, -30), ( 0, -10), (-30, -30), (-20, 0), (-40, 20), (-10, 20), ( 0, 50) ]

If you are a compiler and see this program, what do you do? Here’s what:

You see the import, and make a note that this program uses the Gloss library. You can then go see what’s in the Gloss library, and you’ll see that there are definitions for things like “circle” and “rectangleSolid” and “polygon” and “green”. You now know what these words mean.

You then see the definitions in this module. There are three of them: “picture”, “stars”, and “star”.

Since your goal in life is to go find out what “picture” means and draw it, you read the definition, and try to understand it.

Oops, you don’t know what “myFavoriteColor” means! Not a problem; you go look that up, and find out that it means blue.

Now you know everything you need about what “picture” means, and you’re done. You go and draw a blue circle.

You might wonder, what about “stars” and “star”? Well, you know what they mean… but they never came up. Just because a word is in the dictionary doesn’t mean you necessarily need it. Remember, the compiler only uses the parts of your program that it needs to draw the thing you’ve called “picture”. If you want to see a shape, you need to make it part of the definition of picture (or of some other word that happens in picture, and so on).

Expressions (and we don’t mean smiles!)

We can talk a little bit more about the things that come after the equal signs in definitions. These are called expressions, and there are several forms of them we’ve used. You have seen all of these before, but it will help to review them.

Variables . A variable name (something that you’ve defined, or something that comes from a library) can be an expression. To find out what it means, you’d look up the definition. Examples of this are picture or green.

. A variable name (something that you’ve defined, or something that comes from a library) can be an expression. To find out what it means, you’d look up the definition. Examples of this are picture or green. Functions (with arguments). Another kind of expression we use a lot is a function, along with its arguments (also sometimes called parameters). Examples of this are circle 100, or translate 50 50 star. Remember that each function expects a certain number of parameters, and you have to give it that many!

Another kind of expression we use a lot is a function, along with its arguments (also sometimes called parameters). Examples of this are circle 100, or translate 50 50 star. Remember that each function expects a certain number of parameters, and you have to give it that many! Lists . A list is a bunch of things in square brackets, separated by commas. We’ve seen them in two different places now: the parameter to pictures is a list of other pictures. The parameter to line or polygon is a list of points.

. A list is a bunch of things in square brackets, separated by commas. We’ve seen them in two different places now: the parameter to pictures is a list of other pictures. The parameter to line or polygon is a list of points. Points. A point is a pair of coordinates in parentheses, with a comma between them. You need them in line and polygon, to go in the list of points you give it.

A point is a pair of coordinates in parentheses, with a comma between them. You need them in line and polygon, to go in the list of points you give it. Numbers . A number is written as just itself, like 5 or 1.75.

. A number is written as just itself, like 5 or 1.75. Strings. Remember with text, where we put things in quotes after it? That’s a form of expression too: a string.

You might have noticed that not all the forms of expressions give you pictures! Some of them give you numbers, or points, or lists. It’s up to you to make sure that you’re putting the right type of expression in the right places. If you try to define picture to be the number 7, for example, it won’t work! That’s because 7 isn’t a picture… it’s just a number.

Now, here’s where things get interesting: Some of those kinds of expressions have smaller parts… and those smaller parts are expressions too! So we build up expressions out of other, smaller expressions.

How about an example? Let’s look at Ms. Sue’s stars program from earlier. Here it is again, so you don’t have to scroll so far.

import Graphics.Gloss picture = stars stars = pictures [ translate ( 100) ( 100) (color blue star), translate (-100) (-100) (color yellow star), translate ( 0) ( 0) (color red star) ] star = polygon [ ( 0, 50), ( 10, 20), ( 40, 20), ( 20, 0), ( 30, -30), ( 0, -10), (-30, -30), (-20, 0), (-40, 20), (-10, 20), ( 0, 50) ]

There are three definitions: picture, stars, and star.

The picture definition is easy. We say that picture means the expression with just one thing in it: the variable stars. So a picture is the same thing as a stars. You can define synonyms like this all over the place! Marcello noticed that you could write:

move = translate

And then you don’t have to remember what translate means any more. (I think you should remember what translate means, though. Defining a new word for it might help you in the short term to write your program, but it won’t help at all when you need to read someone else’s program!)

Let’s look at star, which is a little bit longer. The expression used for star is a function with arguments: the function is polygon, and there is one argument. Remember, that argument is an expression of its own! In particular, it’s a list, which means it’s a bunch of things separated by commas, surrounded by square brackets. We can go deeper, though: each of the things in the list is yet another smaller expression: in this case, a point. And finally, each of the coordinates in a point is yet another expression, which is a number. So we have expressions within expressions within expressions within expressions! That’s normally how things go: you do a lot of building up expressions in computer programming.

I’ve been saving the most complicated one for last. Let’s take a look at stars. This time, I’ll describe the expression using a bulleted list, and I think you’ll see why.

At the top level, stars is defined to mean a function with arguments…

The function is pictures, which is a variable. So it has no smaller pieces.



The argument is a list — a bunch of things in square brackets, separated by commas…



The first thing in the list is a function with arguments…





The function is translate. That’s just a variable; it has no smaller parts.







The first argument is 100. It’s a number, and has no smaller parts.







The second argument is also 100, and has no smaller parts.







The third argument (which means the picture to draw) is another function with arguments.







The function is color, a variable.









The first argument is blue, which is a variable.









The second argument is star, which is also a variable.





The second thing in the list is a function with arguments…





The function is translate, a variable.







The first argument is -100, a number.







The second argument is -100, a number.







The third argument is another function with arguments.







The function is color, a variable.









The first argument is yellow, a variable.









The second argument is star, a variable.





The third thing in the list is yet another function with arguments.





The function is translate, a variable.







The first argument is 0, a number.







The second argument is 0, a number.







The third argument is another function with arguments.







The function is color, a variable.









The first argument is red, a variable.









The second argument is star, a variable.

That was long! But can you look over it, and see how we can break down the expression into pieces, and each of their pieces is another expression?

Understanding Programs

The last thing we did this week, and also your homework, was to try to predict the results of some programs. Here’s how this works.

You’ll need some graph paper — you know, the kind with little squares all over it. Draw a square on your graph paper… maybe make it 10 boxes to a side. Draw a dot right exactly in the middle of your square. This is the point (0,0).

If you made your square 10 boxes to a side, then each box is a distance of 50. See if you can find some points in your square.

Find the point (250, 250).

(You should have come up with the top right corner of the box.)

Find the point (0, -250).

(You should come up with the point in the middle of the bottom edge.)

Now your goal will be to read some programs, and try to draw what they would draw. You can check your answers using the programming environment. Be careful, though. If you submit one of these programs, your computer will forget the program you’ve been working on, so be sure to save a copy of that somewhere first!

Exercise 1: Draw the following.

import Graphics.Gloss picture = rotate 45 (rectangleWire 150 150)

Exercise 2: Draw the following.

import Graphics.Gloss picture = rotate 135 (pictures [ circle 50, rectangleWire 10 100 ])

Exercise 3: Draw the following.

import Graphics.Gloss picture = translate 50 0 (rotate 45 triangle) triangle = line [ (0,0), (100,200), (-100,200), (0,0) ]

Exercise 4: Draw the following.

import Graphics.Gloss picture = rotate 90 (translate 100 0 (circle 100))

After you’ve tried those, try making up some expressions of your own, and predict what they are going to do. We’re spending some time on this, because before we can move on to animations, it’s important to see what your programs mean!

That’s all until next week.