Logo

flowers

Manual

Introduction

A logo program is at its simplest just a series of instructions to a turtle to move around a screen drawing coloured lines as he goes.

To make logo programming more powerful, you also get a looping construct, procedures, and arithmetic expressions, all explained in more detail below.

Turtle Commands

pd colour

Pen down. colour is a character in the range a to p inclusive. After calling this, whenever the turtle moves, he will trace a line in the selected colour.

pu

Pen up. After calling this, until you call pd again, any movements the turtle makes won't leave a line behind him or disturb any pixels.

fd expr

Tell the turtle to move forwards. He'll draw a line behind him if his pen is down. expr can be a number (integer or decimal), or an arithmetic expression enclosed in square brackets (see Arithmetic Expressions below).

The screen goes from -500 to +500 on both axes.

bk expr

Like fd only he moves backwards.
Example
illustration

This shows all the different colours. Colour a is black. Things like call, rot, defproc etc. are explained later.


pu bk 300 lt 90 fd 300 rot

pd b call square 100
pd c call square 100
pd d call square 100
pd e call square 100

pu bk 100 rt 90 fd 100 rt 90

pd f call square 100
pd g call square 100
pd h call square 100
pd i call square 100

pu bk 100 lt 90 fd 300 lt 90

pd j call square 100
pd k call square 100
pd l call square 100
pd m call square 100

pu bk 100 rt 90 fd 100 rt 90

pd n call square 100
pd o call square 100
pd p call square 100

defproc square side
    rep 4
        fd side lt 90
    endrep
    pu
    fd [side * 2]
endproc
 

home

Move the turtle back to the centre of the screen where he started. If his pen is down, he'll trace a line on his way.

rot

Reset the turtle's orientation to 0 degrees as it was when he started.

setpos x:y

Move the turtle to position x, y. If pen is down, draw a line on the way.

lt angle

Tell turtle to turn left angle degrees.

rt angle

Tell turtle to turn right angle degrees.

print expr

Outputs expr to stdout-- useful for debugging, or for using logo as a desk calculator, since if expr is an arithmetic expression it will be evaluated.

printn expr

The same as print, but outputs a newline afterwards.

Writing Logo Programs

Syntax

A statement is a command followed in some cases by parameters. For example, the fd command must be followed by exactly one parameter-- the distance to go forward. The pu command on the other hand, must not be followed by any parameters. Commands, parameters, and other commands are all separated by whitespace-- which is 1 or more of either or all of the newline, tab or space characters.

Lists (used in procedure definitions and calls, see below) can't have whitespace in them. The members of the list are separated with the : character. The empty list is represented by a single :.

Procedure and parameter names can use any characters you like so long as they can't be confused with anything else (digits, operators, commands etc.)

Arithmetic expressions must be enclosed in a single set of square brackets.

Comments start with # and carry on to the end of the line.

Looping

rep count commands ... endrep

You can tell the turtle to repeat a series of commands a certain number of times using the rep command.

e.g.


rep 4
    fd 100 rt 90
endrep

will draw a square.

Loops can be nested as many times as you like, so:


rep 36
    rep 4 fd 100 rt 90 endrep
    rt 10
endrep

will draw a whole fan of squares.

Procedures

defproc name param-list commands ... endproc

This defines a procedure, which is a parameterized list of commands. Procedures aren't executed until you call them.

For example:


defproc rectangle width:height
    rep 2
        fd width lt 90 fd height lt 90
    endrep
endproc
 

defines the procedure rectangle.

call procedure-name param-list

Tells the turtle to execute the procedure with those parameters, e.g.


call rectangle 100:200

will call the procedure rectangle with parameters 100 for width, and 200 for height. This means all the commands between defproc rectangle width:height and endproc will have width and height substituted for 100 and 200 respectively, and given to the turtle to execute.

Procedures can call other procedures, can pass their parameters on to other procedures, and parameters can be included in arithmetic expressions. Here is an example illustrating all these features:

polygon fan picture


defproc polygon size:n
    rep n
        fd size
        rt [360 / n]
    endrep
endproc

defproc polygon_fan size:n
    rep [2 * n]
        call polygon size:n
        rt [360 / (2 * n)]
    endrep
endproc

call polygon_fan 200:6
 

Arithmetic Expressions

The interpreter can also do arithmetic. So instead of telling the turtle:

fd 100

(which means go forward 100), you can tell him:

fd [(30 + 10 * 2) * 2]

which means the same thing.

Arithmetic expressions must be enclosed within square brackets. Inside the square brackets you can put spaces, tabs, or newlines (whitespace) between things as you please, but you don't have to. Expressions are evaluated using the proper rules for precedence, may contain the operators +, *, /, -, parentheses (, ), and integer or decimal numbers.

A special feature of this logo interpreter is that [0 / 0] = 0. In fact, 0 / 0 is a trinity that can be either 0, 1 or infinity, but in this logo interpreter, it always 0. The more astute reader will realize that this property means you can write:


pu lt 90 fd 400 rt 90 pd k

defproc zig count
    rep [count / count]
        rt 45 fd 50 rt 90 fd 50 lt 135
        call zig [count - 1]
    endrep
endproc

call zig 4
 

zigzag

instead of the more conventional:


pu lt 90 fd 400 rt 90 pd k

defproc zig count
    rep count
        rt 45 fd 100 rt 90 fd 100 lt 135
    endrep
endproc

call zig 4
 
You may think (rightly) that this is a rather convoluted way to do things. Really, the special rule for division means rep can be used to synthesize if in the sense of if not zero. With if and recursion, you can write loops without using rep … but then you used rep to simulate if and if you had rep in the first place then when not just use it for the purpose for which it was obviously intended?

Being able to simulate if with the [0 / 0] rule does mean however that you can implement more powerful kinds of looping than rep on its own is capable of. It isn't possible to write a program to draw a spiral, for example, without using recursion.


defproc corner length:angle
    rep 2
        fd length rt angle
    endrep
endproc

defproc spiral length:pitch:laps
    rep [laps / laps]
        call corner [length + laps * pitch]:20
        call spiral length:pitch:[laps - 1]
    endrep
endproc

pu
lt 90 fd 300 rot
pd m

call spiral 3:1:70
 
spiral

The more elegant solution would have been to provide if and recursion, and done away with rep. The practical solution would have been to provide if as well as rep, and if one was feeling really generous, something like for as well-- not that you need it though.

The example we've just seen shows how to use tail-recursion to implement a loop where some of the values inside the loop change with each iteration-- something we couldn't do with just rep, which can only repeat exactly a series of turtle commands.

Here's another example using recursion to draw square spirals in the 'Grecian' style with an inner spiral. Note that we call the function to draw a right hand bend before recursing, and the left hand bend afterwards. That means we draw count right hand bends first, and then on the way back up, another count left hand bends.

square spiral

defproc right size
    rep 2
        fd size rt 90
    endrep
endproc

defproc left size
    rep 2
        fd size lt 90
    endrep
endproc

defproc spiral count:size:pitch

    rep [count / count]
        call right [size * count]
        call spiral [count - 1]:size:pitch
        call left [(size - pitch) * count]
    endrep

    rep [1 - count / count]
        fd [pitch / 2] rt 90
    endrep

endproc

defproc pattern count:size:pitch
    rep 2
        pd k
        call spiral count:size:pitch
        pd l
        call spiral count:size:pitch
    endrep
endproc

call pattern 8:50:6

The interpreter

Get it from here.

Two contrasting styles of programming and programming languages are called imperative and functional. Logo is almost a purely imperative programming language (somewhat corrupted by having arithmetic expressions), Scheme is almost completely functional. Therefore it is interesting to implement the logo interpreter in Scheme. The Scheme is compiled to C with chicken, and from C to a binary executable with a C compiler.