Jecel Assumpcao Jr jecel@lsi.usp.br
Mon, 15 Feb 1999 13:12:35 -0300

Alan Grimes wrote:
> After smoking a bushel of weed I came up with this:
> Lets write TUNES in LOGO!!! =P
> ps: I honestly don't smake anything.

Please note that this serious response is not meant to spoil your
joke, but I have to ask: why not?

One obvious complaint would be that there are no good implementations
of the language available. But that was the situation with Pascal
before Borland's Turbo Pascal came along. That single implementation
was enough to keep C at bay for over half a decade! The same with
Logo - just because no one has done a serious implementation doesn't
mean it can't be done.

While Logo is more friendly than other Lisps by having a syntax
that greatly reduces the parenthesis (but is a bit confusing for
my taste) and nicer error messages (due to, among other things,
a separation of functions that return values from those that don't),
it lacks these features:

  - lambda
  - closures
  - continuations
  - macros

I also find it irritating that primitives can do things user defined
functions can't, like being infix or taking a variable number of
arguments (though UCBLogo can do the latter).

It would seem that these limitations would justify the language's
"baby Lisp" nickname, but it is amazing what you can do with what
is available:

  to mywhile :cond :body
      if not run :cond [stop]
      run :body
      mywhile :cond :body

Even with the lack of closures we can define a control structure
like this thanks to the dynamic scoping. Unfortunately, if either
"cond" or "body" are used as variables in the scope where mywhile
is called, then the results will be totally wrong. You can get
around this by using variable/argument names like XXX985YYY in
mywhile's definition, but this isn't very satisfactory.

Note that :cond and :body are simple code lists. Without lambdas,
how can you define a map function?

  map [[x] print reverse :x] [[1 2 3] [a b c] [100 110 120]]

should print out

  3 2 1
  c b a
  120 110 100

If we had a dolambda, we could define

  to map :expr :alist
      if empty :alist [stop]
      dolambda :expr list first :alist []
      map :expr butfirst :alist

A "poor man's" lambda could be built like this:

  to dolambda :lambda :values
      run auxlambda first :lambda butfirst :lambda :values

  to auxlambda :names :body :values
      if empty :names [output :body]
      if empty :values [output :body]
      local "binding
      make "binding word "" first :names
      output (sentence [local] :binding [make] (list :binding
                   first :values)
                   auxlambda butfirst :names :body butfirst :values)

My point? As Jerry Pournell loves to say "perfect is the enemy of
good enough". Even a Tunes written in Logo would be way better than
no Tunes at all. Of course, Scheme is a much better systems programming
language than Logo (and ML may be even better for Tunes from what
I have heard, but it is one of the few languages I don't know). The
open source development style doesn't work unless there is running
code to be dicussed and improved. If there was something running
(in Scheme, for example), I'll bet Rice's arrow system could be
implemented with little effort. Nothing explains ideas as well as
a working system.

As for low level stuff, I don't think it makes sense to work on
that anymore with Utah's OSkit finally out.

-- Jecel