Since I got back into Lisp again (I had a wonderful flirtation with
it in University, but it was presented as a toy language, so I
didn't stick with it), I've been telling people how incredibly
freeing it is, and how I seem to be allergic to syntax. I've had a
hard time explaining this to other people, and finally hit on a way
to do it. This essay is the result.
Before I get into this, some general comments on Lisp:
- If you're saying "Eww, how can you count all those parens?", You're Doing It Wrong. See scheme-style for how it actually works. Note that this objection is different from "I don't like all those parens", which is a perfectly legitimate personal choice, but see the rest of this essay.
- If you're saying "But Lisp is a toy language", you're simply incorrect.
Unless you want to make one of those two points, please feel free to
email me about this essay.
Moving on. I use an example out of Perl. It doesn't actually
matter what the example means, I don't think, except that it's
setting a sub-set of a complex data structure hanging off the object
"self".
Let's say we have:
$self->{'CONF'}->{'outerdatawindow'} = $outerdatawindow;
I have no idea how this would work in
CLOS off the top of my
head, but let's say it looks like this in CL:
(setf (outerdatawindow (CONF self)) outerdatawindow)
In both cases, I need to know:
- what type of thing self is as a data structure
- what the CONF slot is for, and what type of thing it holds
- what the outerdatawindow slot is for, and what type of thing it holds
In the CL case, I also need to know:
- what function application looks like
- that the CONF and outerdatawindow functions are slot accessor functions
- what setf does
It is important to know that the first one doesn't count to me:
no matter what language I'm in, I need to know what function
application looks like.
On top of that, the last one doesn't really count either: it's just
a library function, every language has them, and I'm always having
to look them up no matter what; that's just how my brain works.
So, in my head at least, only one additional item of information is
needed for CL that wouldn't be needed for any possible language.
In the perl case, I need to know:
- what = does
- what ; does
- what $ does in both places, which are in my mind quite different: retrieving a value feels different than retreiving a reference to a value. This is a problem with my mind rather than Perl, but that's what this whole essay is about anyways. I probably wouldn't have this problem if $$foo{'bar'} didn't work, but that just makes $ Incomprehensible Magic to me, so that every case of its use is a special case in my mind.
- What -> does
- What {...} does
- Whether the quotes are actually necessary or not
In any given programming situation, for every one of the points
listed above, the odds of my having to look something up are, at a
bare minimum, 1 in 10. That is, if I've been programming my ass off
in a language for days and I know this shit cold, for every chunk of
information like the ones above, there's still a 1 in 10 chance
I'll have forgotten it and have to look it up; I keep many
standard library reference windows open when I code, always, and
often many language reference windows open.
The less familiar a language is, the higher that 1 in 10 goes, of
course, but it never goes lower than that, and I think 1 in 10 is a
pretty generous estimate; the lower bound may be more like 1 in 5.
So every chunk added to a statement is another seperate-die-roll
chance that I have to look something up.
In Lisp basically all I need to know is function application and
what the functions do and what's in the variables. All inescapable.
Yes, lisp has special forms, but they're few and far between, and
I just treat them as functions anyways, because that's mostly
what they look like. There was a conversation whith kpreid where I
realized that I was fucking up because of that, but mostly it works.
New pieces of syntax (like $ or -> or whatever) cannot be handled in
this fashion.
I think the difference between me and other people is that for other
people, after a while the syntactical bits stop couting as data that
one might forget, and that's never true with me. They always count,
and I routinely have to look them up, and that's on top of
having to look up functions routinely. So every bit of syntax
gotten rid of makes me happy.
To give you a sense of scale here, I remember having to stop and
think about how to do function application whilst working with
Oz, when I was right in the thick of it.
Now, Oz's function application syntax is unusual, but I was doing at
least an hour in this language every single day, and it's not
that unusual. No question that this whole issue is a problem
with my brain; I just wanted to explain the problem once and for
all, since it's hard to convey to people.
It's worth noting that this may all be illusory. I feel that
syntax-heavy languages have more places-per-line-of-code that my
memory can fail me, but that may not actually be true. It may
simply be that looking up functions annoys me less, because it's
unavoidable. Even if that's all it is, being less annoyed is
valuable all by itself.