I went to sleep at about four-thirty in the morning last night. I was in bed a few minutes before that, but I did a little reading about Perl’s canonical object model, using the bless() function and all that nifty built-in class hierarchy stuff. It got me thinking about lexical closures in Perl as an object model, again, and I had several false starts toward sleep as I kept turning the bedside lamp on again to read something about what closures do in Perl while I was thinking about it. It occurred to me that I hadn’t responded to SoSiouxMe‘s commentary on closure-objects as contrasted with bless-objects, and I actually remembered enough of what she’d said that new ideas for what to come back to say about it (once I’d gotten some sleep) occurred to me. Amazingly, after sleeping, I was easily able to reconstruct all those thoughts, check them against what she said and some other sources, and compose a lengthy response. Sometimes, I have trouble doing that after thinking in the shower, let alone after sleep.
Perhaps it was my excited thinking that made me wake up so quickly. I got up after just over two and a half hours of sleep. Of course, I in no way imagined I’d slept so little, so when I saw the time on the clock I thought I had slept close to fifteen hours. Panic! Surprise! CRAP! There’s stuff I needed to do today!
Amazingly, it took me about two more hours of puttering around doing the things I could still do after business hours, and researching/posting that aforementioned response, before I realized that I had my AM and my PM mixed up, and had actually gotten too little sleep rather than too much. I only realized it because I noticed there was still daylight coming through the windows when the time was rapidly catching up with ten o’clock on the cable box. Wotta relief.
So I started thinking again, since I have all this extra time today (I was expecting to wake up at noon, and planned accordingly). In particular, I found myself thinking about the fact that lexical closures are, if anything, more “native” to languages like Scheme and Common Lisp than to Perl. It just seems to be a very intrinsically Lispy thing.
Some of my readers out there are surely not aware of this, but I’ve recently installed UCBLogo on my laptop and gotten my hands on Computer Science Logo Style, Vol. 1: Symbolic Computing. I’m only a few chapters into it. I have very vague recollections of the Turtle Graphics face of Logo on old (pre-Mac) Apples at school, but there’s a lot more to Logo than a child’s toy language used to make squares with a little triangular cursor like some kind of computer geek’s Etch-A-Sketch. It’s probable that even fewer of my readers than are aware of my recent flirtation with Logo are aware that Logo is, in fact, a Turing-complete Lisp dialect — just without the heavy-handed required use of parentheses. Its syntax is refreshingly clean and simple, and I’m enjoying the experience quite a lot. It helps that Brian Harvey’s book Symbolic Computing doesn’t talk down to an assumed grade-school reader, but rather treats the reader as a competent, mature person new to functional programming (but not necessarily new to programming in general, with liberal references to differences between Logo and, for instance, BASIC). It also helps that, contrary to its reputation, Logo is not just for five year olds or fifth graders, it is not just a toy language, and it is not tied to something that looks like an Asteroids game screen without stars and asteroids (unless you draw them).
Logo is a Real Programming Language that was made intentionally more accessible to newbies and had some learning tools built around it. That doesn’t make it less a “serious” programming language. It’s a victim of its own early educational successes coupled with the sidelining that Lisp dialects have suffered in the programming world (thanks in part to the “weirdness” of prefix notation and the ubiquitous parentheses in most functional programming). The UCBLogo (also originally written by Brian Harvey, with help, and available from his webpage if you don’t use an OS that provides extensive package mangement support like Debian’s) implementation of the Logo language is most excellent, and available across a reasonably wide variety of platforms (covering, at minimum, Linux, MacOS, and MS Windows). The exact same binary is used both for opening the interactive shell interpreter for UCBLogo and for constructing shebang lines in stand-alone scripts on Linux, which I find just utterly keen in my appreciation for elegant simplicity — I’m used to languages like Perl, Ruby, and so on, that provide two entirely separate software packages for invokation of the language from the command line or the shebang line (though the Usual Suspects for shells, like bash, tend to do it more the same way as UCBLogo). It even comes with a Turtle Graphics interface, which somehow surprises and delights me on some nostalgic level, though I haven’t bothered to (re)learn how to use it.
I find myself now wondering just how easily a lexical closure is accomplished in Logo. I know that lexical scoping is possible (and, in fact, is the default behavior, which is splendid) with Logo, but am not entirely certain that Logo’s return statement (actually the output command) for procedures is well suited to creating lexical closures. It’s possible there’s another way to do it than the way Perl does, when using a Lisp dialect such as Logo (or Scheme, or whatever), but I haven’t yet run across it. I wonder if any of Harvey’s books on Logo will discuss lexical closures. I’m disinclined to expect to find reference to lexical closures in Logo anywhere else, especially considering the unfortunate manner in which basically every other book about the language on the planet is targeted to grade-schoolers. Google is certainly not providing any help in the matter of finding out whether lexical closures are (easily) possible in Logo. While it’s true that one can “do anything” with one Turing-complete language that one can “do” in another, that’s for a specific programmatic definition of “do” (referring to what the resulting program can do, not how the programmer can make it happen) that doesn’t apply to lexical closures, so I find myself concerned with the question of whether they’re supported by Logo. I hope so: they’re fun.
I love the prefix notation for operations (not operators because they’re actually “functional” primitive procedures in Logo, and not symbolic relationship descriptors as in a “procedural” function-using language) in Logo — and, presumably, in other Lisp dialects — more and more, as I get more used to using them in Logo. The whole worry about operator precedence goes out the window: precedence is a natural outgrowth of planning out your procedures with prefix notation, rather than something inherent in your choice of operators and parentheses while scribing an expression as with infix notation. For those not yet ready to abandon infix symbolic notation, however, the familiar */+- infix operator syntax is available as a load of syntactic sugar, complete with operator precedence rules. I recommend steering clear of them long enough to get used to prefix notation if learning Logo, however. By the time you get used to it in Logo, you’ll probably find the lack of prefix notation in many procedural and object oriented languages annoying, just as you’d probably find the lack of availability of multiple workspaces in Windows Explorer annoying after getting used to, and comfortable with, them using something like WindowMaker or Enlightenment.
The fact that all data types are lists in Logo (yes, even “word” datums — they’re just syntactic sugar for a per-character delineated list rather than the space-delineated “list” lists, or perhaps space-delimited lists are in fact the syntactic sugar) is a beautiful thing to behold, too. I think I’m solidly on the path to that “profound enlightenment experience” to which Eric Raymond refers, when discussing the benefits of learning Lisp. I don’t know exactly what he means by that, necessarily, but I’m already feeling enlightened. I’ve considered the potential benefits of “everything is a list” before, of course, but actually working with it when I’m familiar with other, non-Lispy languages is really driving the point home. The benefits of a functional syntax combined with a list-oriented semantic structure are great fun to experience substantively for the first time (again). While I don’t recommend doing it any time soon, an interesting effect of this is the fact you could literally write an entire, highly complex program of hundreds or thousands of “lines” of code on a single, continuous, semantically indivisible “line” of code — as a single lengthy statement. As BASIC is a line-oriented language as contrasted with something like Perl, so Perl is a line-oriented language as contrasted with something like Logo.
At one end of the spectrum, you have a language like BASIC, which automatically ends a semantically indivisible line of code when you insert a newline into your program, for which what code is on which line makes a tremendous difference in procedural execution, and for which you simply cannot cram more than a certain amount of language semantics onto a given line. Somewhere in the middle is a language like Perl (or C or whatever), which tends to be best served by the availability of line-ending punctuation because there’s a lot more semantic extensibility to the concept of a “line” of code, and because several semantically indivisible lines of code can usually be included on a single visually distinct line of a file (though languages like Python and Pascal limit that flexibility without much deleterious effect in exchange for some benefits), and further because it’s convenient to be able to artificially break a visually distinct line of the file without breaking a semantically indivisible line of code sometimes.
At the other end of the spectrum is something like Logo — and this proves the old saw about things always running in cycles, makes us aware that the old is always new again, and at the same time takes a wholly novel (from the perspective of someone not accustomed to it, like me) approach to old things. Logo doesn’t use semantic line-delimiting punctuation syntax at all (unless you consider a newline to be punctuation): instead, it offers semantic line-continuation syntax, in the form of a tilde rather than the common semicolon, for when you want to visually break a line without semantically breaking it, to insert newlines into the middle of an expression. Unlike with languages where semantically indivisible lines of code are limited by a certain inability to stretch out an expression for too long, with newlines as semantic line delimiting syntactic elements instead of semicolons, this is with Logo not a conceit or quirk of the language. Rather, it is a strict necessity for allowing an elegant and “intuitive” syntactic representation of the language when formatting your code.
It’s just incredible to me how a very long Logo program could all compose a single, well-formatted, and easy to read (yet semantically indivisible) line of code.