This summer, as part of Google Summer of Code, I created debugging tools to be used by students programming in the CodeWorld environment. As a current learner of Haskell and of CodeWorld, I believe tools that help users reason about logic are very useful. I wanted to help users identify breaks in logic, and reason about mathematics and code. The tools I built can decompose a larger, more ambiguous problem (“Help! My programme doesn’t work!”) into a smaller, more precise one (“The starting coordinate for our spacecraft’s trajectory is not correct”).

When a student builds an drawing, animation or game in CodeWorld, my new debugging tools help them deconstruct what the programme does in

time: by enabling slow-motion, fast-forward and scrolling through the history of the programme.

position : by enabling the user to zoom in and out and move around to get a different perspective.

organization: by giving the user a deeper understanding of the properties of parts of their pictures.

This video gives a cursory view of these tools.

This sushi game was built by two 7th graders from Colorado.

Features I created:

I built four different features for debugging. They are useful explicitly and in conjunction with each other.

1. Viewable Properties in Inspect Mode

Last summer, Eric Roberts created the Inspect Button for debugging for CodeWorld. I expanded on this tool by showing the viewable properties and their evaluated arguments.

The new viewable properties functionality builds on the Inspect button and shows the evaluated values for expressions defined in the source code.

Eric created an Inspect button that shows the highlighted code to the left and the display of each component (that is tied to the source code) on the coordinate plane. However, the source code does not currently show what the expression evaluated to unless we use the new viewable properties functionality within the Inspect button. This new feature allows a user to see the evaluated expressions for attributes of the picture, which is very helpful in debugging pictures with multiple functions and arguments that work together.

In the above example, we can see that the actual thick polyline expressions are composed of points and thicknesses, and the precise values that give the results shown. We can create a pipeline of expected values vs actual values with this method of debugging.

2. Zooming and Panning

I created buttons that can zoom in, zoom out and reset to the default view this summer. I also created a slider that can zoom in and out, and panning functionality for the drawing canvas. In this example (below), details of a fractal composition are viewable because of these new tools.

In the video, we can see more detail by using the zoom-in and zoom-out buttons, and by panning. This allows us to see smaller patterns within a larger pattern.

3. Time Travel Debugger (History Slider)

Have you ever played a game and not liked the result? Let’s fix that! I’m curious to see what it would like if I won. I want to go back in time to “debug” what would have happened if I had not lost.

I figured out pretty late how to get points. So why not rewind to a point where I can have an (almost) perfect game!

Cheating…it’s a feature, not a bug.

The way this works is by having two lists: one that represents the list of past states and one that represents future states. We can then pop off the most recent value from either the stack of past states or future states to travel back or forward in time.

By popping off the head from the stack of the desired list, we can Undo or Redo state in our Redo and Undo buttons and our stateSlider

This uses the zipper data structure where the state is a pair of lists ([],[]).

4. Speed Slider

The new speed slider allows you to speed up an animation. Playing through an animation at different speeds allows a user to identify patterns in an animation, as well as inconsistencies in those patterns. These inconsistencies can be broken down as either intentional and useful, or as breaks in logic or bugs.

“Why moments” in Programming (bugs)

In the example below, we have a bouncing ball that has a defined boundary in the code.

import CodeWorld main = debugSimulationOf initial step picture initial = (0, 20) step dt state = bounce (inertia dt state) inertia dt (x, vx) = (x + vx * dt, vx) bounce (x, vx)

| x < -9 = (x, -vx)

| x > 9 = (x, -vx)

| otherwise = (x, vx) picture(x, vx) = translated x 0 (solidCircle 1) & rectangle 20 20



It seems to work just fine initially, but when I speed it up by using speedSlider, we see moments when the ball is stuck. This is a bug.

To find out how and why this happens, I paused CodeWorld when the bug occurred, and then stepped backwards and panned to see where this occurs and why. By panning, I am not limited to the viewing boundary of the ball as dictated by the viewing pane, so I get a different perspective. Here, we see that the ball bounces, but is stuck and bounces again, but that wedges the ball in further. We can even rewind to the point at which the ball was bouncing as expected.

Revealing Illusion in an Animation

This animation shows the journey of a hot-air balloon into Space, whereby the traveler becomes a NASA astronaut. When the window is constrained, it is not apparent how the animation is made. It appears as delightful magic.

By using the new debugging, this magic is deconstructed, like a Noh Theatre act that is unmasked.

Made by an 8th grader from California.

Challenges Along the Way

Getting Started

One of the other issues we discovered was that the CodeWorld install script did not work correctly on 32 bit machines. My first pull request made a change to fix this issue. It wasn’t long before I also realized that smaller screens (such as that of my $20 refurbished computer, which runs 32-bit Ubuntu 16.04) didn’t have room for the debug controls I was trying to add. So I had to make another side-trip to add resizing of the programme before I could get started on debugging. This involved CSS and HTML.

In retrospect, these were good ways to get my feet wet with the project.

Hardware

Next, there were a series of hardware issues I encountered. In all, I wiped two operating systems and installed Ubuntu 18.04 three times in three months on two machines.