Friday, January 04, 2008
One more time into the breech with a speech impediment
I think I finally figured out why I don't like Lisp.
It has nothing to do with its (non-)syntax and the proliferation of parentheses. Sure, it can be annoying to the non-initiate, but one can get used to it. The first language I learned was Microsoft BASIC for the Tandy Color Computer, and if I can learn to not only program, but like something that looks like this:
0 'CODE TAKEN FROM THE RAINBOW M AGAZINE, VOL. IV, NO. 1 (AUGUST 1984), PAGE 78-'SOPWITH COCO' FL IES AGAIN! 1700 X=30+SIN(JB)*28:Y=160-COS(J B)*28:CIRCLE(FA,FB),1,0:CIRCLE(X ,Y),1,1:FA=X:FB=Y:RETURN 1710 IF D7=10 AND N(S)=0 THEN RE TURN ELSE LINE(30,160)-(SX,SY),P RESET:DRAW"C0;BM83,170;XA$(D7);B M-10,0;XA$(D6);BM-7,0;XA$(D5);C1 ;XA$(10);BM+7,0;XA$(10);BM+10,0; XA$(10);":LINE(128,40)-(IX,IY),P RESET:CIRCLE(162,92+GX),1,0,.1:D 7=10:D6=10:D5=10 1712 IF AZ<AL THEN AZ=0 1730 SCREEN1,0:RETURN 1740 F=INT(RB(S)*.5729):G=INT(RB (S)*5.729)-(10*F):I=INT(RB(S)*57 .29)-(100*F)-(10*G):DRAW"C0;BM66 ,151;XA$(FS);BM+7,0;XA$(GS);BM+7 ,0;XA$(IS);C1;XA$(I);BM-7,0;XA$( G);BM-7,0;XA$(F);":FS=F:GS=G:IS= I:JB=RB(S):GOTO 1700
After that, I think can deal with a few parentheses here and there.
My dislike of Lisp also has nothing to do with its seemingly archaic, or
even downright bizarre, function names like CAR
and
CDR
(which stand for “Contents of Address Register” and
“Contents of Decrement Register” respectively—no, seriously, they do!)
which to modern people have no relationship to what they actually do (return
the first element of a list, and a list minus the first element,
respectively). Non-English programmers have had to deal with programming
using seemingly arbitrary letter combinations for years.
Don't get me wrong—I'm fully thankful that I don't have to program in, say, a Swedish programming language:
(* Thanks to wlofie for translating the code from Pascal into Håstad *) medan not_done börja för x:= 1 till 5 gör börja om person^.age = 120 så too_old(person); om person^.age > 130 så gåtill person_should_be_dead; slut; slut;
But that doesn't mean I couldn't if I had to. I would just have
to learn that code blocks appear between the tokens BÖRJA
and SLUT
and that we don't have IF THEN
statements, but OM SÅ
statements.
So it's not that Lisp contains nonsensical function names like
CAR
, CDR
and TERPRI
(like C doesn't
have weirdly-named functions like strspn()
and
sbrk()
) that make me dislike the language.
This, and the syntax, are shallow problems, easy to deal with in various ways. No, the reasons I hate Lisp are deeper than that.
I'm the compiler when using Lisp.
Sure, I can let SETF
Do The Right Thing™ in updating a
variable instead of using SET
, SETQ
or
RPLACA
(for instance), yet there are still areas of
Lisp (okay, Common Lisp if you want to be pedantic) where I get to micromanage the code.
Arrays, for instance, can have up to seven dimensions (or more, depending upon the implementation), but arrays of a single dimension are considered “vectors” and have different functions to access elements, but there are also two special cases of vectors, bit vectors and strings, and each of those have special access functions. That's at least four different methods of accessing arrays.
You also have a slew of functions that manipulate and modify lists in
place, like NCONC
, NREVERSE
, NUNION
and DELETE
, but there are an equal (EQ
?
EQL
? EQUALP
?) number that generate a new list:
APPEND
, REVERSE
, UNION
and
REMOVE
(ah, if only there were some consistency in the function
names). It'd be nice if I didn't have to deal with such details and let the
compiler figure it out for me (much like manual memory allocation, which
Lisp does away with because it's garbage collected, but then, if that's so,
why does Paul
Graham include a section about avoiding garbage collection in his book
ANSI
Common Lisp?).
Oh, and then there's LET
and LET*
. Both let
you declare a bunch of variables sorry, bind a bunch of
variables (there's apparently a subtle distinction between setting a
variable, and binding a variable, but from where I'm at, I can't tell the
difference), but one does it “sequentially” and the other does it “in
parallel” (which has implications about using previous bindings to bind
later bindings—hey, I didn't design this language) and why the
Lisp system can't figure out which one to use is beyond my ken.
And reading up on the subtle differences between PROG
,
PROG*
PROGN
, PROG1
,
PROG2
and PROGV
is like reading Medieval monastic
tomes on the differences between the care and feeding of Seraphim, Cherubim,
Ophanim and Erelim.
Gee, if I wanted to micromanage code at that level, I'd be writing in Assembly. And I wouldn't have to deal with all the parentheses around each statment either.
I still like the idea of Lisp, and I think as a target language, it makes sense. But when I write a program, I want to solve a particular problem, not play compiler, unless, of course, I'm writing a compiler. Lisp proponents say that's a feature, because you are supposed to write a DSL in Lisp that succinctly solves the problem you're trying to solve with a program, but we already have a bazillion different computers langauges; do we really need a bazillion more one-off computer languages? (my frightening minor epiphany is also related to this, as computer languages are primarily communication between programmers and may help to explain why a language like Java is so popular in large companies, and Lisp isn't)
Update later today
Oh, one more thing I forgot …