The myth of the Lisp genius
johndcook.com
johndcook.com
* The Structure and Interpretation of Computer Programs
* Paradigms of Artificial Intelligence
* Art of the Metaobject Protocol
* The Schemer Series (Little, Seasoned, Reasoned)
* Essentials of Programming Languages
* Lisp in Small Pieces
Few programming languages have such an abundance of truly deep gems. One has to wonder if there's a reason. > One has to wonder if there's a reason.
This particular type of argument keeps coming up in Lisp-related discussions, but I seriously doubt its validity.Lisp is overrepresented in classic texts on computer science, yes. But that doesn't allow you to jump to the conclusion that, hence, it's the best possible language or even a very good one for all things ever. As far as I'm concerned, cultural heritage (with Lisp having a long academic tradition) and syntactic/semantic transparency are far more likely explanations. SICP, for instance, doesn't employ Scheme because it is an apt language choice for industry projects or general programming but because it's a very slim, non-obtrusive language that virtually disappears behind the concept that's under scrutiny. Watch the lectures: it takes them about 10 minutes to explain all of Scheme's syntax. That's great, because when elucidating CS concepts, syntax doesn't matter at all.
However, being particularly well-suited for explanatory/conceptual purposes does not make Lisp an ideal language for everything. Not even necessarily for many things.
I don't consider Art of the Metaobject Protocol to be introductory or conceptual. Alan Kay considered it one of the only interesting books published on object oriented programming for a decade! Lisp in Small Pieces is also not particularly introductory or conceptual - that's a hardcore compiler optimization text.
I'd love to hear of a domain where a Lisp dialect isn't as well suited as anything else.
It's good to know lexing & parsing techniques, but upfront? That's like writing a TCP/IP stack before you can do CGI scripting.
The same is equally true with many other languages, nowadays; one can use Erlang tuples, JSON, ML/Haskell type constructors, Lua tables, Python dicts & lists, etc. instead of s-expressions, but Lisp had a several-decade head start, so it (and to a lesser extent, ML) has a disproportionately large share of excellent compiler literature.
Cost is one. These books would be ten times as big had they used Java examples. ;-)
Seriously now: Lisp has a very unobtrusive syntax. It seems a good fit for teaching a lot of concepts.
http://www.google.com/search?q=unobtrusive
PS: It was rather a tongue in cheek comment, implicating the Lispy roots of Javascript, and the increasing popularity of it among programmers. I would bet that interest towards functional programming or Lisps will increase with such movements, and the myth might in that sense be invalid in a near future.
Nitpicking here, but that is actually graceful degradation/progressive enhancement.
Unobtrusive JavaScript is about writing JavaScript code that plays well with others. The example you gave of not having inline JavaScript in your presentation layer (HTML) is one example. Not writing JS code in the global namespace and avoiding monkey-patching built-in objects are other examples.
* C Programming Language - by K&R
* The Indispensable Guide to C with Engineering Applications - by Paul Davies
* C Interfaces and Implementations - by David Hanson
* A Retargetable C Compiler: Design and Implementation - by David Hanson
* Graphics Programming Black Book - by Abrash with lots of Quake goodiesLisp has a major advantage over C for symbolic programming; it's really not C's strong point.
I've read K&R and parts of the Hanson books. They're all excellent but less interesting than most of the Lisp books above, SICP and PAIP in particular.
Allen's Anatomy of Lisp is the best introduction to language formal semantics I've seen. Too bad it's out of print, but it is a bit dated by now.
Now if you're actually talking about the craft of programming, the two best books ever are Graham's On Lisp and Hoyte's Let Over Lambda. Lisp macros are the best programming tool available today, and those are the only books that go in-depth on macros.
Lisp has some unique features. Some people like them, and feel more productive using them. Other people don't, and prefer other languages. Can we move on now?
Also, Lisp has been around for a while - it's been a couple decades ahead of its time for fifty years! Much great research literature has come out of its culture.
Besides, Haskell certainly gets plenty of "blog posts by people who almost certainly don't use it on a day to day basis". Erlang's culture seems to favor ugly pragmatism over "avoiding success at all costs", though.
If we want to fix Hacker News, we need a way to stop these sorts of karmic feedback loops from setting themselves up, because they are echo chambers.
(Also, it'd be nice if bloggers didn't measure post success by traffic, but we all know that isn't going to change.)
I'm only concerned with how that perception of success affects HN. Presently, it's too easy for bloggers to choose to discuss A Most Excellent Technology in the hopes of making the front page. The actual writing may not make any points beyond, "vim changed my life!" but, still, it's put on the front page by the bikeshedding committee, thus perpetuating the feedback loop. You may argue that certain tools have a favored status within certain groups, and that is fine -- I'd prefer if people were picky about their tools. But the standard must be raised on bikeshedding articles beyond mere sentiments of "I like this technology." There needs to be an intellectual gain made from the blog post, not simply an opinion being expressed.
Otherwise, HN risks becoming like every other social news site, where people upvote the articles they want to see to the point of creating more noise than signal. We are still have quite a ways to go before we're there, but the recurrence of topics is a bit troubling.
This has been discussed many times (recently, somebody attributed a significant difference in productivity among programmers to... the ability to touch type).
Anyway, why different tools could in principle not be able to generate wildly different productivity outcomes?
"If you only have a hammer" can be reversed: if you don't have a hammer, then planting nails becomes incredibly difficult and takes a great amount of time (and ingenuity). A (not too practical-oriented) friend of mine once called me because he had spent an hour and a half trying to screw together a simple Ikea bookshelf (where the documentation said it could be done in less than 10 minutes). Turned out he was trying to screw the big bolts with pliers, and that's really hard.
You've had fifty years, ffs, and what have you got to show for it. Some furry guy who wrote emacs 40 years ago? Why is it that the web was built with php and perl? Why my desktop apps are still mostly written in C? You've had you're arse handed to you on a platter by every language (just about) since fortran. Stop waxing lyrical about how great lisp it, and get out there and prove it, dammit.
Lisp may be a great language, but it's proponents don't seem all that great at getting stuff done
Put another way - in 10 years if HTTP/Javascript continue on the same path people could arguably say the same thing - "some furry guy wrote Linux in C, but what has C done for the world recently? All the cool apps being built recently are in Javascript/HTML on the frontend and Python/Ruby on the backend"
C was invented as a replacement for assembler to portably write operating systems and applications in a slightly higher-level notation.
Lisp was invented as a tool for computing with symbols (computer algebra, theorem prover, game playing, natural language processing, expert systems, knowledge representation, ...).
Implementation details largely determine how fast a given program will run.
C makes it rather easy to predict how fast a piece of code will run, and what its bottlenecks will be. Lisp makes that rather hard.
Given that there are always programs that need to be as fast as possible even with hand-optimized algorithms running on top-of-the-line hardware, C will win for many applications that have even moderate performance requirements.
Also, current mainstream operating-systems favor C and C++, if only implicitly.
For speed, I use profilers, because I'm still surprised at where the code is spending its time, even after 20 years of programming in C.
I'm beginning to think that Lisp appeals to programmers that like programing in raw Abstract Syntax Trees which is a small subset of all programmers.
Try using Google? CL-HTTP has been around since 1994, Symbolics came out with the second ever commercial 3d animation package a few months after Wavefront in 1983 or 1984, first HDTV-capable digital editing systems in 1989 for Japan, etc. Most of the "hot" parallel processing stuff of today (Map/Reduce, futures, actors) was done in Lisp at MIT in the early 80s.
Just because you're too lazy to find out whether something exists doesn't mean it's not there.
The original article seems to base this on the flawed assumption talent and choice of tools are not related.
edit: should have phrased the above as "this statement seems based". It's not the entire article.
The article does say they could be related:
"Another possibility is that super-programmers are attracted to Lisp."
That would be a strong correlation. However, the article is about causality, though. If the truth is that
Programming talent -> Choose Lisp
Then it is not necessarily the case that
Choose Lisp -> Programming talent
Anyway, as was pointed out elsewhere, someone can write a web CRUD in Rails in 1% of the time it would take to write it in C with Apache modules (or ISAPI DLLs). Choosing the wrong tool can have disproportionate effects.
Having a large tool set is one of the hallmarks of the great programmer.
One example off the top of my head: a friend of mine was struggling for a week to deliver a simple J2ME (it was 2002 or 2003) app using Eclipse. I directed him towards NetBeans. The product was ready that same afternoon. The IDE support in NetBeans was so complete his job was more a fill-in-the-blanks than anything else.
Before I started I only knew Basic and a little Fortran but the project I worked on required me to learn these two new languages, C for the low-level code that interfaced to a graphics tablet and the display driver, Lisp for the code that did some analysis on the lines and geometric shape drawn by the user.
I remember that on days I was working on the Lisp code I was happy and things seemed in harmony. On C days I often ended the day worried and headachy.
However, I couldn't have written the C portion in Lisp and writing the Lisp portion in C seemed unreasonable at the time as well.
What I take from the experience is that, to some extent, Lisp seems so much more productive is that it's typically chosen for programming tasks that don't deal with the ugliness and "hardness" of things like drivers or other low-level code. Not sure about GUIs but that's another area where programming becomes tedious and unfun, at least for me.
So, I don't think that Lisp is chosen for easier tasks but definitely for tasks where a solid grounding in CS and an ability to think abstractly is more important and there's some level of self-selection going on in those areas.
When I have problems with UIs it's because there's a lack of separation in structure, design, and scripting that you get with HTML+JS or MXML+ActionScript which both make UI dev really easy and fun. In contrast, I think Swing, AWT, WxWidgets, Tkinter, GTK, Windows API, .NET, and even Qt make graphics programming a pain in the neck (some more than others). But once you get toward a more web-approach of UI, s-expressions are a perfectly fine way of representing XML too. Tags are functions, Perl realized that as well.
My own experience with writing low level software is that without a good support library you're going to be doing assembly that may be painful depending on the microcontroller and what you're interfacing with. (ARM stuff is pretty good.) If there are good bindings for higher languages like Lisp, programming in Lisp becomes nice again. PyGame is a great example of porting a (in my view) somewhat ugly C library that is SDL and making it nice and neat to use in the higher level Python. I know a team in Colorado who are using Flex to build a multi-touch application on a USB tablet.
In the face of no good library though, C is definitely a great choice and it's useful for augmenting assembly. If I want to worry about memory and pointers, C's my goto language.
There are just genius programmers.
Lisp just happens to be a pretty good language.
The two are quite orthogonal to one another.
If you agree (as I do) that there are differences in "power" of language, I would expect that genius programmers would be far more likely than average to choose a language of above-average power.
Thought experiment: How many genius programmers do you know that use VB6 by choice?
And I definitely do not know of anyone who programs in VB6.
However, I am some what familiar with John Carmack. I would consider him a genius programmer. Yet he uses C++ almost exclusively. You would have to ask him if he thinks it's the most powerful language available to him. However, I would hazard a guess that his choice of C++ was incidental (http://rome.ro/smf/index.php?topic=3086.0) -- it just happened to be the de facto lingua franca for developing graphics intensive video games.
By orhtogonality I mean to imply that attributes of one are not affected by the other. Lisp is and will continue to be a powerful language with or without genius programmers using it. In fact, if genius programmers are exceptional and rare as we say then I would imagine Lisp has developed over the last fifty years almost exclusively without the help of geniuses. Similarily, not all geniuses will think to use Lisp; yet they will still be exceptional programmers and produce exceptional software.
Update: Included link to thread about an alleged response from Carmack to an email asking about C++. Apparently he uses it and has used it since Doom3.
Point taken about the orthogonality of language choice and programming ability. There are great programmers who use Lisp, there are great programmers (like Mr Carmack) who use C and then there are great programmers like Richard Stallman who can write Emacs in Lisp and then write GCC in C (albeit with a Lispy flavour).
http://www.google.com/search?q=carmack+prefers+direct3d
:)
First, it is an issue of social dynamics. Very intelligent people frequently develop means by which they congregate without the less intelligent. Elite academic institutions facilitate this. The corporate world does not. As far as I can tell, lisp was the anti-blub when there was only blub, which allowed people to distinguish themselves from their peers -- a bit like going to Mensa meetings. This need seems to be less pronounced in the younger generation since there are other distinguishing languages in fairly common use.
Second, there is current research in neurobiology that indicates that the evolution of the brain (perhaps responding to its environment) has a naturally recursive structure and there is a growing field in the study of religion and philosophy that indicates that the growth of many systems has a fractal structure. In fact, Mandelbrot commented on this himself in response to Lovejoy's Great Chain of Being, although he never applied it to the correlative systems of the East, nor the syncretist projects of the Renaissance. These are frequently associated with genius for good reason. I suspect Lisp is popular because of how it "clicks" with something mentally.
Third, it is not quite clear how any of this relates back to programming as a craft. Philosophers can create their own discrete systems. Mathematicians, even if they don't deal well with other people, are, at least ostensibly, dealing with reality. Lispers, on the other hand, frequently must deal with real products for real people. Realistically this means that products must have significant scope, which almost invariably means more than one person working on them (actually products are rarely brilliant, though inventions may be). Which is to say, the "inventive" aspect, which may be contained and individual, is likely distinct from the practical aspect, which is collective. Obviously certain features (e.g. static typing, immediate comprehensibility when viewing method/class names, etc.) would seem to be preferable for large collaborative projects.
In conclusion, although it is said "real artists ship," it is often the case (e.g. Van Gogh, Schopenhauer) that real artists languish unacknowledged, their brilliance unappreciated in their own time. Art, when pursued for its own sake, rarely can deal with practical considerations -- which may good for the increase of knowledge generally or the field of computer science, but bad for business (insofar as business is making money right now).
My life as a programmer and hardware designer started when I hand-built (wire wrapped) my first 8080-based computer way-back-when. Coding was done typing in hex codes into a hexadecimal keypad. Pretty amazing what you could write that way. Wanting more, I wrote a simple version of Forth. Wow! The productivity gain was impressive. Meanwhile, in College, we had to take FORTRAN. I hated it for some reason. Then my Physics professor offered an alternative: If you signed-up for his APL class you could get equivalent credit. Out went FORTRAN, in with APL. I would not learn C until three years later.
The fact that my real programming life started with exposure to the extremes represented by hand-coded hex, Forth and APL probably made me think very differently once I got to C and other languages. APL allows you to think and translate those thoughts and ideas to computer instructions with very little to distract you. The process of programming in C-like languages can be very mechanism oriented rather than problem oriented. By this I mean that you spend a log of time working on how to get the mechanics of the thing to work rather than focusing on the problem domain.
I learned and programmed in Lisp extensively later in life. It was the AutoCAD version of Lisp. I wrote all sort of tools and utilities for AutoCAD and can say that I enjoyed using the language. In terms of productivity and the ability to quickly express ideas, I think it did pretty well. Is it the realm of geniuses? Nothing is.
These lisp geniuses are just programmer that grew up in a time where lisp was often used. So the are "just" programming geniuses.
Lisp does not make medicore programmers 10x better. Its just a very good programming language.
P.S. Back then it did make you much more productive because all other languages where way behind not like knowdays.
No language will. OTOH, no mediocre programmer will grok Lisp.
[1] http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussma...
[2] http://ocw.mit.edu/courses/electrical-engineering-and-comput...
I'd suggest you to give Scheme a try, its more minimal than Common Lisp and IMHO simpler to start off with. All you have to keep in mind is that syntax in Scheme is both uniform and minimal. What you also need to remember is that Scheme is probably unlike any other language you have encountered (The Algol family), so you must not try to program in Scheme the way you do in say C or Pascal.
* The former uses Scheme, the latter uses Common Lisp. While you could get caught up in the lengthy debate over which (if either) is superior, it's probably a better to just pick one and learn the basics. Then, you'll be able to make an informed decision later.
I don't recall _The Little Schemer_ being any kind of gentle introduction.
Perhaps you're thinking of SICP?
If you like the format, _The Little MLer_ is one of the best intros I've seen to ML-style type systems.
In other words: the beginning of the learning curves of Lisp vs. other languages are about the same. Lisp's curve just continues after that.
Other languages force you into specific toolsets (objects, functions, etc.) and thwart pure expression of the problem.
> Other languages force you into specific toolsets
> (objects, functions, etc.) and thwart pure expression of
> the problem.
Pure expression and complete malleability are decidedly non-intrinsic goods. Sure, you're free to reshape your language according to the requirements of the task at hand, but that process takes tremendous amounts of experience and care and foresight. If you lack these qualities, Lisp isn't going to get you anywhere. Even worse: it may end up being counterproductive.Graham made such successful use of Lisp because he was a highly competent engineer, and thoroughly familiar with CLisp. Firing up SBCL doesn't grant you these abilities qua choice of language. So I'm glad that some people still offer counterpoints to the Lisp cargo cult around here.
(Yes, of course there are exceptions. But I think in general that having this freedom will make you consider how to use it, which will make you consider alternate ways to code the same thing, which is ultimately how you learn.)
Knuth himself said he didn't think he could have written TeX without his literate programming tools, right? Which fits the pattern of Lispers extolling metaprogramming, though without their built-in support.
(Despite which, I don't in fact think Lisp makes you a genius, or even significantly better than with other popular languages -- though it was a different story back in the 80s when I learned it.)
I'm a lisp novice, but doesn't it impose functional composition? And isn't that some mighty structure?
You can write Lisp code that's as imperative as Java. Whether this is good or bad is left up to the reader.
CLisp is a multi-paradigm language. You can use it in a OOP or a functional style. You can even use its OO features in a functional way and viceversa. E.g Objects are poor's people closures. [1]
(It's common misconception, and a confusing name)
http://www.lispworks.com/documentation/HyperSpec/Body/s_go.h...
http://clhs.lisp.se/Body/s_tagbod.htm
http://www.lispworks.com/documentation/HyperSpec/Body/s_thro...
I doubt it would be possible to become a superprogrammer by coding Java because you would be too busy trying to comply with all the specifications.
But maybe a better question would be how often you would be better mixing those types of development in a single program.
Strong, static typing is really great. It may not be appropriate to every problem, but it saves a lot of time in the long run. Just as every programmer ought to spend a year in Lisp, every programmer should spend a year in a Hindley-Milner static-typing language.
My feeling about dynamic typing is that it test-drives really well, but it's not great for a 6,000-mile road trip. Lisp definitely beats Haskell and Ocaml in the former regard, and for small projects, I don't think there's any language that can be faster. On the other hand, for a large project with 5 developers, experience has led me to conclude that I'd much rather be using a statically-typed language.
Another problem languages like Ocaml and Haskell have is this: most programmers have a very predictable trajectory through increasingly more powerful languages: C++, then Java (garbage collection), then Python or Ruby (more abstraction and power), then Lisp, which has the aura of being the pinnacle of languages, one that removes all the accidental complexity and leaves programmers able to tackle the intrinsic complexity of the problem. Strong, static typing seems like a step backward-- some seatbelt that was thrown away at the Java-to-Python transition. It's not, and Hindley-Milner type inference ensures that the static typing doesn't even eat up much developer time, but the benefits of static typing don't appear until you work on a larger project where debugging and testing become major concerns. The difference between a 40% and an 80% debug/test overhead is enormous, but aren't going to show up on a 500-line project.
Strong static typing is an awesome tool that the language forces you to use. Lispers don't like being "forced" to do anything. However, on a project of sufficient size, the relatively minor drawbacks of static typing are more than paid off by the reduced test/debug overhead.
* Strong Static Type Checking for Functional Common Lisp
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.6958
* Qi/Shen http://en.wikipedia.org/wiki/Qi_(programming_language)
* Typed Racket
I think what is at issue is that Lispers aren't willing to have static-typing completely baked in. Haskell's various type system extensions show that people are still working hard to figure out how to get the expressive benefits of generic programming in a strongly typed language.Personally, I'm particularly interested in supporting a la carte type systems for Clojure and have started work towards that end.
I've seen virtually no one take this trajectory. Half of the Lisp programmers I know had Lisp as one of their first languages (MIT or Berkeley alum). Most C++ devs that went on to Java or C# did NOT go to Ruby or Python. Most C# devs would consider that a step backwards unless you were using a specific framework for a specific task, e.g., Rails.
The only thing I do tend to agree with is that Ruby/Python devs seem to have Lisp envy. But very few others classes of developers do.
We also learn Scheme as our first language at Indiana University computer science@
(defun turn-cat-into-dog (cat-or-nil)
...)
From such a definition, it is clear that this is f:[cat,nil]→dog, but the compiler isn't required to help you if you pass in a 4. This may cause some run time overhead in non-optimized code, but from my experience, is rarely a source of bugs. Has your experience been different?Perhaps then, the biggest benefit of the type system is that it forces the programmer towards expressive code?
(defmethod turn-cat-into-dog ((a-cat cat)) ...)
(defmethod turn-cat-into-dof ((a-cat null)) ...)
or declarations in the mid 80s of the last century: (defun turn-cat-into-dog (thing)
(declare (type (or cat null) thing))
...)But for a 6000-mile road trip? Are you kidding? That's when Lisp shines brightest because of macros. If you get 3 or 4 Lisp programmers together and none of them has ADD (on second thought, this may not be possible) you'll get that project done much faster and better than you would otherwise. Because of functional programming, bugs will be easy to deal with, too.
I would speculate that, with regard to development time as a function of complexity, Lisp is O(n) whereas other languages are O(n^2) or worse.
It's perfectly okay to use Lisp just like you would use any other language.
It's better designed and more consistent than most others, and has good implementations. It makes sense to use Lisp as just a regular language without any wizardry.