Implementing StarLogo
May 27 2021 11:42
StarLogo is a parallel-processing simulation language designed by Mitchel Resnick in the ’80s, extending ideas from Logo.
Logo was designed to teach children logical and procedural thinking, particularly in terms of “turtle graphics”: moving a turtle about on a flat surface and drawing lines. Sophisticated geometry can be explored procedurally: Abelson and DiSessa’s Turtle Geometry treats vector graphics, topology, and general relativity.
Resnick designed StarLogo to help teach systems thinking, and used it successfully with groups of high-school students. He describes several of these projects and investigations in Turtles, Termites, and Traffic Jams.
StarLogo specifies simulations in terms of turtles - mobile agents - and patches - fixed pieces of ground. Turtles and patches can have properties which can be set and tested, and procedures that execute repeatedly and concurrently for each patch or turtle.
(StarLogo was first implemented on a Connection Machine, a massively
parallel SIMD computer; by convention, parallelized versions of
various programming languages were named with a “∗”, for example
*Lisp
and C*
, hence the name StarLogo. Versions of StarLogo
were implemented on Macintoshes and in Java.)
I thought it would be fun to implement a StarLogo and play with the simulations described in the book. As I am learning Go, so my first thought was to model StarLogo demons as goroutines. As I don’t know how to do GUIs in Go yet I decided to prototype in JavaScript.
Here’s an outline:
a_simulation.js
sketch = {
setup: () => { ...initialization... }
step: () => { ... }
}
starlogo.js
const canvas = ...
const ctx = ...
const turtle_demons = []
const patch_demons = []
function Turtle () { this.x = random(); this.y = random(); ... }
Turtle.prototype.forward = function (n) { ... }
Turtle.prototype.right = function (a) { ... }
Turtle.prototype.draw = function () { ... }
Turtle.prototype.activate_demon = function (demon) { turtle_demons.push(demon) }
...
function Patch (row, col) { this.id = [row, col]; this.center = ...; this.color = ...; }
Patch.prototype.get = function (property) { ... }
Patch.prototype.set = function (property) { ... }
Patch.prototype.draw = function () { ... }
Patch.prototype.activate_demon = function (demon) { patch_demons.push(demon) }
...
const turtles = []
const patches = []
const setup = () => {
for (let i = 0; i < TURTLES; i++) { turtles.push(new Turtle()) }
for (let i = 0; i < PATCHES; i++) { patches.push(new Patch()) }
...
sketch.setup()
}
const step = () => {
sketch.step()
for(d of turtle_demons)
for(t of turtles)
d(t)
for(d of patch_demons)
for(p of patches)
d(p)
}
setup()
The heart of the simulation is the step function in starlogo.js. It
executes the sketch’s own step and then each of the demons for each of
the turtles and patches. There are a current-state
and a
next-state
as is usual in cellular automata implementations, which I
left out of the sketch above.
Cosma Shalizi wrote a fine essay at The Bactra Review on the paedagogy and the politics of decentralized systems in Prof. Resnick’s book.
“The heart of the book, on how to teach people about decentralized processes and emergent behaviors, and the tricky process of designing and controlling them, is excellent. Since I happen to think that self-organization is both quite important and quite neat, this is to me a thing of joy; and no doubt people with different scientific and philosophical biases will find Resnick’s woollier ideas congenial.” – Cosma Shalizi