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 …
One last time? Okay, make that two last times …
This tutorial will show how a blog can easily be implemented in Common Lisp, using a few frameworks. Installing these frameworks is not covered, and neither are details on getting Common Lisp implementation up and running.
Implementing a blog in Common Lisp: Part 1
Heh. I liked that bit about how a blog can easily be implemented in Common Lisp, but actually avoids the hard part, getting a Common Lisp implementation installed, which brings up one other thing I don't like about Lisp—it doesn't play well with others and wants to be the entire environment (Forth has the same problem, as well as Smalltalk).
The other frameworks that need to be installed, along with Common Lisp? One's a webserver, which has this to say about implementations it runs on:
Hunchentoot talks with its front-end or with the client over TCP/IP sockets and uses multiprocessing to handle several requests at the same time. Therefore, it cannot be implemented completely in por table Common Lisp. It currently works with LispWorks (which is the main development and testing platform), CMUCL (with MP support), SBCL, (with Unicode and thread support), OpenMCL, and Allegro Common Lisp.
HUNCHENTOOT—The Common Lisp web server formerly known as TBNL
And if you happen to have a Common Lisp implemention not listed here,
well, have fun storming the castle porting the code (yes, it's a
cheap shot, but it's another point against Lisp in that it tends to lack
support for things that are taken for granted today that weren't some twenty-
odd years ago, like networking).
Oh, and forget CMUCL, since the third framework, Elephant, isn't supported (and the one Common Lisp implemention I have installed, GNU Common Lisp, isn't listed as supported by any of the frameworks—sigh).