# teaching machines

## University of Canterbury Seminar

May 24, 2019 by . Filed under deltaphone, madeup, public, talks, twoville.

Hi, I’m Chris and I teach people to teach machines. But I am a reluctant computer scientist. Sometimes I get concerned that the thing I know the most about is not directly linked to my survival. My father knew how to keep machines running. My wife grows vegetables. In a post-apocalyptic world, they would be valuable. I would not be.

A few weeks ago, my wife asked me if I thought our sons would study computer science. I told her that I hoped to teach them enough of it at home that they’d be freed up to study something else.

I really do like my discipline, but I love more the things that my children, my students, and I can make with it. The past few years, I have been searching for ways to make computer science less virtual and more physical, more integrated in the world around us. Our agenda for today is to demonstrate three projects that support my mission of making computer science less virtual.

### Computational Making

Schools left and right, politically and geographically, are establishing makerspaces, buying up 3D printers and laser cutters, and getting their students designing and building real things. The students are making. This sounds great. However, if you talk to the teachers and librarians who are staffing these makerspaces, you will hear about the many kids who are just downloading other people’s 3D models and design files from Thingiverse and fabricating those.

This happens for a couple of reasons. First, its part of the maker ethos to share what one has made. Second, learning to model in 2D and 3D is time-consuming and doesn’t really fit well into an already crowded school curricula. I think computer science can fix this. Instead of just plain making, we need computational making.

We hear a lot these days about computational thinking. There’s little agreement about what skills and concepts make up computational thinking, and it has come to be used as a way to invoke the idea of computer science but subtract out or downplay programming. I needed a term to invoke the idea of creating but with programming added in. That is computational making, which I define as a creative process

• guided by algorithms and data
• carried out in a parametric design space
• with a physical output.

Let’s now look at some tools I’ve been building to facilitate computational making.

The first tool is Madeup, a programming language for making things up—literally. It is very much modeled after the drawing mechanics of Seymour Papert’s Logo from the 1980s, but extended to three dimensions. Madeup, like Logo, is meant to make learning geometry an interactive experience. Instead of imposing a grand coordinate system over all space, the programmer uses a coordinate system relative to the avatar on the screen. Logo’s avatar was a turtle, and Papert called this way of thinking about space turtle geometry. Let’s see it at work in an example. We’ll code a rupee from the Legend of Zelda games.

For those of you who have been spending your time elsewhere, rupees look like this:

We will program the cross section of one of these. Imagine that we cut one right down the middle. What shape would we see? An elongated hexagon. Let’s write Madeup code to trace out the top half of the hexagon, like so:



moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10

var mupDiv = jQuery('#mup_rupee1');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee1').submit();

moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10



Next we revolve that cross section around the x-axis, sampling the surface or revolution just six times to produce the hexagonal structure:



moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10

nsides = 6
rotate 0, 1, 0, 90
revolve 1, 0, 0, 360

var mupDiv = jQuery('#mup_rupee2');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee2').submit();

moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10

nsides = 6
rotate 0, 1, 0, 90
revolve 1, 0, 0, 360



And finally we stretch it a bit vertically:



moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360

var mupDiv = jQuery('#mup_rupee3');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee3').submit();

moveto 0, 0
move 10
yaw 45
move 5
yaw 90
move 5
yaw 45
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360



What if want to make a sharper bevel? We must change the angle we turn. Instead of 45, let’s try 30:



moveto 0, 0
move 10
yaw 30
move 5
yaw 90
move 5
yaw 30
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360

var mupDiv = jQuery('#mup_rupee4');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee4').submit();

moveto 0, 0
move 10
yaw 30
move 5
yaw 90
move 5
yaw 30
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360



Whoops. We’ll need to change the peak angle too. But to what? Some experimentation leads us to 120:



moveto 0, 0
move 10
yaw 30
move 5
yaw 120
move 5
yaw 30
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360

var mupDiv = jQuery('#mup_rupee5');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee5').submit();

moveto 0, 0
move 10
yaw 30
move 5
yaw 120
move 5
yaw 30
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360



But we can do better than experiment. Why is it 120? Because all told, we are turning back the direction we came, which is 180 degrees. We burn 30 of those up on the first yaw and 30 on the third yaw. That leaves 120 left for the middle yaw. Now we can generalize this and turn the angle into a parameter:



angle = 30

moveto 0, 0
move 10
yaw angle
move 5
yaw 180 - 2 * angle
move 5
yaw angle
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360

var mupDiv = jQuery('#mup_rupee6');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_rupee6').submit();

angle = 30

moveto 0, 0
move 10
yaw angle
move 5
yaw 180 - 2 * angle
move 5
yaw angle
move 10

scale 1, 1.5, 1
rotate 0, 1, 0, 90
nsides = 6
revolve 1, 0, 0, 360



Madeup is a fully-featured programming language. It supports conditionals, loops, variables, functions, and arrays. There are many ways to turn a path into a solid. We’ve seen revolve, but there’s also dowel. Let’s make a chain link:



moveto 0, 0

repeat 2
move 3
repeat 18
yaw 10
around
move 0.3
end
end

dowel

mupDiv.closest('pre').replaceWith(mupDiv);

moveto 0, 0

repeat 2
move 3
repeat 18
yaw 10
around
move 0.3
end
end

dowel



Let’s see a few more examples.



long = 3.2
short = long * 0.5

to rectangle x, y, z, rollAngle, pitchAngle, yawAngle
push
roll rollAngle
pitch pitchAngle
yaw yawAngle
moveto x, y, z
repeat 2
move short * 2
yaw 90
move long * 2
yaw 90
end
dowel maxBend:1
pop
end

.rgb = {1, 0.7, 0.8}
rectangle -long, -short, 0, 0, 0, 0
.rgb = {0.7, 1, 0.8}
rectangle short, 0, long, 90, 90, 0
.rgb = {0.7, 0.8, 1}
rectangle 0, long, short, 90, 0, 90

var mupDiv = jQuery('#mup_dowel');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_dowel').submit();

long = 3.2
short = long * 0.5

to rectangle x, y, z, rollAngle, pitchAngle, yawAngle
push
roll rollAngle
pitch pitchAngle
yaw yawAngle
moveto x, y, z
repeat 2
move short * 2
yaw 90
move long * 2
yaw 90
end
dowel maxBend:1
pop
end

.rgb = {1, 0.7, 0.8}
rectangle -long, -short, 0, 0, 0, 0
.rgb = {0.7, 1, 0.8}
rectangle short, 0, long, 90, 90, 0
.rgb = {0.7, 0.8, 1}
rectangle 0, long, short, 90, 0, 90



This perimeter of this gear is extruded and a hole is subtracted from its center:



.rgb = {1, 1, 0}

for i to 360 by 60
polarto 3, i
polarto 5, i + 15
polarto 5, i + 30
polarto 3, i + 45
end
home

extrude 0, 0, 1, 3

nsides = 20
moveto 0, 0, 10
moveto 0, 0, -10
subtract
dowel

var mupDiv = jQuery('#mup_extrude');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_extrude').submit();

.rgb = {1, 1, 0}

for i to 360 by 60
polarto 3, i
polarto 5, i + 15
polarto 5, i + 30
polarto 3, i + 45
end
home

extrude 0, 0, 1, 3

nsides = 20
moveto 0, 0, 10
moveto 0, 0, -10
subtract
dowel



The Madeup editor also supports a blocks programming interface, and one can (mostly) switch back and forth between text and blocks.

How does Madeup make computer science less virtual? The model can be printed on a 3D printer or embedded in a game engine.

I spent the last year

### Twoville

The second project I’d like to share you has one less than dimension than Madeup. Twoville’s purpose is to help programmers build 2D scalable vector graphics (SVG) files that can be fed into a laser or vinyl cutter.

Let’s make another jewel, a diamond. Since we’re in 2D, we’ll just create the profile of a diamond. We start with a square, but rotate it a bit:



viewport.center = [0, 0]
viewport.size = [5, 5]

r = rectangle()
r.center = [0, 0]
r.size = [3, 3]
r.color = [0.5, 0.8, 0.8]
rotation = r.rotate()
rotation.pivot = [0, 0]
rotation.degrees = 45

var twovilleDiv = jQuery('#twoville_diamond0');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_diamond0').submit();

viewport.center = [0, 0]
viewport.size = [5, 5]

r = rectangle()
r.center = [0, 0]
r.size = [3, 3]
r.color = [0.5, 0.8, 0.8]
rotation = r.rotate()
rotation.pivot = [0, 0]
rotation.degrees = 45



Twoville tends to be a very declarative language, as we’re often just setting properties. To ease the syntactic burden of setting a sequence of properties, I added in the scoping function with:



with viewport
center = [0, 0]
size = [5, 5]

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45

var twovilleDiv = jQuery('#twoville_diamond1');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_diamond1').submit();

with viewport
center = [0, 0]
size = [5, 5]

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45



We want to chop off the top, so we overlay another rectangle across it:



with viewport
center = [0, 0]
size = [5, 5]

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45

with rectangle()
center = [0, 2]
size = [4, 2]
color = :red

var twovilleDiv = jQuery('#twoville_diamond2');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_diamond2').submit();

with viewport
center = [0, 0]
size = [5, 5]

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45

with rectangle()
center = [0, 2]
size = [4, 2]
color = :red



To remove the red rectangle, we create a cutout object that serves as a mask:



with viewport
center = [0, 0]
size = [5, 5]

chopper = cutout()

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45

with rectangle()
center = [0, 2]
size = [4, 2]
color = :red
parent = chopper

var twovilleDiv = jQuery('#twoville_diamond3');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_diamond3').submit();

with viewport
center = [0, 0]
size = [5, 5]

chopper = cutout()

with rectangle()
center = [0, 0]
size = [3, 3]
color = [0.5, 0.8, 0.8]
with rotate()
pivot = [0, 0]
degrees = 45

with rectangle()
center = [0, 2]
size = [4, 2]
color = :red
parent = chopper



A similar approach can be used to make a phone:



with viewport
corner = [-1, -1]
size = [12, 19]

hole = cutout()

// Screen
with rectangle()
corner = [1, 2]
size = [8, 14]
parent = hole

// Home
with circle()
center = [5, 1]
parent = hole

// Phone body
with rectangle()
corner = [0, 0]
size = [10, 17]
color = :black
rounding = 1

var twovilleDiv = jQuery('#twoville_phone');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_phone').submit();

with viewport
corner = [-1, -1]
size = [12, 19]

hole = cutout()

// Screen
with rectangle()
corner = [1, 2]
size = [8, 14]
parent = hole

// Home
with circle()
center = [5, 1]
parent = hole

// Phone body
with rectangle()
corner = [0, 0]
size = [10, 17]
color = :black
rounding = 1



Like Madeup, Twoville supports conditionals, loops, functions, and arrays. I used functions to abstract out the droplet shapes of this logo that I walked by everyday in Brisbane, Australia, during the first half of my sabbatical:



with viewport
center = :zero2
size = [20, ~]

to lobe(spin, size)
offset = 0.25

p = with path()
color = [1, 0.5, 0]
opacity = 1
with rotate()
pivot = [0, 0]
degrees = spin
closed = true

with p.jump()
position = [offset, -offset]

with p.line()
position = [offset, -size]

with p.arc()
degrees = 270
center = [size, -size]

lobe(0, 5)
lobe(-90, 3.25)
lobe(-270, 5)

var twovilleDiv = jQuery('#twoville_droplets');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_droplets').submit();

with viewport
center = :zero2
size = [20, ~]

to lobe(spin, size)
offset = 0.25

p = with path()
color = [1, 0.5, 0]
opacity = 1
with rotate()
pivot = [0, 0]
degrees = spin
closed = true

with p.jump()
position = [offset, -offset]

with p.line()
position = [offset, -size]

with p.arc()
degrees = 270
center = [size, -size]

lobe(0, 5)
lobe(-90, 3.25)
lobe(-270, 5)



If you’ve done anything with 3D printing in schools, you will have encountered the slowness of the technology. Models take a long time to print, and the machines need minding. 3D printing doesn’t scale well to large groups of students. Vinyl and laser cutters are much faster, and I think Twoville will better accommodate the time-limited summer camps and workshops I’ve been putting on back home.

### Deltaphone

The last project I’d like to share has a less touchable output. It also has one less dimension than Twoville. I’m losing dimensions as I get older. It must be a case of “dimentia.” Deltaphone is my exploration of applying the idea of turtle geometry to music. Instead of thinking about music as a sequence of absolute positions on the staff, we think of a song in Deltaphone as a sequence of changes or deltas between one note and the next.

Let’s compose a little song to see how it works.

Deltaphone supports variables, conditionals, loops, and functions. The output of Deltaphone is a score.

This project is only a few months old, and I don’t know if it has a future or not. I need to find a music teacher who doesn’t feel threatened by technology and who can help me shape it into a tool to explore music theory and composition.

### Conclusion

These are three projects that I have been developing to make computer science less virtual, to fit it into the everyday worlds of objects and music.

Educational psychologists argue about whether its better to learn a subject in a contextualized or decontextualized manner. Contextualized learning situates concepts in a themed narrative, like robotics or game development. Decontextualized learning happens when there is no overarching narrative.

Neither approach is perfect. We often rely on the context to engage students. The danger of contextualized learning is that learners may not see that concepts transfer to other contexts. For example, someone who has written an algorithm to determine the winner from a collection of players may not see that a very similar algorithm can be used to find the largest file in a directory. The danger of decontextualized learning is that that learners may not see that concepts transfer anywhere.

While this debate is important for educators to consider, I’d like turn it around a bit. What if we embedded computer science in a context not to improve the learning of computer science, but to improve the learning of the context? If the folks using these tools become better makers, mathematicians, and musicians, then my goal will be met.