There are plenty of efforts around to teach coding in schools. Most of them focus on standard imperative programming languages: for example, Python, or JavaScript, or even Java (which is a horrible choice, but is entrenched due to its role in the Advanced Placement curriculum and exams). Most of these efforts don’t think much about functional programming.

Regular readers of this blog are probably familiar with functional programming, but for those who aren’t, you should understand that it’s really a rather different paradigm from most typical programming. It’s not just another syntax, with a few different features. Instead, it’s a whole new way of breaking down problems and expressing solutions. Basic ideas taught in the first few weeks of traditional computer programming courses – for example, loops – just don’t exist at all. And other really central ideas, like functions and variables, have a completely different meaning.

I’m not quite alone in teaching functional programming, though. Matthias Felleisen and Shriram Krishnamurthi started sizable effort to teach Scheme at the K12 level in the 1990s, and Emmanuel Schanzer created a Scheme/Racket based curriculum called Bootstrap, which is heavily based on functional programming. I’ve made the same choice, and for much the same reason.

In the end, while functional programming is very different from the mainstream of computer programming, it is very similar to something else: mathematics. Functions and variables in the functional programming world may mean something different from the same words in Python or JavaScript; but they mean the **same** thing as functions and variables in mathematics.

In fact, I never set out to teach “coding” at all! My goal is to teach mathematics more effectively. But mathematics education suffers from the weakness that students who make a mistake often don’t find out about it until days later! By them time, whatever confusion of ideas led to the error has long been forgotten. CodeWorld began as my attempt to get students to directly manipulate things like functions, expressions, and variables, and get immediate feedback about whether the result makes sense, and whether it does what they intended. For that purpose, a functional programming language is perfect for the job!

Even after the switch to functional programming, I still surprise a lot of people by telling them I teach middle school students in Haskell! Let’s face it: Haskell has a bit of a reputation as a mind-bending and difficult language to learn, and it sometimes even deserves the reputation. This is, after all, the programming language community with more Ph.D. students per capita than any other, and where people hold regular conversations about applying the Yoneda lemma to help solve their coding challenges!

But it doesn’t have to be! Haskell also has some advantages over almost anything else, for someone looking to work with tangible algebra and mathematical notation.

First of all, the language semantics really are comparable to mathematics. Haskell is often called *purely *functional, meaning that it doesn’t just enable the use of functional programming ideas, but in fact embodies them! By contrast, most other widely used functional languages are i*mpure*. In an *impure* functional language, a function is *actually* the same complicated notion of a procedure or recipe that it is in an imperative language, but it is conventional (and the language offers powerful features to help with this) to stick to a subset that’s consistent with mathematics, most of the time. That’s often a fine trade-off in a software engineering world, where the additional complexity is sometimes needed; but in education, when I tell a student that a function *is really just a set of ordered pairs*, I don’t want to have to later qualify this statement with “… except for this magical function here, which produces a random number.”

Even more importantly, basic syntax looks almost exactly like mathematics (or at least, it can). Bootstrap, for example, gets the semantics right, but looking through sample student workbooks, there’s quite a bit of “here’s how you write this in math; now write it in Racket.” By contrast, when teaching with CodeWorld, we’ve been able to effectively explain the programming language as a set of conventions for typing math **directly** for the computer. There are obviously still some differences – both at the surface level, like using * for multiplication and ^ for exponents, and at a deeper level, like distinguishing between variables and constructors on the left-hand side of equations. But in practice, this has been easily understood by students as limitations and tweaks in which math notation CodeWorld understands. It feels like a dialect, not a new language.

(It’s worth pointing out that Racket also includes a purely functional language subset that’s used by Bootstrap, though the syntax is different. Shriram Krishnamurthi has mentioned Pyret, as well, which among other nice properties closes some of the ground between Scheme and mathematics notation, at least for expressions. You still can’t just write “f(x) = x + 5” to define a function, though.)

So what about the mind-bending parts of Haskell? It turns out most of them are optional! It took some effort, but as I’ll mention later, I have removed things like type classes (including the dreaded monads) and many unnecessary uses of higher-order functions. What’s left is a thin wrapper around notation that students are already learning in Algebra anyway.

Of course, a programming language by itself isn’t a complete tool. You also need libraries! The next big decision was to base CodeWorld on the programming model of Ben Lippmeier’s Gloss library.

Gloss is an interesting choice on its own. The programming model is very simple. Everything is a pretty comprehensible mathematical thing. It’s probably too simple for sizable projects, and you could make the case that teaching it is letting down students who want to be able to scale their programming skills up to larger projects. But again, it has two advantages that I believe outweigh this concern.

First, it’s *tangible*. Outside of Gloss, much of the current thinking around building interactive applications in functional programming environments centers around FRP (Functional Reative Programming). FRP defines a few abstract concepts (“events” and “behaviors”), and then hides when they look like or how they work. Of course, strong abstraction is a foundation of software engineering. But it’s not a foundation of learning, or of mathematics! Indeed, Elm also recently (and probably with even less justification, given its less educational audience) dropped FRP in favor of tangible functions, as well. The advantages of concrete and tangible types that students can get their heads around are hard to overstate.

Second, again, this choice better supports building an understanding of mathematical modeling. In addition to it being easier for a middle school student to understand a value of type Number -> Picture, than the more abstract Behavior Picture from FRP (or the even more obtuse non-terminating while-loop of the imperative world), it also gives them experience with understanding how real phenomena are modeled using simple ideas from mathematics. Later programs are built using initial values and step functions, along explicitly bundled state. This gently starts to introduce general patterns of thinking about change in ways that will come up again far down the road: in the study of linear algebra, calculus, differential equations, and dynamical systems!

Of course, there’s a cost here. I wouldn’t point someone to Gloss for a real-world project. Even something as simple as a single GUI component can be complicated and fragmented, since students have to separately connect the state, initial value, behavior over time, and event handling. But the cost in encapsulation is most keenly felt in larger projects by more experienced programmers who can find this sort of plumbing work tedious. Typical introductory programming students still have a lot to learn from connecting these pieces and understanding how to make them work together.

Once I had Haskell and Gloss in place, the next big choice made by CodeWorld was to replace the Haskell prelude with a customized version. GHC, the most popular Haskell compiler, provides a lot of power to customize the language by making changes to libraries. This extends even to the meaning of literal text and numbers in the source code!

One reason for replacing the Prelude was to keep the complexity of a first working program as low as possible. For students who are just starting out, every word or piece of punctuation is an obstacle. Haskell has always done better on this front than Java, which requires defining a class, and a member function with a variety of options. But adding import statements definitely doesn’t fit the vision articulated above of the programming language as a thin wrapper around mathematical notation. So the modified Prelude puts all of the built-in CodeWorld functions in scope automatically, without the need to import additional modules. As a result, a minimal CodeWorld program is one line long.

A second reason for replacing the Prelude was to remove a lot of the programming jargon and historical accidents in Haskell. Some of this is so entrenched that experienced programmers don’t even notice it any more. For example, even the word “string” to denote a bit of text is a holdout from how computer programmers thought of their work in the mid 20th century. (CodeWorld calls the analogous type Text, instead, and also keeps it separate from lists.) Haskell itself has introduced its own jargon, which is confusing to students as well.

But the most important consequence of replacing the Prelude is that advanced language constructs, like type classes and monads, can be hidden. These features haven’t actually been removed from CodeWorld, but they are not used in the standard library, so that students who don’t intend to use them will not see them at all. This made more changes necessary, such as collapsing Haskell’s numeric type class hierarchy into a single type, called Number. Perhaps the most interesting adaptation was the implementation of the (==) operator for equality comparison, without a type class constraint. This was done by Luite, by inspecting the runtime representation of the values in the GHCJS runtime (see below).

Sometimes, it seems that the dogma of the functional programming language community (and Haskellers in particular) is that programmers are corrupted by imperative languages, and that a programmer learning a functional language for their first experience would have a much easier time. I haven’t found that to be 100% true. Perhaps it’s because even students with no prior programming experience have still been told, for example, to think of a program as a list of instructions. Or perhaps it’s something more intrinsic in the human brain. I don’t know for sure.

But what I do know for sure is that even with no previous experience, middle school students will gravitate toward imperative semantics unless they are carefully held back! Because of this, another choice made by CodeWorld, and one of the main differences from Gloss, is that it makes some changes to intentionally trip up students who try to think of their CodeWorld expressions as an imperative sequence of instructions.

One example of such a change: in Gloss, a list of pictures is overlaid from back to front. In CodeWorld, though, the order is reversed. Combining pictures, whether via the pictures function, or the & operator, is done from front to back. The reason is that as I observed students in my classes, I realized that many of them had devised a subtly wrong understanding of the language semantics: namely, that circle(1) was not a circle, but instead a command to **draw** a circle, and that the & operator simply meant to do one thing, and then the next, and the pictures ended up overlaying each other because of the painter’s algorithm. Because of this misunderstanding, they struggled to apply or understand other operations, like translation or rotation, in a natural way. After swapping the order of parameters, students who form such a hypothesis will immediately have it proven wrong. (The analogous mistake now would be to assume that & means to do the second thing first, and no student I’m aware of has made that error.)

A similar situation exists with colors. In Gloss, the color function changes the color only of parts of a picture that don’t already have a color! This means that the semantic model of the Picture type in Gloss is quite complex indeed. Instead of just being a visual shape, a Gloss Picture is a shape where some parts have fixed color, but others have unspecified color, and the color function operates on that value by fixing any unspecified bits to the given color. Indeed, the **most** sensible way to understand these values is in terms of the implementation: that the color function sets a current color in the graphics context, which is used for that subtree, but only if it’s not changed first. This is a leaky implementation! It is fixed by CodeWorld, where applying a color to a picture overrides any existing coloring.

Another change that helped a lot with this was to carefully remove the use of verbs for function names in the CodeWorld standard library. I observed verbs misleading students many times. Sometimes, they expected that use of a function would permanently change the value of its parameter. Other times, they even expected a function like rotate to turn a picture into an animation that keeps moving! The key idea they are missing is that functions are not actions, but rather just relations between values. Such relations are better (even if it’s sometimes awkward) described somewhere on a scale between nouns and adjectives, rather than verbs. The way the code reads after this change once again acts as a roadblock to students who try to build on an incorrect understanding.

Beyond the programming language and libraries, another important choice in CodeWorld was to strongly adopt the web as a medium. The first version of the platform in 2010 was a relatively early adopter of web-based programming tools! However, the execution model (using SafeHaskell to run student code in a trusted way on the server and stream frames to the client) was definitely doomed from the start. It was a hack, which worked for one class, but was hardly scalable.

Things got better with the advent of Haskell-to-JavaScript compilers. I built a first prototype of this in 2012 using Fay, but ultimately settled on GHCJS, which is just an amazing project. Now students get very capable code implementing complete games and other applications, all running locally in their browsers with very reasonable performance.

This decision was important for a few reasons. The first is compatibility and universal access. Schools have whatever devices they have access to: Chromebooks, bring-your-own-device plans, etc. Students themselves are constantly switching devices, or leaving theirs at home. Depending on a locally installed application – or saving student projects on a local disk – for a class at the middle school level would be a disaster. Because CodeWorld is all web-based, they can work from any system they wish, and have full access to all of their saved projects.

The second reason a web-based environment was important is that sharing is a huge part of student motivation. Because the CodeWorld server remembers all compiled code by its MD5 hash, students can send projects to each other simply by copying and pasting an appropriate URL into an email, chat message, or text message. It is difficult to express how helpful this has been.

Despite the advantages of the web, though, I am hoping to soon have export of student projects to mobile applications, as well. The development environment will remain web-based, but created applications can be installed as apps. It’s likely that someone will be working on this feature over the summer.

Another big decision made by CodeWorld, and hinted at already, was to often sacrifice traditional computer programming education for better mathematics. This has been done with a hodge-podge of small changes, such as:

- De-emphasizing programming concepts like abstraction, maps and folds, and higher-order functions, in favor of approaches like list comprehensions that look more like mathematics.
- Uncurrying all functions in the standard library. This is easily the most controversial decision I’ve made for the Haskell community, but it’s really just a special case of de-emphasizing higher order functions. After uncurrying, functions can always be written in standard mathematical notation, such as f(x) or f(x, y).
- The coordinate plane uses a mathematical orientation. Gloss’s coordinate plane looks like computer screen coordinates, with (0, 0) in the top left. CodeWorld’s plane puts (0, 0) at the center, and it orients the positive y axis to point up. These just match conventions.
- CodeWorld also rescales the coordinates so that the plane extends from -10 to +10 in both dimensions, rather than counting in pixels. This turns out to have been an amazing choice! It simultaneously allows students to do low-precision placement of shapes on the plane without multi-digit artithmetic, and introduces decimals for added precision. In the end, this combination better supports middle school mathematics than the alternative.

Another change here was originally an accident. CodeWorld, from the beginning, did not implement using any kind of image file in a program. Originally, this was because I hadn’t bothered to implement a UI for uploading assets to use in the web-based programs! But after teaching with it, I don’t regret it at all. I’ve had other teachers tell me the same thing. By giving students only geometric primitives, not images copied and pasted from the web, as the tools for their projects, they are more creative and work with a lot more mathematics in the process.

The final big decision on my list doesn’t pertain to the web site or tools at all, but is about the organization of classes. There are a lot of efforts out there to encourage students to learn to code. Hour of Code encourages teachers to devote an hour to programming activities and games. Many organizations are running day-long activities in Processing or Scratch or Greenfoot. Bootstrap started with once-a-week after school programs using Racket, and has scaled up from there. I’ve volunteered as a mentor and team lead for weekend hackathons by organizations like Black Girls Code.

These are great! I wouldn’t discourage anyone from jumping in and doing what they can. But in many cases, they seem to miss the opportunity for student creativity. There’s a tendency for a lot of organizations to create very guided activities, or shy away from anything that might get a student away off the beaten path. Early versions of the Bootstrap curriculum, for example, encouraged kids to build games, but designed a game from start to finish (in terms of generic words like the “player”, “target”, and “danger”), and give students limited creative choices in the process. (Bootstrap has since expanded into a more open-ended Bootstrap 2 curriculum, as well.) Hour of Code consists almost entirely of scripted activities that feel more like playing a game than building one, which makes sense because they are intended to be completed in an hour. The BGC hackathon mentioned above was limited to use of a drag-and-drop GUI design tools, and devoted more time to having students sit in presentations about startup business models and UX design than letting them create something impressive of their own.

So one way that CodeWorld has been different from many of these activities is that I’ve tried to plan from the very beginning of the course for students to decide on, design, and implement their own ideas from the ground up. Sometimes that means taking longer, and taking smaller steps. From the very beginning, projects in the class aren’t plugging bits into a designed program, but rather creating things of their own choosing, at the level students are capable of doing creatively from scratch at that point. It means that I don’t even start talking about games until halfway through the class. But I think it’s important to let students dig in at each step and express themselves by creating something that’s deeply and uniquely theirs. Along the way, they spend a lot more time tinkering and trying out things; even trying out different possible overall organizations of their programs!

I think CodeWorld has been very successful at this. When students in CodeWorld create their own games, they really create their **own** games. They work differently, and have different designs.

Here are a few examples from various classes, all written by students between 12 and 14 years old:

- Gnome Maze Use WASD keys to help a gnome navigate the maze and find the gold.
- Donkey Pong One player uses W and S, the other uses the up and down cursor keys. Hit the ball back and forth.
- Dot Grab One player uses WASD, and the other uses the arrow keys. Race to eat the most dots.
- Yo Grandma! Save an old lady in a wheelchair from various hazards by dragging attachments onto her wheelchair.
- Jacob the Fish Help Jacob dodge sushi and eat minnows, and avoid becoming a snack for an even larger fish
- Knight-Wizard-Archer A twist on rock/paper/scissors, with fantasy characters
- Popcorn Cat Drop the cat to eat the popcorn, but dodge dogs

]]>

Originally, I started this project using Haskell and the excellent gloss package, by Ben Lippmeier. CodeWorld has been moving slowly further and further away from the rest of the Haskell community. This has happened in a sequence of steps:

- Way back in 2011, I started “CodeWorld”, but at the time, I called it Haskell for Kids. At the time, I understood that the reasons I’d chosen Haskell as a language were not about cool stuff like type classes (which I love) and monads and categories and other commonplace uses of solid abstractions (which fascinate me). Instead, I chose Haskell for the simple reason that it looked like math. The rest of Haskell came with the territory. I built the first CodeWorld web site in a weekend, and I had to settle on a language and accept all that came with it.
- From the beginning, I made some changes for pedagogical reasons. For example, gloss defines rotation to be clockwise. I insisted on rotation working in the counter-clockwise direction, because that’s the convention universally used in math. Later, I resized the canvas to 20×20, so that typical programs would need to use fractions and decimals, which is a middle school math education goal. I made thes changes, even though they broke compatibility with a widely used package. Sorry for anyone that’s struggled with this.
- I rebranded “Haskell for Kids” as CodeWorld, and stopped explicitly depending on gloss in favor of just reproducing its general approach in a new Prelude. This was a deliberate attempt to get away from focusing on the Haskell language and libraries, and also to the accompanying import statements and such. This hid the ways that Haskell was a general purpose language with uses outside this toy environment. That is unfortunate.
- I rewrote the Haskell Prelude, to remove type classes. Along the way, I collapsed the whole numeric type class hierarchy into a single type, and even got Luite (the author of GHCJS) to help me with some deep black magic to implement equality on arbitrary Haskell types without type classes. This threw away much of the beauty of Haskell… in favor of dramatically improved error messages, and fewer things you need to know to get started. It was a real loss.
- Finally, I commited the unforgivable sin. I dropped curried functions, in favor of defining functions of multiple parameters using tuples. This finally makes CodeWorld feel like a completely different language from Haskell. That really sucks, and I know some people are frustrated.

First, I want to point out some things that are *not* the reason for any of this:

- I did
*not*do this because I think there’s something wrong with Haskell. I love type classes. I love currying, and especially love how it’s not just a convenient trick, but sometimes introduces whole new perspectives by viewing tedious functions of multiple parameters as simple, clean, and elegant higher-order functions. - I also did
*not*do this because I think anyone is incapable of learning full-fledged Haskell. In fact, I taught full-fledged Haskell to middle schoolers for a year. I know they can do it.

So why did I do it? Two reasons:

- Teaching mathematics has always been more important to me than teaching Haskell. While Haskell is an awesome programming language, mathematics is just an awesome perspective on life. For every student who benefits from learning an inspiring programming language, many students will benefit from learning that humanity has a method called mathematics for thinking about fundamental truths in a systematic, logical way that can capture things precisely. So any time I have to choose between pushing students further toward their math education or away from it, I’ll choose toward it.
- Details matter. Even though I know kids are capable of a lot, they are capable of a lot more without artificial obstacles in their way. I learned this the hard way teaching this class the first time. The smallest little things, with absolutely no great significance as a language, matter a lot. Having to put parentheses around negative numbers obscures students from reaching leaps of understanding. Confusing error messages mean the difference between a student who spends a weekend learning, and one who gives up on Friday afternoon and doesn’t think about it until the next school day. Different surface syntax means that a lot of kids never fully make the connection that functions here are the same thing as functions there.

In the end, I do think these were the right decisions… despite the frustration they can cause for Haskell programmers who know there’s a better way.

A couple weekends ago, though, I worked on something to hopefully restore some of this loss for Haskellers. You see, all the changes I’ve made, in the end, come from replacing the Prelude module with my own alternative. Specifically:

- I deliberately replaced functions from the Prelude with my modified versions.
- Because I provided an alternative Prelude, I had to hide the
*base*package, which made it impossible to import things like Control.Monad. This was*not*a deliberate decision. It just happened.

So I fixed this. I added to the *codeworld-base* package re-exports of all of the modules from *base*. I renamed *Prelude* to HaskellPrelude in the process, so that it doesn’t conflict with my own Prelude. And finally, I added a new module, CodeWorld, that exports all the really *new* stuff from CodeWorld like pictures, colors, and the interpreters for pictures, animations, simulations, etc. The result is that you can now start your programs with the following:

import Prelude()

import HaskellPrelude

import CodeWorld -- If you still want to do pictures, etc.

main = putStrLn "Hello, World"

At this point, you can write any Haskell you like! You aren’t even constrained to pure code, or safe code. (The exception: TemplateHaskell is still rejected, since the compiler runs on the server, so TH code would execute code on the server.)

In fact, it’s even better! You’re free to use GHCJS JavaScript foreign imports, to interact with the browser environment! See a brief example here. Now you’re out of the sandbox, and are free to play around however you like.

Right now, the CodeWorld module still uses uncurried functions and other CodeWorld conventions like Number for numbers, etc. There’s no reason for this, and it’s something that I should probably change. Anyone want to send a pull request?

]]>

Here are some things I intend to change in the near future. A more complete list is on the project issue tracker, but this is a summary with more details and reasoning about some of the changes.

An important goal of this project is to align with a standards-based U.S. middle school math education, as much as possible. To be clear, I still refuse to add complexity or turn the project into a patchwork of specific lessons that promote a specific narrow path of learning. First and foremost, this should be an environment for tinkering and encountering ideas in self-motivated way. But given alternative designs that could each be valid on their own, I’ll choose the one that pushes students toward the math standards.

It’s sometimes a tough line to draw. But I’ve become convinced that there are a few places where I can do better. Two of those are going to be major breaking changes, coming soon.

Haskell’s convention of currying functions is the wrong default for CodeWorld. Practically all of mathematics, especially at introductory level, is carried out with the notation *f*(*x*,*y*) = … . The interpretation is that a function of two parameters is a function whose domain is a product – a set of ordered pairs. The Haskell language makes a different choice. Applying a function to two parameters is more like *f*(*x*)(*y*) (the parentheses are optional in Haskell itself), and the interpretation is that *f*(*x*) denotes a partially applied *function* that’s still waiting for its second parameter.

If the goal were to teach about higher-order functions, there would be lots of great arguments for the latter. If the goal were convenience, you could argue for the latter pretty persuasively, as well. I think Haskell’s use of currying is great. But when the goal is to let students encounter and tinker with things they will see in school math, the right choice is to adopt the convention of mathematics.

Luckily, the assumption of curried multi-parameter functions isn’t baked into Haskell too deeply. By changing the standard library, it’s quite possible to write *f*(*x*,*y*) just as well. The parentheses on *f*(*x*) become optional, but this is actually true of mathematics in general (for example, operators in linear algebra are often written without parentheses, as are trig functions). I will adopt the convention of using parentheses around even single function parameters.

The only big source of awkwardness comes with binary operators. So long as we choose not to teach the notations `foo` (for turning a function into an operator) or (+) (for turning an operator into a function), this doesn’t come up much. Notably, sections still work fine, since they take only one argument.

A couple convenient side effects of this choice are nice, too:

- Students who routinely write parentheses around function arguments less often find themselves forced to surround negative numbers in parentheses for weird parsing reasons. As trivial as it might seem, this was a very real and significant learning obstacle the last time I taught the class, and I’ll be happy to see it go.
- Getting expression structure wrong sometimes gives much better error messages this way. It’s harder to accidentally mix up precedence between an operator and function application; and passing too few arguments to a function gives a clear error rather than inferring a function type and breaking in an obscure way elsewhere.

The second big change is to resize the canvas from 500×500 to 20×20.

The justification for a 500×500 canvas was generally about confusing pixels – little dots on the screen – with the general idea of a coordinate system. It’s convenient to blur the distinction at first, but it has in the past become a barrier to understanding the full nature of the coordinate plane with real (or even rational) coordinates. Many students were confused when later faced with fractional coordinates. At the same time, developing a full understanding of the rational number system is a big topic in 6th, 7th, and 8th grade mathematics, so it would be great to ask students to do more tinkering with these numbers.

By replacing this with a 20×20 grid (x and y coordinates ranging from -10 to 10), several goals are accomplished:

- Students early in the class are working with numbers in a range they can comprehend better.
- Students routinely work in fractions or decimals to fine tune their projects.
- The abstract coordinate plane, including fractional coordinates, becomes more familiar.

This is a big win overall.

On the less controversial side, I’m planning a number of changes to make the site more usable:

- Pervasive auto-complete, based on a pre-populated list of the standard library symbols as well as parsing the student code for declared names.
- More complete documentation, tutorials, and better examples. I admit that the current site is grossly lacking in documentation. I don’t envy anyone who tries to figure it out on their own!
- Better tools for playing around with results. At the very least, students will be given the chance to scroll, pan, and see coordinates of points in pictures, animations, and simulations.

I also have my wish list for things I’d love to see possible, but am not quite ready to build yet. This includes:

- Social features: sharing projects with friends, commenting on or expressing support for other projects.
- Collaborative projects with shared editing or exporting libraries for others to use.
- Better debugging tools, such as easy controls to move forward and back in time, fast-forward, pause, etc. for animations, simulations, and even games.
- Possibly grading features for teachers to grade projects and provide a scoring rubric and comments.

What else would you like to see? Let me know in the comments here, on codeworld-discuss, or by filing a feature request in the issue tracker.

]]>

- Doing their own original, creative work, instead of following instructions or reaching set answers.
- Getting instant feedback 24 hours a day, so they can tinker and learn in a self-directed way.
- Building confidence by working on their own ideas, inspiring pride and excitement.
- Experiencing how concepts from geometry, algebra, and physics can be springboards for creativity.
- Becoming creators, rather than just consumers, of technology.

That’s a lofty set of goals, but it was very successful. In the 2011-2012 school year, I taught a small class of six students, two to three hours per week. We had an awesome time. They built their own computer games throughout the year. We struggled together, worked our way through, and finished the school year with an awesome expo where the students showed off their work to local technology professionals and participated in a question-and-answer panel about their experiences. It was fascinating listening to this, because a few patterns arose:

- Students didn’t really think of what they were doing as math. This remained true, even when the skills they learned involved describing the behavior of systems using equations, functions, and variables; describing complex shapes in terms of geometry, the coordinate plane, and rotations, translations, and scaling; coming to grips with the meaning of probability and randomness; etc.
- The students who entered the year being “good at technology” weren’t necessarily the most likely to succeed. Talking to these students broke all of the stereotypical molds about computers and technology! Students took to the activity and wildly succeeded were very often girls, and had previously thought they were more the art-and-music type.

At the end of that year, I had plans to teach this program in multiple schools the following school year. Unfortunately, things then got a little sidetracked. I started a new job at Google over the summer, moved to California, and dropped the program. The web site that students had used to build their projects fell into disrepair, and stopped working. I stopped doing anything about it.

Over the last week and a half, though, that’s changed! CodeWorld is back!

The CodeWorld web site is (as always) at http://www.codeworld.info.

Any web browser will do, but you really need to use the latest version of whatever browser you choose. If you’ve been putting off upgrading Internet Explorer, it’s long past time!

You’ll also want a Google account. You can log in using your Google account, and save your programs to Google Drive. Because your programs are saved to the cloud, you can use the web site from any computer you like, even computer labs in a school, and your programs will follow where ever you go.

Using the web site is simple. Type your program on the left. Click Run to see it work on the right. You can sign in to open your existing projects and save your projects. You can also get links to share your projects with others. There are sample projects along the bottom of the screen, including Yo Grandma!, a game written by Sophia, one of my students from the original class.

Unfortunately, instructions on how to write the programs are still mostly missing. If you already know the language, a link to the generated documentation might help. Otherwise, hold on! Once the programming environment is stable, I plan to put together a comprehensive progression of exercises, tutorials, and examples.

Under the hood, I mostly recreated this from scratch, throwing away most of the original project from a few years ago. This new version of the environment has a lot of advantages: it runs your programs on your own computer, so your program runs a lot faster. It’s less restrictive. And I completely customized the language to make a lot of things simpler and easier to understand.

Changes:

- The programming language for CodeWorld is called Haskell. Haskell is an awesomely mathematical language, but parts of it are also notoriously complex. The new incarnation of CodeWorld still uses Haskell, but goes a lot further to hide the rough edges. In particular, you’ll rarely see any classes, and there’s an obvious type for most things (e.g., all text has the type Text, and all numbers have the type Number.)
- Previously, CodeWorld was based on a library called Gloss for the Haskell programming language. Gloss is great, and I saved as many ideas from it as I could. But CodeWorld is now its own library. This let me clean up some terminology, align the meaning of programs more closely with the goals of algebraic thinking and math concepts, and work with the simplified version of the language.
- The biggest change to how the web site works is that your programs now run on your own computer, instead of on the web server. This is using an awesome project called GHCJS, which converts the Haskell program into JavaScript, which is understood by web browsers.

I’ll try to keep posting here as I have learning material ready to use with this tool. Stay tuned!

]]>

For anyone new to the ideas, I should review a little about what CodeWorld is. CodeWorld is the name for the curriculum I built and taught last school year. It has the goal of teaching abstract and mathematical reasoning skills through computer programming. Throughout the course of the year, students use a web site to write descriptions of pictures, then animations, and finally video games, and run them in the web browser to immediately see the results.

I taught a pilot program last school year in a neighborhood school, and it was a huge success. I have high hopes of getting something going again in the future.

Many people have noticed that CodeWorld stopped in its tracks some time during the summer. What ended up happening was a fairly big life change for me: I’ve changed jobs (now working for Google on YouTube!), moved (to San Francisco from Colorado), and have been focused on personal changes for a while. Unfortunately, that meant I had to cancel the plans to teach CodeWorld at *three schools* in Colorado this school year. I hope, though, this is only a temporary setback! I still have high hopes for the future.

In terms of technology, CodeWorld is built on several things:

- The Haskell programming language. This is a language that’s very well suited for CodeWorld because it expresses things in a way that’s very declarative and consistent with the mental models students should bring into algebra and other abstract mathematics classes.
- The Gloss library. This library, originally developed for introductory college programming classes, is a great fit for many of the same reasons. It’s based on Haskell, and again does everything declaratively. It’s also very concise, not needing a lot of wordy boilerplate to get something quickly on the screen.
- The SafeHaskell feature of GHC. This allows the server to safely compile and run code written by students without worrying that it might delete critical files and such.

In some ways, the set of technology chosen for CodeWorld is perfect. Specifically, it let me get a web site up and running in about a week of work, right before the start of the class last school year. That saved a lot of hassle, and made the class a lot more successful. In other ways, though, each of these choices is lacking in a few ways.

- Haskell is a great choice of language, but it’s very difficult to target Haskell to run in web browsers. For this reason, CodeWorld actually runs students’ programs way over in a data center, far from their computers. This worked and was easy to do (great!), but it also means programs run very slowly, and the server gets bogged down if it’s used by too many people at once (not so good).
- Gloss is the closest thing we have to a perfect choice. Even that, though, has its limitations. Because Gloss has a number of users who want to do more advanced things (like use it to show off parallel processing APIs in Haskell), there are some technical pieces in the back end that are difficult to fit in with a web browser as well. Also, mainly due to backward compatibility, there are inconsistencies in the API (circle to draw the outline of a circle versus rectangleWire to do the same with a rectangle, for example), inconsistencies with what students will see in math classes (angles are clockwise, for example, in the official implementation), and lost opportunities to make small tweaks that will more clearly emphasize declarative thinking. We definitely want something
**like**Gloss, but there are a few details that it would help to tweak in some incompatible ways. - SafeHaskell turns out to be problematic for a variety of reasons. Aside from the performance problems from running on the server in the first place, it’s really only a small part of a solution to the problems of running untrusted code. For example, it has no protections against using excessive resources and slowing down the server until it’s unusable.

So I’ve been evaluating a new technical path. This new approach uses Chris Done’s language called Fay, which is a subset of Haskell specifically designed to run in web browsers. It has all of those advantages of Haskell that I mentioned above, but works better in a web browser. I’ve been porting the Gloss library over to Fay, but taking liberties to modify some of the inconsistent behaviors and lost opportunities as I go. SafeHaskell then becomes entirely unnecessary, as the code is no longer running on the server. It’s running in the student’s web browser instead, where JavaScript is already thoroughly sandboxed by companies that put lots of resources into the problem.

This technology migration isn’t done yet, and there’s still a lot of little syntax stuff that’s frustratingly unsupported by Fay… but I’m working on it, helping out the Fay project a little but, too, and it’ll get there!

In addition to changing technologies, I’ve been putting a lot of thought into what I want the future of the system to look like. I am looking at how to make the platform more appealing when I am not personally living right by the school and able to pop over and help with any students who are having problems.

One side of this is definitely a redesign of the web site. The site needs examples, it needs to look more finished, and it needs documentation! I’m working on a mock-up of the future web site, and while my web design skills are definitely lacking, I think I’m happy with the concept so far. You can take a look, if you want, and let me know what you think.

Another side actually was started over the summer, and that’s putting together a comprehensive teacher’s guide, including worksheets, exercises, and organization of the content. This needs to be more than just a web site; it needs to be an organized approach to presenting the ideas and guiding students through the learning process. I’m strongly considering making a somewhat involved video series to present the concepts, as well.

The third and final part of this is putting the pieces in place for a sustainable community of people working together. I don’t have any specific plans here, yet… but I’ll just say that I see positive things ahead. I’m now working with tens of thousands of brilliant people, many of whom care very much about education, in a company that encourages its employees to experiment with technology in ways that aren’t focused on just one product. I’m also within a short drive of the Khan Academy, and plenty of other groups that care a lot about math education.

Some things I’d like to try here:

- Getting together students who build things with CodeWorld to meet and share their creations.
- Helping students make the transition from developing things for “a school project” to sharing them with friends and others, and possibly even offering their creations in various app stores or markets. (Student creations in CodeWorld actually tend to be fairly similar to the casual game market for smartphones and such…)
- Creating more resources for teachers who want to incorporate this into their schools. I’d love to hold seminars and such for teachers! Please ask me to do this, once the pieces are in place!

So that’s where CodeWorld is, and where it’s hopefully going. I’m still very excited about the future of this effort, and looking forward to making some more progress here soon.

]]>

So we all watched the video, and talked about it… and then about midnight last night, I realized this would make a perfect introduction to Gloss simulations, which we’re learning about in our Haskell programming class! Fast forward about 20 minutes of hacking, and we have this short program:

import Graphics.Gloss thePattern = [5,2,5,1,2] initial g = (-1, 0.0, [], cycle thePattern) step dt (hand, time, balls, pattern) = (newhand, newtime, newballs, newpattern) where (throw, newtime) = properFraction (time + dt) newhand = if throw == 1 then -hand else hand thrown = if throw == 1 then [ (hand, newtime, head pattern) ] else [] newpattern = if throw == 1 then tail pattern else pattern newballs = [ (bhand, btime + dt, height) | (bhand, btime, height) <- balls, btime + dt < fromIntegral height ] ++ thrown draw (hand, time, balls, pattern) = pictures [ juggler, pictures [ ball b | b <- balls ] ] ball (bhand, btime, height) = translate (50*x) (50*y) (circleSolid 10) where t = 1 - 2 * (btime / fromIntegral height) x = if even height then bhand else bhand * t y = if height < 3 then 0 else fromIntegral (height - 1) * (1 - t^2) juggler = pictures [ line [(-50, 0), (0, 25), (50, 0)], line [(-30, -100), (0, -50), (30, -100)], line [( 0, 25), (0, -50)], translate 0 50 (circle 25) ]

Feel free to check it out.

This isn’t the best code in the world, because I deliberately write it to avoid as many ideas as I can that we haven’t talked about in my Haskell class. Among those, for example, are any kind of user-defined data types, or any structured data other than tuples and lists! I’ve also used list comprehensions when maps and filters might be clearer, for the same reason: we’ve *done* list comprehensions in class! Those are coming soon, but for the time being, it’s not too hard to see what’s going on here. A couple notes about the world type:

- The state of world comprises four pieces of information: which hand will throw next, how much time has passed since the last throw, what balls are in the air, and what pattern is coming up next. Since we don’t have user-defined types and it makes the math easy, I’ve described hands as -1 for left, and +1 for right.
- The balls in the air form a list, but each element of that list is another tuple, containing the hand the ball was thrown from, how long it has been in the air, and its height.

So like all Gloss simulations, we need to specify three things:

*The initial state.*This is the left hand, no time since the last throw, no balls in the air, and the pattern sitting ahead of us. The cycle function turns a finite list into an infinite repeating one.*The step function.*This is where most of the logic sits… there are a lot of bits, but it does what you’d expect! Every second, a ball is thrown, and the hand switches sides. We update the balls to add to their time in the air, and keep only the ones that haven’t landed. When a ball is thrown, we add it. And each time we drop a number from the pattern.*The draw function.*This draws the juggler and all of the balls. The balls are drawn with some faux-physicsy thing that, frankly, is just the result of fiddling and isn’t an accurate physics simulation. I can get away with that when teaching middle schoolers! Hey, at least they follow parabolas; just not all with the same acceleration. In class I just skimmed over the math for where the ball appears, since the class right now is about the state type, and drawing is something they’ve been doing all year anyway.

Definitely a lot of fun. I encourage you to copy and paste the code above into http://dac4.designacourse.com:8000/sim and fiddle with the patterns and see what they look like!

]]>

Just to set the stage: we spent quite a few weeks on pictures, and just last week we started on animations. We learned:

- Whereas pictures were just
*variables*, animations are*functions*. - They have a single
*parameter*, which is how many seconds since the program started running. - The
*result*of the function should be a picture.

To define a function, we give the parameter a name on the left side of the equal sign, right after the function name. We can then use that name after the equal sign, just like if it were a number. Here’s an example:

animation t = rotate (60*t) (rectangleSolid 40 200)

The function is called *animation*. The parameter is called *t*. And after the equal sign, we can use *t* just like any other number. For example, we can multiply it by 60, and then rotate the picture by that many degrees.

The result of functions comes from *substitution*. So to find out what this animation will look like after 5 seconds, the computer just looks at everything after the equal sign, and replaces any *t* that it sees with a 5. So it takes the following steps:

*animation 5*— this is what the computer starts out trying to figure out.*rotate (60*5) (rectangleSolid 40 200)*— It replaces any*t*by 5 after the equal sign.*rotate 300 (rectangleSolid 40 200)*— This is just math: the computer calculated 60 times 5, and got 300.

So after 5 seconds, the computer will draw the rectangle rotated by 300 degrees. If you try this out with a few numbers, you’ll notice that the rectangle turns by more and more degrees over time, making it spin.

We played around with animations that change lots of things: by *t* in different places, you can make things spin (using *rotate*), move (using *translate*), or get bigger or smaller (using *scale*, or by using *t* as the parameter to Gloss functions like *circle*). But you might have noticed something disappointing about doing anything except rotation: after a while, the numbers get too big to see! Things move off the edge of the screen, or get so big you can’t see them any more.

Because of this, our programs so far haven’t really done anything except rotate. To do much more without everything ending up too big or too far off the screen, we’re going to have to get comfortable with a different kind of function…

Animations are functions that get a number, and turn it into a picture. But that’s not the only kind of function! We’ve actually seen quite a few kinds of functions, if you count the ones that Gloss defines for us:

*circle*is a function that turns a number into a picture (just like animations, but the number means something different)*light*is a function that turns a color into a different color.*rotate*is a function that turns a number**and**a picture into different picture (one that’s rotated).*polygon*is a function that turns a**list**of points into a picture.

In general, you can think of a function as a machine that turns things into other things:

You feed the parameters in, and you get the result out the other side. Different functions need different types and different numbers of parameters, and they give you different types of results, too. So when you want to use a function, the first things you should ask are: (1) How many parameters does it need? (2) What types of things does it want for its parameters? And, (3) What type of thing is it going to give me back when it’s done?

In the end, you want to create pictures, of course! So at first you might think that you’re only interested in functions that give you pictures back. But that would be short-sighted! Remember the functions *light* and *dark*? They are functions that expect one parameter – a color – and give you back another color, *not* a picture. But they’ve still been very useful for building your pictures, haven’t they?

The same thing is true with numbers. Even though you ultimately want to end up with a picture, it’s very useful to be familiar with some functions that work with numbers, because we *use* numbers all the time when we’re making pictures. So we’ll spend a lot of this week talking about functions that work with numbers.

When you have a function that expects a number for its only parameter, and gives you back a number as a result, we have a convenient way to draw it. It might look weird at first, but believe me, it makes things a lot easier! So here’s how to draw a function. It only works if the function is from numbers to other numbers.

We start out by drawing two lines: one horizontal, and one vertical, like this:

I’ve called the vertical line *f* and the horizontal line *t*. That’s because normally, the horizontal line will represent the amount of time the program has been running, and we’ve been calling that *t*. The *f* is just short for “function”.

Next, you want to label the tick marks on the lines: for *t*, just number them 1, 2, 3, 4, and so on. Zero is where the two lines cross, so the first tick mark after that should be 1. For the vertical line, how you label it depends on the numbers you’re working with! Notice it’s got both positive and negative numbers, too.

The next step is to draw some points. Ask yourself, if you give your function is given the number 0, what number does it give back? Now draw a point *directly* above or below the point on the horizontal line that means zero (remember, that’s the point where the lines cross). How far up or down you draw the line is decided by what the function gives you back. Now do the same thing for 1, and for 2, and so on…

Finally, once you’ve got a bunch of points, connect them with a smooth line. That line is how you draw that function.

Let’s try an example. We’re going to draw the function

f t = t/2 - 2

That means the function is called *f*, its parameter (the number you give it) is called *t*, and the number it gives you back is half of *t*, minus 2.

Let’s draw the lines like we did before, and label the points counting by one in both ways:

The next step is to figure out some values of the function, and draw them as points on the graph:

f t = t/2 - 2

f 0 = 0/2 - 2 = 0.0 - 2 = -2.0 f 1 = 1/2 - 2 = 0.5 - 2 = -1.5 f 2 = 2/2 - 2 = 1.0 - 2 = -1.0 f 3 = 3/2 - 2 = 1.5 - 2 = -0.5 f 4 = 4/2 - 2 = 2.0 - 2 = 0.0 f 5 = 5/2 - 2 = 2.5 - 2 = 0.5 f 6 = 6/2 - 2 = 3.0 - 2 = 1.0 f 7 = 7/2 - 2 = 3.5 - 2 = 1.5 f 8 = 8/2 - 2 = 4.0 - 2 = 2.0 f 9 = 9/2 - 2 = 4.5 - 2 = 2.5 f 10 = 10/2 - 2 = 5.0 - 2 = 3.0 f 11 = 11/2 - 2 = 5.5 - 2 = 3.5 f 12 = 12/2 - 2 = 6.0 - 2 = 4.0 f 13 = 13/2 - 2 = 6.5 - 2 = 4.5

Here’s the graph with the line that connects those points:

Looking at the graph, you can get a good feeling for what that function does. Imagine you’re always moving to bigger and bigger numbers of seconds since the program started (because you are!). Then this function will keep getting bigger and bigger forever. You can also see that it will keep getting bigger at the same speed. And you can see that it starts out being -2, and then after 4 seconds it’s 0, and it keeps going up from there.

So what does that mean?

- If you say
*rotate (t/2-2)*, that means start out rotated a little bit clockwise, and then turn counter-clockwise at a constant speed forever. - If you say
*translate (t/2-2) 0*, that means start out a little to the left, then move right at a constant speed forever. - and so on…

In class on Tuesday, we did this worksheet together, where we practiced drawing functions that use numbers.

You might notice at the end of the worksheet a few functions that we haven’t used yet that are useful:

*min*and*max*. These functions actually take two numbers as parameters, and they return one of the two numbers you give them. So*min*gives you the smaller of the two numbers, and*max*gives you the larger of the two numbers.*sin*. This function, which is pronounced like “sign”, is useful for making things move back and forth. It is way more interesting than just that, but we’ll save the more interesting stuff for high school trigonometry classes. All we want it for is to make things move back and forth. Keep in mind that*sin*itself only goes back and forth between -1 and 1, so you probably want to multiple the answer by something bigger!

Want to see what the sin function looks like? Here you go:

See how graphs of functions help you understand what they do?

Because the Little School is off next week for a inter-term break, it will be two weeks until my next summary! Never fear, though, I’ve got something for you to work on.

Your task is to make an animation of an amusement park ride. Try to get several kinds of movement in there: rotating in circles, moving back and forth, and anything else you can do! Those of us in my class are going to make these:

- Skyler: Roller coaster
- Grant: Bungee Jump Ride
- Marcello: Ferris Wheel
- Sophia: Tilt-a-Whirl
- Sue: Swinging Pirate Ship
- Me: Kids Jumping Rope (the example from week 7, but I might tweak it a little)

We’re planning to put them together into a gigantic amusement park picture when we’re done. If you have friends doing this at the same time, you can, too! (Do you know how? It’s just like top-down design: get everyone to send you their programs, but call them something other than *animation*, then scale them, move them to different places, and combine them using *pictures*.)

Good luck! And as always, use the comments to ask for help if you’re stuck.

]]>

This is the summary of week 7 of my Haskell class for children, aimed at ages 11 through 13 or so. You can go back and review the previous weeks to catch up.

We’ve now spent six weeks learning some of the Haskell programming language, and making various pictures, from simple stuff to some pretty complicated drawings. Now it’s time for the next big step: animations!

We’ve done all of our programming using the gloss-web web site at http://dac4.designacourse.com:8000, where you can program and look at the result in a web browser. So far, everything we’ve done has been in the “Picture” portion of the web site, which you get to by clicking the picture button:

Now we’re ready to move on to the next type of program. So to get started, click the “Animate” button instead.

This page will look very nearly the same, but don’t be fooled! The web site now expects from you a different kind of program: one that describes a picture that moves over time.

You’ll remember that the picture mode expected you write a definition for a variable called *picture*. Everything else in your program was just there to help you define what *picture* meant, and when you finished, the program would run by looking up the definition of *picture*, and drawing it. Your other definitions were useful only because they let you use those new words to define *picture* more easily.

The same thing is going on here, but there are two changes:

- Instead of
*picture*, you’re defining a word called*animation*. - Instead of being a description of a picture,
*animation*is a**function**. Like all functions, it has a parameter, which is the amount of time that’s passed.

*Warning:* I’ve said from the beginning not to use Internet Explorer for the programming web site. It’s probably worked so far if you didn’t listen to me. But now it will *not* work any more, so you’ll need to use something else: Firefox, Chrome, Safari, Opera… take your pick, but Internet Explorer won’t work.

Let’s jump in with some examples.

The first example program we’ll write is the one that is given to you by the web site:

import Graphics.Gloss

animation t = rotate (60 * t) (rectangleSolid 100 100)

Here’s how to think about what that means.Think of *t* as standing for the number of seconds it’s been since you clicked the **Run** button.

At the very beginning of your animation, it’s been 0 seconds since you pressed **Run**. So the program is saying the same thing as: *rotate (60*0) (rectangleSolid 100 100)*. Remember that *** means multiplication. Of course, 60 times 0 is 0, so this is just *rotate 0 (rectangleSolid 100 100)*. It draws a rectangle that hasn’t been rotated at all.

But then some time passes. After half of a second, now *t* is 0.5. Now the picture your program is drawing is *rotate (60*0.5) (rectangleSolid 100 100)*. What is 60 times one half? It’s 30. So now the picture is *rotate 30 (rectangleSolid 100 100)*, and it will draw a rectangle rotated by 30 degrees. This will continue, too. After a full second, *t* is 1, and 60 times 1 is 60, so the rectangle will be rotated by 60 degrees. After 2 seconds, it will be rotated by 60 times 2, or 120 degrees. As *t* gets bigger, the rectangle will be rotated more.

Okay, here’s a little quiz: how long will it take for the rectangle to turn all the way around, a full 360 degrees? That shouldn’t be too hard: you want to find the number that will give 360 when it’s multiplied by 60. That’s how many *seconds* it will take.

What about after that? Can you rotate something *more* than 360 degrees? Sure, you can… but you can’t tell that you did it! Rotating 360 degrees looks just like leaving it alone. So, for example, when it’s rotated 390 degrees, that’s the same as just rotating 30. (If you were thinking about this, you might have noticed that you actually can’t even tell if a square has been rotated 90 degrees! That’s because of the symmetry of the square. But you can’t tell if *any* shape has been rotated 360 degrees, no matter if it has symmetry or not.)

Try this example on the web site, and make sure it looks the way you expected.

Let’s make a small modification to the example earlier. We’ll make the square rotate faster:

import Graphics.Gloss

animation t = rotate (100 * t) (rectangleWire 100 100)

Just like before, *t* stands for the number of seconds since you clicked Run. At the very beginning, *t* is zero, and zero times 100 is still zero. So it starts in the same place. But now look what happens: after half a second, it’s rotated by 50 degrees. After a full second, it’s rotated by 100 degrees. It will only take about three and a half seconds to make a full turn.

Now let’s try to change the angle it starts at, so that it started standing on one point like a diamond.

import Graphics.Gloss

animation t = rotate (100 * t + 45) (rectangleWire 100 100)

Okay, what’s that when *t* is zero? It’s *rotate 45 (rectangleWire 100 100)*. So the square will start out turned on one point. It will still rotate at the same speed as before, though: 100 degress every second. Try that and see what it looks like.

Now let’s try moving something instead of rotating it.

import Graphics.Gloss

animation t = translate (50 * t) 0 (circle 25)

Take a moment and try to guess what that will look like.

To figure it out, let’s look at the picture we’ll get at different times. When the animation first starts, it’s been 0 seconds, and *t* is 0. Then this is *translate 0 0 (circle 25)*. That won’t move the circle at all, so it will still be in the middle of the box. But now when *t* is 1 (after the animation has been going for a full second), it will become *translate 50 0 (circle 25)*, so the circle will be a bit off to the right. In fact, the circle keeps moving right until it runs right off the screen (and even afterward, but then you can’t see it any more).

Try it!

Can you guess how to make the circle move faster? If you guessed that we want to multiply *t* by a higher number, you’re right!

import Graphics.Gloss

animation t = translate (100 * t) 0 (circle 25)

The circle will still start in the middle. (Why?) But now after one second, it will have moved twice as far. It’s moving faster.

We won’t do it as an example, but what if you wanted the circle to start on the left side of the screen? Hint: it works a lot like example 3!

What if you want something to get larger as time goes on? You can do that, too. Here’s an example:

import Graphics.Gloss

animation t = circle (20 * t)

Once again, *t* stands for the number of seconds since you pressed Run. At the very beginning, your picture will be *circle (20 * 0)*, which is the same thing as c*ircle 0*. A circle with a radius of 0 is too small to see, so you won’t see anything. But after half a second, it becomes *circle (20 * 0.5)*, which is *circle 10*, and you will see a circle with a radius of 10. The circle will keep getting larger: after ten seconds, it will be *circle 200*. Eventually, if you’re patient enough, it will grow too big to even show up on the screen.

Try that, and see if it does what you expected.

(You could have also written that using scale: *animation t = scale t t (circle 20)*. Do you see why those two programs should do the same thing?)

Sometimes we might want something to rotate, but around the middle of the whole picture (or part of a picture), and not just around its own middle. The trick is to move it (with *translate*), and then rotate the picture that you get as a result of that.

import Graphics.Gloss

animation t = rotate (60 * t) (translate 100 0 (circleSolid 25))

See if you can work out what that will look like at different times, and then try it out and check yourself.

You might have noticed that a lot of the things we’re doing here seem very similar to what we did with list comprehensions. You’d be right!

Both times, we had **variables**, and we got different pictures because those variables got different values. The difference is that with list comprehensions, we put all of those different pictures together at the same time. Now we’re using different pictures at different times. But the idea is the same: you use variables to represent numbers that you don’t know yet, and then you can build versions of your picture where those variables mean something different.

We’ve actually used variables like that three times:

- When we defined
**functions**(like*awesome*), the parameters got names, and you used those names in the function. - In list comprehensions, you used the funny backward arrow: <-, to pick a name and arrange for it to get lots of different values.
- Now, in animations, you’re again defining a function: a special one, where the parameter is the time.

This is something that will keep happening. Variables are very important, so you should get used to seeing expressions that have variables in them, and doing something called “substitution”. That just means answering the question “If *t* is 5, what does this work out to?”

With pictures, we worked on organizing our program by top down design: we started by saying what *picture* meant, but we sometimes used other words the computer doesn’t know yet. Then we went back in and filled in what those words meant. We just kept this up until the program was done. The nice thing about top-down design was this: you didn’t have to think about your *entire* program at once. You could just think about one piece at a time.

We’d like to keep doing top-down design with animations, too. There’s one thing we have to figure out, though, and that’s what to do with *t*. Here’s what we’ll do:

- When we’re defining a word, if its a piece of the picture that, just looking at that one piece, will have some movement, then we’ll make it a function, taking a parameter called
*t*. - When we’re using it later on, we’ll pass
*t*for that parameter.

It’s important to keep these consistent: if you define a function with a parameter, then you also have to give it that parameter when you *use* the function. If you define a variable without a parameter, then you aren’t allowed to give it a parameter when you use it.

Let’s look at an example: here’s a program to draw a clock:

import Graphics.Gloss animation t = clock t clock t = pictures [ backPlate, minuteHand t, secondHand t ] backPlate = color (dark white) (circleSolid 250) minuteHand t = rotate (-0.1 * t) (line [(0,0), (0,250)]) secondHand t = rotate (-6 * t) (line [(0,0), (0,250)])

We’ll break it down piece by piece:

- First, we defined the
*animation*function. When you’re working in animation mode, you always have to define this, and it always has the parameter*t*, that means how many seconds since it started. We say that the animation is a clock. The clock will have moving parts, so we pass along*t*. - Since we gave the time,
*t*, to*clock*earlier as a parameter, our definition of*clock*has to say it has a parameter, too. A clock consists of three parts: a back plate, a minute hand, and a second hand. The back plate does**not**move, so we don’t pass along*t*. But the minute hand and second hand do move, so we’ll be passing the time along to those. - Next we define
*backPlate*. Remember we didn’t give it a*t*parameter because it won’t be moving, so this is just a variable. - Now we define
*minuteHand*. We did give it a parameter, so now we have to say it gets a parameter. And just like in the earlier examples, we can use that parameter*t*to make it rotate. We want the minute hand to rotate 360 degrees every*hour*, and an hour is 3600 seconds. So that means we want it to move only a tenth of a degree every second. Also, we’d like it to move clockwise, so that number has to be negative. (Remember, positive rotations are counter-clockwise.) - Finally, we define
*secondHand*. It needs a parameter, too, so we give it the*t*parameter. The definition looks the same, but now we want it to rotate 360 degrees every minute (60 seconds). That works out to 6 degrees every second, and it’s still negative so that the rotation is clockwise.

Hopefully, that doesn’t look too bad! It’s just the same kind of top-down design we’ve been doing, except with some time thrown in to keep things moving. You have to ask yourself whether each part has movement in it or not, and you have to consistent about the answer.

The assignment we’re working on this week is to make a working model of the solar system. That is, put the sun in the middle, and the planets around it, and have them rotate around the sun. A few notes:

- It doesn’t need to be to scale. In fact, the planets are
*so*far apart, and*so*small compared to the distance between them, that if you try to draw everything to scale, you won’t even be able to see it! So just pick what looks good. - If you are ambitious, try to add at least one moon, and give Saturn its rings.The hint here is that moons and rings aren’t too hard, as long as you’re using top-down design. For example, you should have something called
*saturn*, and instead of making it a circle, make it a pair of circles with one of them stretched a bit.Now suppose you’re adding a moon to earth, you probably want a function called something like

*earthSystem*that represents the earth and its moon together. Since the moon is moving around the earth, it should be a**function**and have a parameter called*t*. When you’re defining*earthSystem*, you’ll probably want even more variables called*earth*and*moon*. These will probably just be colored circles. - Our class here in Colorado Springs actually all decided to make up their own solar system with different planet names. That’s fine, too. In fact, the computer doesn’t care what you name things.

Good luck! And feel free to ask in the comments for help.

If you’re bored, try this animation. It’s a preview of what’s coming in the next couple weeks.

import Graphics.Gloss animation t = pictures [ jumprope t, translate (-210) 0 stickFigure, translate ( 210) 0 stickFigure, jumper t ] jumprope t = scale 1.75 (1.1 * sin t) rope rope = line [ (x, 100 * cos (0.015 * x)) | x <- [-100, -75 .. 100 ] ] stickFigure = pictures [ line [ (-35, -100), (0, -25) ], line [ ( 35, -100), (0, -25) ], line [ ( 0, -25), (0, 50) ], line [ (-35, 0), (0, 40) ], line [ ( 35, 0), (0, 40) ], translate 0 75 (circle 25) ] jumper t = translate 0 (max 0 (-50 * sin t)) stickFigure

That’s all for this week.

]]>

Welcome to the week 6 summary of Haskell for Kids, my middle school level (that is, ages 12 – 13 ish) programming class using Haskell and Gloss at the Little School on Vermijo. You can go back and review weeks 1, 2, 3, 4, and 5 if you like.

This week was time for practice. Instead of introducing any new ideas, I’ll just post the practice activity we did together in class on Tuesday. The way we practiced was very simple: I drew pictures, and we tried to write descriptions of those pictures. Rather than waste time, let’s just jump right into it. It might help to download (and maybe print out) the PDF file from the end of week 5 (follow the link earlier) for a reminder of how to write list comprehensions.

I’m not including answers, because it’s too easy to just read ahead! If you can’t figure one of them out, feel free to ask for help in the comments.

**Hints:** None! Hopefully this one is easy.

**Hints:** The parameter to *circle* is a number. Use the variable from the list comprehension for that.

**Hints:** This one should also be easy. It’s just a stepping stone to the next practice.

**Hint:** The list comprehension variable tells you how far to translate.

**Hint:** Don’t do this with *rotate*. You can change just one thing from practice 4 and make this work. Remember that you can use the list comprehension variable more than once.

**Hint:** Remember that if you translate something first and then rotate it, it will be rotated around the middle of the picture.

**Hint:** Here you’ll want to use two variables in your list comprehension. One of the examples from the reference page shows you how to do this.

**Hint:** Again you want two variables, but this time one of them will be used in *translate* and the other one in *rotate*.

In addition to this, we just worked on our list comprehension projects. If you remember from last week, the project was to pick something repetitive and draw it. I suggested a U.S. flag if you’re in the U.S. and don’t have another idea. Some of the other projects kids from our class came up with were an iPhone with a grid of icons, a keyboard (the musical type!), and a galaxy with spiral arms and a background of stars. So be creative!

Oh, and I have to show off Sophia’s keyboard, because she worked really, really hard on it, and I’m very impressed. It’s a great use of list comprehensions, too. Here goes…

]]>

Welcome to the week 5 summary of my Haskell class for kids. You can go back and read the previous weeks summaries, if you like:

- First Week: The Basics
- Second Week: Organization
- Third Week: Playing Computer
- Fourth Week: Top Down Design

Our theme this week will be functions and variables.

We started with a simple example. We already know how to draw a star:

star = polygon [ ( -75, -100), ( 0, 87), ( 75, -100), (-100, 25), ( 100, 25), ( -75, -100) ]

and Sophia has figured out how to draw an elephant (this is one of her early versions, actually, but I picked it because it’s shorter; you don’t need to understand it):

elephant = pictures [ rotate (-20) (scale 3 2 (translate 30 40 (circleSolid 25))), translate 150 (-20) (rectangleSolid 40 80), translate (-10) 40 (scale 1.5 1 (circleSolid 80)), translate 50 (-50)(rectangleSolid 40 70), translate (-60) (-50) (rectangleSolid 40 70), translate (-140) 50 (rotate 100 (rectangleSolid 10 40)) ]

But now we want to draw a really awesome star. Being “awesome”, of course, means being twice as large, and the color chartreuse.

awesomeStar = scale 2 2 (color chartreuse star)

awesomeElephant = scale 2 2 (color chartreuse elephant)

and

But, by now, you can probably guess that I can draw an awesome version of *any* picture. There are awesome spaceships, awesome shoes, awesome bicycles… give me any picture at all, and I can tell you how to draw an awesome one: you draw it twice as big, and make it chartreuse. It will get tiresome to keep repeating ourselves, but luckily, Haskell lets us say this just once:

awesome x = scale 2 2 (color chartreuse x)

Now we don’t need to define a bunch of variables like *awesomeStar* and *awesomeElephant*. Instead, we can just write *awesome star*, with a space in between the two!

We’ve seen things like this before: awesome is called a **function**, and the thing that we’re making awesome is called its **argument**. But up until now, we’d only used functions that other people gave us… like *rotate* and *translate* in the Gloss library. Now, we know how to write definitions for our own functions.

To sum up, we can write a function because:

- Given
*any*thing, we know how to make it awesome. - It follows a formula:
*scale 2 2 (color chartreuse ____________)*where you just fill in the blank.

If both of those are true, you can write a function definition. It looks like like the variable definitions we’ve written before, except that it has **parameters**. A parameter is any word that comes before the equal sign (=), **except for** the first one. In the function we wrote a minute ago, we called the parameter *x*. Parameters are just placeholders, so when you use the function, you’ll give it an argument, that argument gets stuck in where ever that variable name pops up.

We also talked about what it means to be cute, and came up with the following:

cute x = scale 0.5 0.5 (color purple x)

Let’s check our assumptions: given any shape you choose to define, we can draw a cute one. It follows a definite formula (make it half the size, and color it purple). And so we wrote a definition where the function is called *cute*, and the parameter is called *x*. If you wanted to draw a cute elephant, you could define *picture* like this: *picture = cute elephant*. There, the function is *cute* and the argument is *elephant*, so to figure out what that means you just replace *x* with *elephant* every time it shows up in the function definition for *cute*!

Let’s look at another function. We know how to draw an elephant… but there’s one problem. No matter where we draw an elephant, its tail is always sticking out at exactly the same angle. Suppose we want to be able to draw an elephant with its tail sticking in whatever direction we like.

It turns out that almost all of drawing an elephant will remain the same, but there’s one *rotate* where we’ll want to change the angle. So once again, we have:

- For any angle, we can draw an elephant with its tail at that angle.
- How we draw an elephant follows the same formula each time, except for a different number in that one place.

Sounds like a job for a function!

elephant angle = pictures [ rotate (-20) (scale 3 2 (translate 30 40 (circleSolid 25))), translate 150 (-20) (rectangleSolid 40 80), translate (-10) 40 (scale 1.5 1 (circleSolid 80)), translate 50 (-50)(rectangleSolid 40 70), translate (-60) (-50) (rectangleSolid 40 70), translate (-125) 50 (rotate angle (translate 0 20 (rectangleSolid 10 40))) ]

See how that worked? Most of the elephant stayed the same, but the rotate in the last line uses the parameter, *angle*. So whatever number we give it decides with way the tail points. It could be straight up…

picture = elephant 0

or it could be mostly down…

picture = elephant 160

So once again, we’re able to use functions: this time to say how to draw an elephant, but leave until later the question of which direction its tail should be pointing.

The interesting thing about functions was that they have **parameters**, which are special variables that can have different values depending on how you use the function. There’s another way that something similar can happen, and it’s in lists. So we’ll finish off by looking at some more kinds of lists.

The lists we’ve used so far have all looked something like this:

[ 1, 2, 3, 4, 5 ]

In other words, a list has always had an opening bracket, then some elements (that is, things in the list) separated by commas, and finally a closing bracket. The things in the list haven’t been numbers… we’ve worked with lists of pictures, and lists of points! You can have lists of whatever you want, but the form is the same: you still have the brackets and the commas. We can call these “simple lists”, because, they are pretty easy to use.

A second kind of list that will come in handy, that we haven’t used before, is a range. That looks like this:

[ 1 .. 10 ]

It always has an opening bracket, a first element, two dots in a row, and then a final element, and a closing bracket. This kind of list counts for you. The things inside (for now, at least) always have to be numbers so that you can count… and the computer will fill in the middle of the list for you. In this case, the list we defined is the same as [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. The range is just a shorthand.

There’s one more simple trick we can play, too: we can give the first two elements, and the computer will continue the pattern:

[ 2, 4 .. 10 ]

This look almost like a range, except that we’ve given the first *two* elements, instead of the just the first one. The computer will notice that we skipped forward by two, and will keep doing that, so that list is the same as [2, 4, 6, 8, 10]!

Finally, we get to the most interesting kind of list of all: called a **list comprehension**. Here’s an example:

[x + 7|x<-[1 .. 5]]

This has quite a few parts, so let’s go through them carefully:

- It starts with an opening bracket, just like all lists.
- Next is an expression. Notice that the expression has a variable
*x*that we haven’t mentioned yet. That’s okay, it’s coming later. - In the middle, there’s a vertical bar (shift + backslash). That separates the expression from the next part.
- Now we have a sort of definition of
*x*, except we say that*x*is*any*thing from another list! We do that with a backwards arrow, which is typed as a less-than sign, followed by a dash. - Finally, there’s a closing bracket.

What this means is: give me a list of all values of (*x*+7), where *x* is any of the numbers in that list. So this is equivalent to [1+7, 2+7, 3+7, 4+7, 5+7]… and of course that is the same as [8, 9, 10, 11, 12].

This last kind of list is very, very interesting; but maybe right now it just looks very complicated and you can’t see why. To see how it’s interesting, we’ll start writing some lists of pictures, instead of just numbers.

The last thing we did this week is combine pictures and list comprehensions to make some interesting pictures. I’ll give you a bunch of examples, but not the pictures they draw. Your task is to *first* try to guess what the picture will look like, and *then* try them out using the gloss programming web site and check your guesses.

I’d very strongly encourage you to take this seriously… use graph paper, work it out, and do your best to figure out what is going to be drawn *before* you run the program and check.

First example:

picture = pictures [ circle x | x <- [ 10, 20 .. 100 ] ]

Second example:

picture = pictures [ translate x 0 (circle 20) | x <- [ 0, 10 .. 100 ] ]

Third example

picture = pictures [ translate x 0 (circle x) | x <- [ 10, 20 .. 100 ] ]

Fourth example:

picture = pictures [ rotate x (rectangleWire 300 300) | x <- [ 0, 10 .. 90 ] ]

Fifth example:

picture = pictures [ translate x 0 (rotate x (rectangleWire 300 300)) | x <- [ -45, -35 .. 45 ] ]

We can also put several different variables on the right side of the vertical bar, separated by commas. In that case, we’ll get something in the list for each possible *combination* of those variables! We can use that, too…

Sixth example:

picture = pictures [ translate x y (circle 10) | x <- [ -200, -100 .. 200 ], y <- [ -200, -100 .. 200 ] ]

Seventh example:

picture = pictures [ rotate angle (translate x 0 (circle 10)) | x <- [50, 100 .. 200 ], angle <- [ 0, 45 .. 360 ] ]

Eighth example:

picture = pictures [ rotate angle (translate (5*x) 0 (circle x)) | x <- [10, 20 .. 40 ], angle <- [ 0, 45 .. 360 ] ]

As you can see, you can use list comprehensions to make lots of really cool pictures where it would be really tedious to write out each shape the way we’ve been doing before.

Your assignment this week is to pick a picture with a lot of repetition that you can draw with list comprehensions, and build it. If you are in the United States and don’t have another idea, a really good one is the American flag!

Hints:

- There’s a program to draw a star at the beginning of this summary. You can copy the star part from that if you like.
- You’ll probably have to draw the stars in two groups: first, there’s a 5-row, 6-column bigger grid, and then there’s a 4-row, 5-column smaller grid inside of that.

You don’t have to draw a flag, though! Especially if you’re not in the United States, your flag probably doesn’t repeat as much as ours, so you’ll want to pick something different. Just pick something you can draw by using list comprehensions to make lists of pictures.

Have fun!

One last thing… I’ve put together a reference card about the recent things we’ve done: lines, polygons, and types of lists. This might be a good thing to keep around. Click below to grab a copy.

]]>