#
Chapter 3
Turtles

## 3.1 Turtles

There are two ways to use the turtles in DrScheme. You can use it as a TeachPack (see the DrScheme manual for details of TeachPacks) or as a library. Use the `turtles.ss` TeachPack.

In the MrEd language or in a module, load turtles with

    (require (lib "turtles.ss" "graphics"))

The following are the turtle functions:

- `(turtles b)` shows and hides the turtles window based on the boolean `b`. The parameter `b` is optional; if it is left out, it toggles the state of the turtles.

- `(move n)` moves the turtle n pixels.

- `(draw n)` moves the turtle n pixels and draws a line on that path.

- `(erase n)` moves the turtle n pixels and erases along that path.

- `(move-offset h v)`, `(draw-offset h v)`, `(erase-offset h v)` are just like move, draw and erase, except they take a horizontal and vertical offset from the turtle's current position.

- `(turn theta)` turns the turtle theta degrees counter-clockwise.

- `(turn/radians theta)` turns the turtle theta radians counter-clockwise.

- `(clear)` erases the turtles window.

Turtles also defines these syntactic forms:

- `(split E)` spawns a new turtle where the turtle is currently located. In order to distinguish the two turtles, only the new one evaluates the expression E. For example, if you start with a fresh turtle-window and type:

      (split (turn/radians (/ pi 2)))

  you will have two turtles, pointing at right angles to each other. To see that, try this:

      (draw 100)

  You will see two lines. Now, if you evaluate those two expression again, you will have four turtles, etc

- `(split* E ...)` is similar to `(split E ...)`, except it creates as many turtles as there are expressions and each turtles does one of the expression. For example, to create two turtles, one pointing at pi/2 and one at pi/3, evaluate this:

      (split* (turn/radians (/ pi 3)) (turn/radians (/ pi 2)))

- `(tprompt E...)` provides a way to limit the splitting of the turtles. Before the expression E is run, the state of the turtles (how many, their positions and headings) is "checkpointed," then E is evaluated and the state of the turtles is restored, but all drawing that may have occurred during execution of E remains.

  For example, if you do this:

      (tprompt (draw 100))

  the turtle will move forward 100 pixels, draw a line there and then be immediately put back in it's original position. Also, if you do this:

      (tprompt (split (turn/radians (/ pi 2))))

  the turtle will split into two turtles, one will turn 90 degrees and then the turtles will be put back into their original state - as if the split never took place.

  The fern functions below demonstrate more advanced use of `tprompt`.

In the file `turtles-examples.ss` in the `graphics` library of your PLT distribution, you will find these functions and values defined, as example turtle programs. (The file is located in the `graphics` subdirectory of the `collects` subdirectory of the PLT distribution).

- `(regular-poly sides radius)` draws a regular poly centered at the turtle with sides sides and with radius radius.

- `(regular-polys sides s)` draws s regular polys spaced evenly outwards with sides sides.

- `(radial-turtles n)` places 2n turtles spaced evenly pointing radially outward

- `(spaced-turtles n)` places 2n turtles pointing in the same direction as the original turtle evenly spaced in a line.

- `(spokes)` draws some spokes, using radial-turtles and spaced-turtles

- `(spyro-gyra)` draws a spyro-grya reminiscent shape

- `(neato)` as the name says`...`

- `(graphics-bexam)` draws a fractal that came up on an exam I took.

- `serp-size` a constant which is a good size for the serp procedures

- `(serp serp-size)`, `(serp-nosplit serp-size)` draws the Serpinski triangle in two different ways, the first using split heavily. After running the first one, try executing `(draw 10)`.

- `koch-size` a constant which is a good size for the koch procedures

- `(koch-split koch-size)`,`(koch-draw koch-size)` draws the same koch snowflake in two different ways.

- `(lorenz a b c)` watch the lorenz "butterfly" attractor with initial values a b and c.

- `(lorenz1)` a good setting for the lorenz attractor

- `(peano1 peano-size)`

  This will draw the Peano space-filling curve, using split.

- `(peano2 peano-size)`

  This will draw the Peano space-filling curve, without using split.

- `fern-size` a good size for the fern functions

- `(fern1 fern-size)` You will probably want to point the turtle up before running this one, with something like:

  `(turn/radians (- (/ pi 2)))`

- `(fern2 fern-size)` a fern - you may need to backup a little for this one.

## 3.2 Value Turtles

There are two ways to use the turtles in DrScheme. You can use it as a TeachPack (see the DrScheme manual for details of TeachPacks) or as a library. Use the `value-turtles.ss` TeachPack.

In the MrEd language or in a module, load turtles with

    (require (lib "value-turtles.ss" "graphics"))

The value turtles are a variation on the turtles library. Rather than having just a single window where each operation changes the state of that window, in this library, the entire turtles window is treated as a value. This means that each of the primitive operations accepts, in addition to the usual arguments, a turtles window value and instead of returning nothing, returns a turtles window value.

The following are the value turtle functions:

- `(turtles number number [number number number])` creates a new turtles window. The first two arguments are the width and height of the turtles window. The remaining arguments specify the x,y position of the initial turtle and the angle. The default to a turtle in the middle of the window, pointing to the right.

- `(move n turtles)` moves the turtle n pixels, returning a new turtles window.

- `(draw n turtles)` moves the turtle n pixels and draws a line on that path, returning a new turtles window.

- `(erase n turtles)` moves the turtle n pixels and erases along that path, returning a new turtles window.

- `(move-offset h v turtles)`, `(draw-offset h v turtles)`, `(erase-offset h v turtles)` are just like move, draw and erase, except they take a horizontal and vertical offset from the turtle's current position.

- `(turn theta turtles)` turns the turtle theta degrees counter-clockwise, returning a new turtles window.

- `(turn/radians theta)` turns the turtle theta radians counter-clockwise, returning a new turtles window.

- `(merge turtles turtles)`

  The `split` and `tprompt` functionality provided by the imperative turtles implementation aren't needed for this, since the turtles window is itself a value.

  Instead, the `merge` accepts two turtles windows and combines the state of the two turtles windows into a single window. The new window contains all of the turtles of the previous two windows, but only the line drawings of the first turtles argument.

In the file `value-turtles-examples.ss` in the `graphics` library of your PLT distribution, you will find these functions and values defined, as example turtle programs. (The file is located in the `graphics` subdirectory of the `collects` subdirectory of the PLT distribution).

It contains a sampling of the examples from the normal turtles implementation, but translated to use `merge` and the values turtles.