Logo Language

Logo is an interesting Programming Language, designed by Seymour Papert for children, once much used in schools, and never fully appreciated.

Logo as a Functional Programming language

Logo looks like it's about manipulating a triangle on the screen (or a robot on the floor) that can leave a mark behind it, with the intention of drawing pictures. However, it can also be used to do much, much more complex things; indeed, Eric Raymond referred to Logo as a "Stealth Lisp".

Ironically, there is a Lisp Language dialect with turtle graphics (originally with a real robotic turtle!):

Logo also had an important influence on Smalltalk Language via Alan Kay and Smalltalk Seventy Two (see Early History Of Smalltalk).

Logo is notable as one of the very few languages that ever had both Dynamic Scoping and Tail Call Optimization at the same time. Over the years, more than one person has believed this combination to be impossible in the general case (see, for example, pages 12 and 13 of Lambda: The Ultimate Declarative

describes how this can be accomplished with Deep Binding

ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-379.pdf

the same basic principle works with Shallow Binding as well, and is how Tail Call Optimization is implemented in Ucb Logo

Brian Harvey

Is the Logo Language really a full-featured Functional Programming language? Does it have Lexical Closures? Does it have even First Class Functions? How about Extensible Types? -- Bear in mind that Lisp Language itself generally used Dynamic Scope before Scheme Language came along.


Here a version implemented in Java Script using Continuation Passing Style embedded in a Tiddly Wiki.


Date:
Wed, 08 Mar 2006 22:13:10 -0800

From:
Brian Harvey

Subject:
Re: ucblogo parameter binding peculiarity

The message below is being cross-posted from comp.lang.logo.

If I were writing a large production program, I'd want a lexically scoped language. But in a language meant to encourage exploration by kids, I still think dynamic scope is the right choice. In case anyone's interested in a longer exposition, here is the relevant excerpt from the lecture notes of my SICP-based course at Berkeley:

Logo uses dynamic scope, which we discussed in Section 3.2, instead of Scheme's lexical scope. There are advantages and disadvantages to both approaches. Summary of arguments for lexical scope:

Allows local state variables (OOP).

Prevents name "capture" bugs.

Faster compiled code.

Summary of arguments for dynamic scope:

Allows first-class expressions (WHILE).

Easier debugging.

Allows "semi-global" variables.

Lexical scope is required in order to make possible Scheme's approach to local state variables. That is, a procedure that has a local state variable must be defined within the scope where that variable is created, and must carry that scope around with it. That's exactly what lexical scope accomplishes.

On the other hand, (1) most lexically scoped languages (e.g., Pascal) don't have LAMBDA, and so they can't give you local state variables despite their lexical scope. And (2) lexical scope is needed for local state variables only if you want to implement the latter in the particular way that we've used. Object Logo, for example, provides OOP without relying on LAMBDA because it includes local state variables as a primitive feature.

Almost all computer scientists these days hate dynamic scope, and the reason they give is the one about name captures. That is, suppose we write procedure P that refers to a global variable V. Example:

(define (area rad) (* pi rad rad))

This is intended as a reference to a global variable PI whose value, presumably, is 3.141592654. But suppose we invoke it from within another procedure like this:

(define (mess-up pi) (area (+ pi 5)))

If we say (mess-up 4) we intend to find the area of a circle with radius 9. But we won't get the right area if we're using dynamic scope, because the name PI in procedure AREA suddenly refers to the local variable in MESS-UP, rather than to the intended global value.

This argument about naming bugs is particularly compelling to people who envision a programming project in which 5000 programmers work on tiny slivers of the project, so that nobody knows what anyone else is doing. In such a situation it's entirely likely that two programmers will happen to use the same name for different purposes. But note that we had to do something pretty foolish--using the name PI for something that isn't pi at all--in order to get in trouble.

It's just the letter p followed by the letter i. It could stand for anything in the mind of any number of programmers.

Lexical scope lets you write compilers that produce faster executable programs, because with lexical scope you can figure out during compilation exactly where in memory any particular variable reference will be. With dynamic scope you have to defer the name-location correspondence until the program actually runs. This is the real reason why people prefer lexical scope, despite whatever they say about high principles.

As an argument for dynamic scope, consider this Logo implementation of the WHILE control structure:

to while :condition :action if not run :condition [stop] run :action while :condition :action end

to example :x while [:x > 0] [print :x make "x :x-1] end

? example 3 3 2 1

This wouldn't work with lexical scope, because within the procedure WHILE we couldn't evaluate the argument expressions, because the variable X is not bound in any environment lexically surrounding WHILE. Dynamic scope makes the local variables of EXAMPLE available to WHILE. That in turn allows first-class expressions. (That's what Logo uses in place of first-class functions.)

There are ways to get around this limitation of lexical scope. If you wanted to write WHILE in Scheme, basically, you'd have to make it a special form that turns into something using thunks. That is, you'd have to make

(while condition action)

turn into

(while-helper (lambda () condition) (lambda () action))

But the Logo point of view is that it's easier for a beginning programmer to understand first-class expressions than to understand special forms and thunks.

Most Scheme implementations include a debugger that allows you to examine the values of variables after an error. But, because of the complexity of the scope rules, the debugging language isn't Scheme itself. Instead you have to use a special language with commands like "switch to the environment of the procedure that called this one." In Logo, when an error happens you can *pause* your program and type ordinary Logo expressions in an environment in which all the relevant variables are available. For example, here is a Logo program:

to assq :thing :list if equalp :thing first first :list [op last first :list] op assq :thing bf :list end

to spell :card pr (se assq bl :card :ranks "of assq last :card :suits) end

to hand :cards if emptyp :cards [stop] spell first :cards hand bf :cards end

make "ranks [[a ace] [2 two] [3 three] [4 four] [5 five] [6 six] [7 seven] [8 eight] [9 nine] [10 ten] [j jack] [q queen] [k king]] make "suits [[h hearts] [s spades] [d diamonds] [c clubs]]

? hand [10h 2d 3s] TEN OF HEARTS TWO OF DIAMONDS THREE OF SPADES

Suppose we introduce an error into HAND by changing the recursive call to

hand first bf :cards

The result will be an error message in ASSQ--two procedure calls down--complaining about an empty argument to FIRST. Although the error is caught in ASSQ, the real problem is in HAND. In Logo we can say PONS, which stands for "print out names," which means to show the values of *all* variables accessible at the moment of the error. This will include the variable CARDS, so we'll see that the value of that variable is a single card instead of a list of cards.

Finally, dynamic scope is useful for allowing "semi-global" variables. Take the metacircular evaluator as an example. Lots of procedures in it require ENV as an argument, but there's nothing special about the value of ENV in any one of those procedures. It's almost always just the current environment, whatever that happens to be. If Scheme had dynamic scope, ENV could be a parameter of EVAL, and it would then automatically be available to any subprocedure called, directly or indirectly, by EVAL. (This is the flip side of the name-capturing problem; in this case we *want* EVAL to capture the name ENV.)


The tragedy of Logo

Part of Logo's low esteem amongst programmers is that they simply aren't aware of its full power; they learned Logo at school, from teachers who didn't know about it (because it's too 'advanced'); most of the schoolkids who learned Logo hit the ceiling of their instructors' knowledge before they reached any limit of the language's capabilities. Ironically, this means that Logo doesn't get a chance to show its real strength, which could be described as Low Floor High Ceiling: a six-year-old can learn the basics of turtle control in a matter of minutes, but can continue building on those fundamentals indefinitely, and eventually use the same tools to master advanced programming concepts.

That part about instructors hitting their limits is so true... I 'borrowed' the manual and got my turtle drawing Koch snowflakes with a recursive function. The normal instruction didn't even get into functions, let alone recursion.

We'd still like to see how far a group of elementary school students could progress in Logo if taught by a knowledgeable computer scientist. That would be interesting. One perennial question in this area is What Sort Of Computation Would Interest Junior School Children

I got excited a bit about Logo, partly because I was trying to interest my kids in something creative with the computer. I don't think I've managed a Mind Storm :-(. I also found some of the language syntax inconsistent and hard to explain to kids, particularly the quoting rules and use of colons for arguments. -- Andy Dent

Not the Logo specification

There is no real Logo specification.

''I worked briefly with Brian Harvey on Berkeley Logo, and his response to "Where's the Logo spec?" was "Basically, there isn't one." However, as with its kindred in the Lisp Language family, there is a subset of functionality which is shared between most implementations. -- Joseph Dale

That's right. I emailed Brian Harvey several years ago asking this, asking if there's a spec, his reply was that they had some meetings about it (I lost the mail, I don't recall who's exactly 'they'), he said the things they all agreed on were that: (a) it has to have list processing (b) no Turtle Graphics required. I ended up implementing a Forth Language with Turtle Graphics instead.

The thing that disappoints me most about Logo is that the different versions diverged considerably in language so you're fairly stuck (MSWLogo has done a fairly nice job of extensions as a current free version but I'd like to see it on the Mac) and so a lot of the interesting examples from old Apple-based Logo environments don't easily propagate. -- Andy Dent

Implementations

The first commercial Micro Computer implementation of Logo was on the Texas Instruments TI99/4. It would complain "out of ink" and refuse to draw further until the screen was cleared. The TI99/4 was using a character generator, and creating new character definitions as needed to fake bitmap graphics. With a 1000 character screen buffer and only 256 characters in the character generator. The TI99/4 used the Sprite Chip invented by Daniel Hillis for his masters thesis at Massachusetts Institute Of Technology.

Later versions appeared for the Apple II (Apple Two), the Commodore 64, (Commodore Sixty Four) the Apple Macintosh, and eventually the IBM PC. At its height in the 1980s, it was in use in one out of every four elementary schools in the US.

Brian Harvey wrote a C implementation of Logo and it has been maintained and updated since. It runs on Unix with X11 (including Linux), DOS, Windows, and MacOS. It's command-line based, rather than fully GUIish. It's available from Brian's homepage at www.cs.berkeley.edu .

Especially of interest is a new version of Logo called Star Logo with is a parallel version of logo for doing things like flock simulations.

Another new version of Logo with multiturtles called Net Logo.

There's an implementation of Logo in Mono Project's CVS, called, appropriately enough, Mono Logo. No Turtle Graphics yet, though.

KTurtle is part of the official KDE Edutainment package. The interperator is based on Ws Basic. It is built specifically for kids so it doesn't have all the advanced features, but has a very easy xml format to translate keywords into other natural languages.

One Laptop Per Child doesn't have Logo (yet), but it has an activity called "Turtle Art" for playing with Turtle Graphics using a snap-together Visual Programming Language.

Python wants to be logo

Uncle Guido wants Python Language to be the new Logo. I say, only if he can make native support for Turtle Graphics, or come up with something that's just as much fun.

-- Perhaps, as well as Turtle Graphics, some tutorials using 'TKInter' would help. Just recently, I pulled down a tutorial to explore Python, and within minutes had a series of interactive buttons built. The importing of tools to easily create a strong button/window interface gives another example of 'keep it interesting by giving the student a familiar context', a teaching rule I really respect. --Darryl Davidson

Not sure how long it's been there, but check out Python's standard 'turtle' module. There is a Quick'n'dirty implementation in the Python Card samples.

There is also Vee Python, which is mainly used by physics people. It probably isn't really suitable for young children though.


I always claimed :Logo came too early Nowadays on faster systems even interpreted it would work marvelous ! Comparable even to Unix. -- Pieter Jansegers


Logo and lego

These are aimed at children but appreciated by adults, but are otherwise not the same.

How about Lego Language?

Also, note that Seymour Papert's seminal logo book is called Mind Storms (ISBN 0465046746). Lego borrowed the name for their programmable stuff, which has nice hack value.


At www.sonoma.edu I have tried to compile a list of the original Logo memos, now scattered among the MIT AI lab memos. Many of them are very interesting. The first four do a good job of explaining the project and the philosophy. The TORTIS papers are about a big button box that let really young children control the turtle (including the ability to store procedures and a "slot machine" which the child programmed by putting cards representing actions into slots in a board!). There are papers reporting on a test of Logo in a Brookline school with LSI-11's (microprocessor version of the PDP-11). There's even a paper breaking down the art of juggling into "procedures" and explaining how to fix common "bugs". Good stuff!


There is a Logo Foundation here: el.media.mit.edu Turtle Academy is a cool website for kids who want to learn logo : turtleacademy.com



See original on c2.com