Hacker News new | past | comments | ask | show | jobs | submit login
Learn Lisp the Hard Way (learnlispthehardway.org)
190 points by wes-exp on July 10, 2014 | hide | past | favorite | 141 comments



Wow. The response on here has been amazing---yes, the criticism too. I was really shocked last night with the spike in traffic from Reddit, but I had no idea what to make of getting to the front page of Hacker News. TBH, I'm feeling pretty overwhelmed about the whole thing.

Just to put my two cents in, as a general reply to a lot of comments here... this is a very, very early draft in progress, and I didn't expect anyone to pay attention to this project, let alone post it everywhere. It needs a lot of work, particularly in toning down the Lisp Evangelism, and staying true to the methodology without accidentally parroting Zed Shaw's voice.

Zed Shaw: it means a lot to me to get your perspective here. Yes, you and your series ultra-inspired me. I've wanted to write a book on Lisp for a long time, but it wasn't until I was pointed to your series that I felt like I could give Lisp the perspective it was missing. I'll make a point of editing the Preface more carefully---everything that's up there so far, I wrote off the top of my head with very little editing, so I guess in following your method and format I accidentally used some of your words as well.

Thanks everyone!


I really hope Colin finishes this as I've always thought Lisp would be a better beginner language if there was a book like mine for it. You've either got "The Little Schemer" series, which is annoyingly written for little kids but close to the style, or you have giant academic tomes that only hard core geeks would bother reading. A "trainer" book like mine would definitely solve this gap.

The intro is a little bit copied but it's fine since he is keeping to the idea and the "rules" I have, but could be nicer if it was in his own voice more. Who knows, maybe he does write like me a lot or he's just ultra inspired.

The big reason I say people should use their own words, apart from copyright, is that if you're writing one of these books for a programming language you love then your words will express that better. You'll say things that come from your community and culture, and you'll give away a sense of what you like about that language. When people copy what I say the prose comes out obviously not by them and not for that language.

Anyway, this is pretty cool and I hope he works on it some more.


http://landoflisp.com/ is a nicely informal book on learning lisp that is easy to get into. Pretty sure I've seen it highlighted here a few times.


I like Land of Lisp, and I own the ebook+paperback, but I don't think that it's well suited to beginning programmers. I think the "let's make a game" approach actually works better for programmers who are coming from a different language and trying to understand concept translations, rather than novel concepts themselves.

edit : I can't reply to you, but re-read what I said. I am making the point that I believe Land of Lisp to be for people coming from other languages, whereas I think that "learn X the hard way" is better for people new to programming altogether.

The parent of my reply is pointing out to zedshaw that "Land of Lisp" is a good beginners book. I am adding that it's my opinion that it's a good "beginner at lisp" book, and not an overall "good-for-beginner-programmers" book.


I see your point, though I'm not sure I agree. I do think you have to have an interest in games. At the least, you can't be turned off by them.

Though, I have absolutely nothing to back up my thought on this. Would be curious to see any studies or other such on these thoughts.

Also, apologies for the edit. My main thought was more for the informal nature of Land of Lisp. That is, it isn't "high theory" written for experts, nor is it written for kids.


Uh, the land of lisp has the let's make a game approach as well. I'm not sure I understand what aspect you're talking about.


I'm not sure why my comment was downvoted, but having read and gone through over half of the Land of Lisp personally, I can factually state that it does indeed have multiple game exercises involved.

To quote from the book page:

  Along the way you’ll create (and play) games like Wizard
  Adventure, a text adventure with a whiskey-soaked twist,
  and Grand Theft Wumpus, the most violent version of Hunt
  the Wumpus the world has ever seen. 
http://www.nostarch.com/lisp.htm#toc

If someone would like to argue that it does not have a "game approach", I would like to see the specific reasoning as to why.


I don't think The Little Schemer is intended for young kids. The preface says

> The Little LISPer is based on lecture notes from a two-week ``quickie'' introduction to Lisp for students with no previous programming experience and an admitted dislike for anything quantitative. Many of these students were preparing for careers in public affairs.

I don't know exactly what that means, but it sounds university-level?


I actually liked the Little Schemer a lot, specifically the way it's laid out with just questions in one column and answers in another (it helped establish a rhythm that made it nice to go through); but I did find the tone a little "young".

All the examples are about food, and there's cartoons littered throughout. There's a bunch of books that seem to be of that tone (Learn you a Haskell, Land of Lisp, Realm of Racket, Learn You Some Erlang), and I found myself instinctively recoiling from all of them (I haven't read the Erlang book, but it seems very much in that style).

I think it's important to have lots of different styles of books for learning a language, because I think different people respond better to different approaches, but selfishly, I wish every language had an equivalent to "ANSI Common Lisp" (by this site's benefactor emeritus) and Real World Haskell. I am also a big fan of the way Zed chose to lay out his books.


Practical Common Lisp is a very good introduction. It's very much targeted at competant non-academics.


"The mysterious force driving human society towards the technological singularity, true and total unification of human with technology, also seems to be shaping all programming languages into Lisp, and all computers into Lisp Machines. Lisp, after all, can do everything, and do it every way; that Lisp is not already the de-facto programming language is just a reflection of the state of the world as a whole—only a very small percentage of the population are excited for the technological singularity, but the singularity is coming no matter how much people complain. One way or another, every programmer is going to end up being a Lisper, because every programming language continues to adopt features and syntax from Lisp, one piece at a time. It is in every programmer's interest to master Lisp now, before the world at large realizes how essential Lisp will become over the next two decades."

The title is right, IMO. This is a difficult way to learn Lisp. I'm feeling the burn already.


That burn isn't from Lisp, though. It's from this author's tying Lisp to a somewhat far-out world view - one that doesn't actually relate to Lisp very much.


I can't bag on a free book, one created as a labor of love...but if I had to make a suggestion, it would be to tone things down a bit:

http://learnlispthehardway.org/book/preface/

> The biggest secret to Lisp is that it is actually the simplest programming language ever created—and that, coupled with its expressiveness and elegance, is why it is favored exclusively by the best programmers in the world.

As a Lisp novice...my thoughts are, "Really?" to both of those assertions. Because the natural follow up is..."So if all the best programmers use it, whatever "best" means, why is it a language that seems so rare in everyday use?".

No need to assert things you can't actually prove or show...it just builds up skepticism before the reader even starts learning. Just talk about the language at hand, or at the very least, do a quick Rosetta Stone comparison of Lisp doing something much more simply than Python/Ruby/PHP, and that's all you need to write in the intro.


An easily overlooked, seemingly forgotten book that is great for newbies is Stuart Shapiro's _Common Lisp: An Interactive Approach_.

I stumbled into Lisp some fourteen years ago when a hard copy of the book landed my way.

The book is now freely available in electronic form (and has been for years): http://www.cse.buffalo.edu/~shapiro/Commonlisp/


That was my first Lisp book 30 years ago already.


I have nothing against Lisp, but...

>Is Lisp as hard as people say it is?

>No. Lisp is actually the simplest programming language, and has no syntactic cruft.

I always see this used when claiming certain languages are easy to grasp. "It's not complex at all! The syntax is incredibly simple!" x86 assembly also has very simple syntax but it's not too easy for beginners to write in, beyond very simple and small programs.


The syntax of assembly language isn't combinative, beyond simple catenation. You're not creating trees, just a "link sausage" (or, a graph, more accurately) of instructions. Lisp syntax expresses tree structures; it actually does what other languages achieve with complicated syntax. They have parsers which build trees out of nodes. Those trees can be written in a Lisp-like way. E.g. a C declaration might be turned, by a C compiler, into (declare specifiers-qualifiers declarators), where specifiers-qualifiers might look like (const int) and declarator might be (a (pointer (array 3))), giving us (declare (const int) ((a (pointer (array 3)) (b (pointer (function (a int) (b int))))) for the surface syntax "const int (a)[3], (b)(int, int)". It's not just that the syntax is simple, but that it can capture the structure of programming (and other) languages while remaining simple.


You still end up with myriad syntax rules; why (a int) and not (int a)? Why not any inversion or isomorphic transformation?


It really is. That's why they used Scheme for the Structure and Interpretation of Computer Programs (SICP). If you look closely at it, you'll notice that they don't actually spend a lot of time teaching you anything about language itself, just the processes.


From the FAQ: "Is Lisp as hard as people say it is?

No. Lisp is actually the simplest programming language, and has no syntactic cruft. While it wasn't designed to be “easy to learn” like Swift, Python, Ruby, or Basic, there is less overall to learn and you will be writing real, useful programs in Lisp sooner than you could with other languages."

Is it necessary to put strong subjective statements that have no supporting links or proof? Also, are you seriously saying that /Common/ Lisp is the simplest language? (from FAQ: "Lisp — the friendly nickname for Common Lisp")


Syntax wise, it is probably the simplest language as long as you don't include Turing tarpits.

Of course, simple syntax is nice, but it doesn't actually get you very far by itself.


Ok i started this. How long before I can condescend to the rest of you barbarian peons?

But seriously - i've been wanting to learn a lisp for a while now and this seems like an accessible way to go about it.



Restarted the server, you should now be able to see the next three exercises... although there's very little to be seen in them so far.


"Is Lisp as hard as people say it is?

No. Lisp is actually the simplest programming language, and has no syntactic cruft. While it wasn't designed to be “easy to learn” like Swift, Python, Ruby, or Basic, there is less overall to learn and you will be writing real, useful programs in Lisp sooner than you could with other languages."

It's like a never-ending stream of lies, every word being a little more absurd than the last...


Just because Lisp looks foreign doesn't mean that it's harder. The syntax is different, but it is also very simple. If this were untrue, Scheme wouldn't have survived as a teaching language all these years.


At first I thought the Dr. Scheme (now Dr. Racket) program was crazy to choose a Lisp like language. Then as I learned more languages I realized how much easier it is to think about programming since I started out with Dr. Scheme.

How To Design Programs for those interested in picking up Scheme: http://htdp.org/


> The biggest secret to Lisp is that it is actually the simplest programming language ever created—and that, coupled with its expressiveness and elegance, is why it is favored exclusively by the best programmers in the world.

But is it?


Sounds like you just got told you're not one of the best programmers in the world and are still in shock about it.


Simple syntax does not a simple programming language make.


Simple syntax "Hello world!"

  ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.


Sounds to me like the GP is in shock about such an over-the-top claim. And it sounds like you're trying to pretend to read his/her statement for something other than what it is.


I'm not one of the best programmers in the world, no shock there.

I'm learning and enjoying clojure, though!


The DSL for string formatting certainly doesn't look simple.

  (format t "~{~@(~A~)~^ ~}, because ~{~A~^ ~} is easier!" llthw (cddr llthw))


It's complex because it's powerful. ~A is the most common directive; it simply prints an object. '~{...~}' (braces) iterates over a list, applying the directives within it to the list elements. Within that construct, '~^' exits if the last element of the list has been consumed; it's used here to keep the separating space from being printed after the last element. '~@(...~)' (parens) capitalizes words in the output of the directives it contains, downcasing the non-initial character of each word.

So there's a lot more power here than in 'printf' control strings. If you find the more exotic notation unintuitive -- and you certainly wouldn't be alone -- you don't have to use it.


It's just disingenuous to say that LISP has extremely simple syntax and then show the DSL for format, which is anything but LISPy or simple.


It's disingenuous to claim a DSL is part of the language syntax. E.g. I would not consider the regex formatting specification as Python syntax. I mean, if we follow that line of thought, it's like saying Jinja is Python syntax.


If you're going to need to teach it for students to read and write programs in the wild than it's irrelevant whether it's 'part of the language syntax' or the ecosystem's syntax. 'Loop' is another one.

Lisp as an idea has a simple syntax but Common Lisp isn't even close to that platonic ideal.


I don't know if it's disingenuous, but I'll agree that it may not be good marketing :-)


I am only recently a lisp user but honestly, how is the format function far from:

printf("something %s then %d finally %f!", "asd", 1, 1.2)

As mentioned, there is a loop built into format. Since lisp also has a (list) function eg: (list 'a 'b 'c 1) I still don't see an argument beyond familiarity with the C style printf syntax for why format is bad/unreadable.


There is a loop embedded in the lisp version.


I do not understant it, but with changing ~ with % I can imagine what it does.


Simplicity of syntax does not translate to ease of use. Or else we'd all be programming in one-instruction Turing Tarpit.


That's right; Lisp's syntax is not only simple; it is simple while retaining the power to combines together and express any syntax tree. If you put on special Lisp goggles, you can see S-expressions inside the syntaxes of other languages.


It's less about it being 'foreign' and more about it being totally unparsable.

The thing with imperative programming is that you don't really need to know the language to at least get an idea of what's happening.

Lisp is so dense that while you can pack an unbelievable amount of programming into a small chunk, approaching it as a beginner is daunting. There isn't a really good way to 'build' on an algorithm and learning it is significantly harder than learning C# or Java or even better yet, Python.

It's like saying, 'Linux is easy to learn! You can do so much in so few characters! It's so powerful! And look, robust manual pages for all!'

Yeah, that's true, but handing a user some pipes and greps isn't going to explain what the hell they actually do or better yet, how to leverage that into something useful. It's just going to look like greek to anyone who sees it and a huge effort has to be made to get to the point where you can even begin to understand what's happening.

Imperative programming doesn't ask you of much. 'Here is a class. Here is the main method. Write some stuff in here. Here are some basic methods in the default libraries and their expected inputs. It's going to execute line by line. Go nuts.'

And that's really the difference here. Lisp asks a lot of the user up front. Python doesn't. C# doesn't. Fuck, Python is so loose that you don't even really need to know what any of the structure is to start writing something that kicks back some output. Yeah, as a group that understands Lisp and Scheme and Haskell and F#, it's really easy to say, 'Lisp isn't THAT hard', but that's bullshit. Lisp IS that hard. Lisp is a very difficult language to pickup when you are starting at square one and it's only marginally easier if your background is purely imperative languages. Misrepresenting that is a bold-faced lie.


How much of your argument is cognitive bias?

From what I understand the hardest thing to teach new programmers coming to Java or Javascript or even Python is assignment and mutability. That has a huge cognitive overhead.

Contrast that with the lambda-form structure and substitution method of evaluating expressions in Lisp.

    (function arg1 arg2...)
It's consistent and simple. You can introduce mutable variables and iteration later. With just the substitution method you can go very far as demonstrated by Gerald Sussman in the SICP lectures.

You color your argument with a preference for imperative programming by over-simplifying Java; arguably one of the more difficult languages to teach beginners. The venerable, "Hello, world!" exercise is an illustrative example.

Again contrast that with:

    (format t "Hello, world!")
I think it is possible that Lisp is not that hard to teach as we're meant to believe by arguments like this. Java is a fine language but it requires a fair amount of expertise to use effectively. The same can be said of C. Python and other dynamic languages of the sort might come close to lowering the "difficulty" bar but I wouldn't discount Lisp just because it seems foreign to you.


You could even just write "Hello, world!"!


Lisp is totally parseable. So much so, that no LALR(1) approach is required to conquer it. It consists of an unambiguous parenthesized notation, plus some simple prefix-basd notations (and only a small modicum of non-nesting infix, like the consing dot and the colon in "package:symbol". You do not run into any issues of associativity or precedence. Moreover, indenting Lisp so that it looks good, readable and "canonical" is very simple; it is based only on a couple of heuristics that can be applied to small expressions or large functions alike.


^ Why would someone downvote facts? Because they conflict with their religion, of course.


There is not so much difference between "parseable by humans" and "parseable by compilers". What is hard for the machine is hard for you also. For instance, if you're asked to sort a deck of 1000 randomly shuffled cards, each printed with a unique integer, you will not do better than O(N log N).

Take any LALR(1) defined programming language. Now write it in one line without indentation. How easy is it to parse (for you, human)? We rely on other clues to grok languages, like indentation. You cannot really "cheat" in parsing; if the machine requires a 600 state transition graph with a push-down stack, that translates into difficulty for you, also.

Lisp is obviously parseable by humans; there are people who easily write and maintain large, complex Lisp programs.


I think you're missing the point and/or wrong.

First, I don't want to have to turn myself into an LALR parser to read some code.

> What is hard for the machine is hard for you also.

But what's easy for the machine may well not be easy for the human. LZW isn't very hard for a computer, but good luck reading it.

Syntaxes that may be equivalent to the computer may well not be for the human. Yes, a human can train itself to read that stuff, but if the language designer made more humane choices, the language would be easier for the humans.

Note that this does not directly address how hard it is for humans to read Lisp. It merely addresses the parent's comments.


My point is hinting at that Lisp is readable when it is properly written with indentation and alignment. And when good coding practices are followed, like writing reasonably small functions, using good variable names and so on.

Humans do not count parentheses and keep track of nesting levels when reading Lisp, any more than they go through LALR(1) state transitions when reading C++.

We structure the code in 2D, and use visual cheats.

With Lisp, there is no clear distinction between "language" and "library".

In any language, code is hard to understand when it uses a lot of external symbols from a library.

No matter how well you understand C, if I suddenly give you a tarball of the USB subsystem of a kernel you've never worked with, and open a random file, it will look like gobbledygook, even though you "understand" the declarations at the "language level".

Most operators in Lisp code are essentially library symbols; and if you're missing some key symbol (such as the outermost one), you might not be able to understand it at all.

Lisp readability requires not only nice code structure, but a decent working vocabulary: enough vocabulary that you're not tripped up by the standard things that are in the language, and you know what is in the language and what is defined by the program.

For instance if you see some (macrolet ...) form and you have no idea what that means, you may be stuck. What is macrolet? Did the program define that somewhere? An experienced lisper doesn't bat an eyelash. Of course she knows what macrolet is: it's a binding construct for making lexically scoped macros, doesn't everyone?

(But at least you know from the unambiguous syntax and formatting clues what goes with what: what parts of the whole thing are arguments to that macrolet, and which are outside that macrolet! So when you look up macrolet in the reference manual, you know exactly what is being passed to it and can figure it out without any undue difficulties.)


And, about that vocabulary point: different Lisp dialects differ in their vocabulary. Common Lisp vocabulary will not get you very far in understanding Scheme. Emacs Lisp vocabulary will serve you only so far if you'e reading Common Lisp. A dedicated Schemer will be tripped up reading EuLisp, and so on. In languages that have a big divide between "built in" and "library", we see this kind of variation at the library level. For instance C is mostly the same on Unix or Windows, but the libraries are mutually foreign languages. `CreateProcess` with umpteen arguments versus `fork` and `exec`, and whatnot. Since C doesn't have built in data structures, everyone rolls their own, creating effectively a different "C with lists" dialect.


Parseable by humans, not compilers/interpreters.


> Lisp asks a lot of the user up front. Like what? Last time I checked you get a repl and type away. If you have a mac you can install CCL from the app store and don't even have to use the terminal to get to a repl.

> Python doesn't. C# doesn't. Fuck, Python is so loose that you don't even really need to know what any of the structure is to start writing something that kicks back some output.

again, not unlike lisp.

> Lisp isn't THAT hard', but that's bullshit. Lisp IS that hard

Care to back up that claim? AFAIR The SCIP barely spends a page explaining the semantics. The CONCEPTS in teaches are hard(er) but they are not lisp. In fact one of the reasons the SICP was written in Scheme is so that you _don't_ have to waste half a semester teaching the language before you can get to the fun, important, useful stuff. The little schemer doesn't spend much time teaching lisp either.


I don't find your argument to be very compelling. Let me guess: you learned imperative programming first, you're most familiar with it, and you only have limited experience with Lisp, if any? The fact that you find imperative programming easy (because you know it well) and Lisp and functional programming to be hard, is not very informative about which of imperative or Lispy or functional programming is easiest to learn.


The only thing that was hard with imperative programming that I can remember was "=". That was absurd, to put it simply. "x = x + 1"? As someone who has seen these symbols in math class and think they know what they mean that notation kind of suck.


Oh man, yes! One of my earliest memories from when I started coding, at 10 years old, was when I saw "X = Y + 10" in a program, and a similar thing in the next line. My first reaction was: what is that? It looks like a system of equations that the machine is supposed to solve!


totally unparsable

Completely and utterly false. Lisp's s-expression syntax is trivial to parse because it is so regular.

The thing with imperative programming

Common Lisp is multi-paradigm, as mentioned in the site's FAQ. You can write imperative code all you want.


Parsable for humans, I believe he meant. And there's something nice about line-by-line execution.


Wrong either way. Because it is so easy to parse by computers it is easy to use them to format it. Have you tried reading foreign (as in not written by anyone you know) lisp code? IME It is not hard(er) than any other language.

For example, IME delving into the codebase of hunchentoot was way easier than django's.


All of this stuff is subjective. I've coded Python for some time, and I've done an entire project in Clojure.

Because I've done more Python working, reading Django's source is much easier for me than most Clojure code (even my own), but that's not to say the same for everyone else.

These are after all languages (even if they are artificial). The human brain is really good at understanding a wide variety of linguistic constructs, the main issue is familiarity and that changes from person to person.


Even if you don't understand Lisp (the meaning of various operators), the structure of a Lisp function is already clear. All you have to understand is symbols, spaces, and parentheses; a lot of that comes from Western writing systems already (which use symbols separated by spaces (and parentheses)). The one piece of common knowledge that you dno't get to apply in Lisp is the writing system for infix arithmetic. (It can be easily put in as a small library module, but nobody ever uses it.)


Well, let's see.

Lisp has no syntactic cruft? It has (almost) no syntax, so there's less room for cruft. That said... cons? car? cdr? That's your syntax? That's not cruft? Seriously? There may be less total cruft, but the percentage of cruft might still be higher...

There's less overall to learn? If you mean to master the syntax, sure, that's true.

You'll be writing real, useful programs in Lisp sooner than you could with other languages? That's a much more arguable point. There's more to being able to effectively program in Lisp than learning the syntax (as there is for every language). Is that "more" easier to learn for Lisp than for other languages? I have no data, but for the web site's claim, I'd at least say "citation needed".


I believe that Lisp requires years to master.

If you're a bright developer, who puts in time eagerly, it will take at least six months before you begin to "get it".

At that time you may start itching to evangelize to others, but those who have not put in the time will not get it.

It's not realistic to try to make someone see in one or two e-mails or postings what took you a year to see for yourself.


I think the whole enlightenment thing w.r.t. lisp is overblown.


lol @ random downvotes for criticizing lisp. Set and match.


I don't think that any Lisp programmer downvoted him.


From what vantage point?


I worked through SICP years ago and used scheme as my primary language for a couple of years. I write in an ML dialect at my day job.

1. lisp got a lot of stuff wrong; there's really no reason not to use scheme.

2. lisp syntax is more something to overcome than something to become "enlightened" about. Language syntax no longer has to be motivated by ease of parsing.

3. Dynamic typing only gets so enlightening. At the end of the day, type theories are where the rubber hits the road.

4. Macros don't excite me much. I mean, they're cool, sure. Okay.

At the end of the day, there's a lot more exciting stuff out there (e.g. any math class beyond the calculus sequence or so) that people get way less worked up about.

It's possible to understand lisp, think that there are important ideas there, but not go around evangelizing. Most smart people who study something non-trivial don't evangelize.


The Lisp language syntax is not motivated by 'ease of parsing'. It is motivated by the 'code as data' idea, which enables a lot of useful source transformations to be implemented AND used in a relatively easy way. One of the applications of that are macros.

Scheme got a lot wrong from a practical perspective. Use Lisp instead.

Type theories are over-hyped. 99.99% of all software is written in languages without advanced type systems.

Macros are nothing for 'excitement'. They are a tool. They enable the user to write source transformations, which has several applications in Lisp: control structures, compile-time computation, etc etc.


Lisp's macros don't even get variable binding right. Treatment of bound variables was one of the explicit purposes for the development of lambda calculus in the first place. Imho if you get something as fundamental as this wrong, you don't get to play.

But Im not going to get into a language war.

Stepping back to the original point, there are other significantly important/powerful ideas in the world, and lisp users are somewhat over-the-top in their significance-to-hype ratio.


Given that macros 'don't get variable binding right', they are still amazingly useful.

> Stepping back to the original point, there are other significantly important/powerful ideas in the world, and lisp users are somewhat over-the-top in their significance-to-hype ratio.

Many of the powerful ideas in software development are available in Lisp.


I mean, a really solid understanding of substitution is probably one of the major contributions of lambda calculus. For what's effectively an implementation to get that wrong is pretty pathological. And also, there's no reason to defend it. It's a bug. Period. Yet here we are.

And there's a whole hell of a lot more in the world than software development...

To the extent that lisp captures any of these other foundational ideas/theories/techniques, type theory does better (which is what I was pre-empting with my original reference, not the role of type systems in the world of practical software development).


> Stepping back to the original point, there are other significantly important/powerful ideas in the world, and lisp users are somewhat over-the-top in their significance-to-hype ratio.

Lisp is not a version of lambda calculus. It's a programming language. Macro programming in Lisp works fine in many cases.

> type theory does better ... not the role of type systems in the world of practical software development).

Lisp is about practical software development.


Right, okay, so lisp is primarily a programming language for practical software development. That's really my whole point.

I'd argue that there are lots of other settings with ideas a powerful or more powerful than whatever it is each individual evangelist feels someone should get out a lisp. Yet none of these other things have enlightened evangelists pushing the product.

That's all I'm saying.


I'm not the above poster but I think the power of macros is way overhyped and not nearly as strong as people claim. I see the claim of "you can write a macro to do it" for any imaginable feature all the time, but it is simply not true.

A recent example from personal use is continuations. Scheme has them as a first-class object. Common Lisp does not, but a common claim is that you can write macros to provide continuations. Some people have: there's "cl-cont" available on Quicklisp, which is a macro that will code-walk your functions to turn them into continuation-passing style and thus allow you to use continuations in those functions.

So that's great, right? Common Lisp now totally has continuations? Not at all. In order to get this feature, you need to wrap ahead of time (specifically, at compile time) the functions you want to be continuable, and all of their callers, in this macro. You cannot simply use a function that you've been given as part of a continuation, it had to have been compiled under this macro.

That's where the power of macros completely falls down and, in my opinion, gets completely overblown. Yes, your language is extendable, but your extensions are limited to computation and source-to-source transformation at compile time. You can't apply any of that power to already-existing artifacts.


> I see the claim of "you can write a macro to do it" for any imaginable feature all the time, but it is simply not true.

Which is not surprising. Actually nobody with a clue makes such a claim.

Still, Lisp macros have a wide variety of very useful applications.

> Yes, your language is extendable, but your extensions are limited to computation and source-to-source transformation at compile time.

Still quite useful. From relatively simple stuff which makes to code more readable to complex macros like ITERATE.


You'll note that I never said it was not useful, but rather it was not this powerful magic sauce that can do anything.

> Which is not surprising. Actually nobody with a clue makes such a claim.

Most Lisp books make this claim.


> Most Lisp books make this claim.

For sure not.


That's right; macros need a target language to expand to, and that target language needs to seamlessly inter-operate with the surroundings and with the forms that are inserted into it. Some semantics is simply not available without transforming the entire program in which the macro call occurs.


Yes, exactly my point. Macros are very powerful but not a magic sauce that makes Common Lisp infinitely extendable. Some things you actually need to change the underlying implementation for.


> It's like a never-ending stream of lies, every word being a little more absurd than the last...

It's been my experience that most things are tractable once you spend long enough staring at them.

If you care enough about a subject to have strong sentiments like "never-ending pack of lies" then your time would perhaps be better served by spending time with the "adored" object, rather than these comments.


Could you enumerate the lies for us? Your comment is arresting but not enlightening without more information.


I wouldn't say "lies" so much as overly optimistic opinions.

The idea that you can write a useful program in Lisp faster than in other languages is pretty unsupportable. For most users, the time and effort spent getting Lisp up-and-running on their machine of choice will already have lost. Incidentally, I played with the interactive REPL and it wouldn't advance beyond the second page.

And, if you do write a useful program in Lisp, you run into the deployment problem. The deployment problem is pretty bad. Apple's Advanced Technology Group at one point had one of the highest concentrations of Lisp-heads in the world and produced a bunch of stuff like Dylan, Sk8, etc. that was intimately tied to their Lisp implementation. Not only was this not cross-platform, and pretty hard to distribute and deploy even on the platform it was created for (680x0 Macs) it was killed by the transition to PowerPC.

This isn't as big a problem if you're writing server software, but it's absolutely disastrous if you're writing desktop or mobile software.

One could show someone how to do something useful and deployable in Python, PHP, Perl, Javascript, or whatever in a few minutes and chances are they could have a usable dev environment set up in a few minutes.


The only thing that makes programs easy to deploy is the popularity of the language/environment they're written for. If the language you're using is popular enough that you can download the implementation using your system's package manager, deployment is easy. If not, it's harder.

And for any language that's popular now, there was a time that it wasn't yet popular, and deployment was a pain.

So I think you have it backwards: Lisp is not unpopular because it's hard to deploy; it's hard to deploy because it's never cracked the popularity threshold.


The old joke with Common Lisp used to be if you've developed a program for one version of Common Lisp, you've developed a program for one version of Common Lisp.

Lisp is notoriously hard to deploy. Code is not portable between different lisp implementations. Apple's ATG ended up axing many projects because they had so much trouble moving their lisp from 680x0 to PowerPC.

The fact you talk about "your system's package manager" ignores my point -- I'm not saying Lisp is especially hard to deploy to servers (although it is -- but this is, as you say, a popularity issue; and it would be far worse if the world of servers hadn't converged on a small number of very similar platforms). I'm saying it's hard to deploy to desktops and mobile, which is where most of the "useful" programs people might want to write still live.

A huge part of Lisp's problem is fragmentation. Which Lisp? Aside from fragmentation in Common Lisp itself, there's all the not-quite-Lisps around, ranging from Arc to Scheme to Clojure to sheesh-I-really-have-no-idea. And of course this is because once you start coding in Lisp there's an overwhelming urge to abstract away difficult things in your own clever way, perhaps even hacking the language itself, and pretty soon your little world is utterly unique.

Another great, simple language in the exact same boat is Forth.


This is only telling half the story. It is perfectly true for, say, Python (still a pain to deploy on Windows, or at least it was the last time I tried), but newer languages that are less popular like Go do not have this problem. Even Rust, a language that is only in alpha, does not have this problem!

Why is this? It's because they can live in, and interact with, the common linking and loading ecosystem that the rest of the world lives in: the C ABI. If you can link your output into something that respects the C ABI, you can deploy it[1].

Common Lisp implementations could immediately solve their deployment problem by living in this ABI. So far, the only one that has done so is ECL (which is an excellent project).

[1] A few alternatives exist. The Java and .NET ecosystems are also viable link targets (as I think Clojure has proved).


If you want to create something that you can link into C program, there are several options:

Lisp systems like LispWorks can generate typical platform shared libraries.

Many can easy embed C-code.

Some compile to C, which than can be embedded. ECL is only one example. Others are mocl or the ECL-related systems.


Well, sure, if all your programs need is the OS and common libraries, deployment is easy.

But this only restates the point. It's easy because those things are popular. Try deploying an executable that requires a shared library that you can't download with your package manager, and you're pretty much back into the same pain.

Using the C ABI helps if you want to link against other code that uses it, though it isn't strictly necessary (pretty much all these language implementations have foreign call mechanisms). But this is a development issue, not a deployment issue.

ECL does make it convenient to build standalone executables, but most CL implementations can also do this.


I'm an Lisp programmer, so I can. The language ANSI Common Lisp certainly has its fair share of "syntactic cruft". For instance numerous "macro dispatch characters" like #'func #:sym #c(2.0 4.1) #(vec tor). None of the syntactic cruft requires a LR(1) algorithm to work out; most of it is based on recognizing a character or two of prefix material and dispatching a read function. When the dispatch involves two characters, the first one is almost always # (though for programming your own nonstandard read syntax, that is not a fixed rule.) Read syntax is not even considered "real" syntax by Lisp programmers; "real" syntax is the structure of macros. But since macro forms are unambiguously written as nested lists, they already express the phrase structure almost directly; there is no phrase structure that needs to be applied to get a syntax tree.

There isn't any syntactic cruft in Lisp that will have you scratching your head as to what goes with what.

There are semantic head-scratchers related to syntax, like working out the implied actions of complicated, nested backquotes. There is never a question of syntax, though: nested backquotes are not ambiguous syntactically: they are just nested lists, with some sprinkling of a simple prefix-based notation throughout (splices and unquotes).


Lisp is the hardly the simplest language. It has way less 'stuff' to learn, but that 'stuff' in imperative languages is generally useful abstractions that you don't to learn, but instead simply know of. By that measurement, x86 Assembly is really the simplest language of them all, but I don't think I need to explain why that's equally absurd.

Lisp is a difficult language due to it's density and unreadability.

Useful stuff hasn't been built in functional languages until very recently, exception being some AI. Haskell and friends are making functional languages cool and useful (and that's great!) but if you want to build something useful as soon as possible, learn .NET, Java, Python or Ruby.


What you mean to say is that Lisp is simple but not easy, but that's true of a lot of things.

You might enjoy this: http://www.infoq.com/presentations/Simple-Made-Easy


I think the sentence is poorly put together, but there aren't any lies. Clojure syntax is by far more simple (and thus easier to learn) than C-style languages or Python or Ruby. But the language is harder to jump into because it places particular emphasis on programming principles that are confusing to new programmers, like function purity, recursion and higher-order functions.

Keep in mind too that different Lisps have different syntax. The only thing in common between them is Polish notation, S-expressions and a macro system. A Clojure program and a Common Lisp program look and feel very different.


"simple" isn't the opposite of "hard," it's the opposite of "complex."


I'm surprised there is no mention of Lispbox[0], by far the easiest way to set up Common Lisp.

[0] http://common-lisp.net/project/lispbox/


I suspect it's mostly because quicklisp (http://www.quicklisp.org) pretty much obsoletes it.


Awesome, I'll give this a try. Does it use Steel Bank Common Lisp ?


They wrote that they use "Clozure Common Lisp compiler" [1]

[1] http://ccl.clozure.com/


Yes, quicklisp works with SBCL.


I went to a techie high school and we studied LISP in an AI class I took. My biggest memory is the load of parentheses! It was definitely an interesting language and I've often thought about looking back at it for giggles. This could be a good reference.


The FAQ section answered all of my questions. Well done.


I'm guessing this was posted earlier than expected. Don't see much content beyond the Preface.


This is fantastic! Really looking forward to the web chapter!


OK. this is actually true. thank you so much


What is that background image? Some fractal?


thephoeron should start a mail list to let us know when there are updates and when the paperback is ready to buy.


"that Lisp is not already the de-facto programming language is just a reflection of the state of the world as a whole—only a very small percentage of the population are excited for the technological singularity, but the singularity is coming no matter how much people complain."

As a transhumanist myself I resent the arrogance that led to this ridiculous appropriation. Yes, Lisp is pretty great, but the use of other languages is not some grave cultural defect through which you can glimpse at all the badness in the world.

If the goal here is to evangelize Lisp, radiating this kind of pomposity seems like a questionable move because it reflects badly on the community you are trying to win new members for. Worse, this could be interpreted as willful cluelessness in the face of the rich multi-language ecosystem potential readers are living in.

As far as the singularity is concerned, monocultural boneheadedness is not something people associate with technological progress.


I love various Lisps, but I've always enjoyed http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m... :

    > 1958 - John McCarthy and Paul Graham invent LISP. Due to high costs
    > caused by a post-war depletion of the strategic parentheses reserve LISP
    > never becomes popular[1]. In spite of its lack of popularity, LISP (now
    > "Lisp" or sometimes "Arc") remains an influential language in "key
    > algorithmic techniques such as recursion and condescension"[2].


Ignorance of things like Lisp is a cultural defect in computer science. It's just a symptom of a greater problem: lack of awareness of what has already been done by prior generations. If electronics engineering were like CS, some twit would be reinventing the long-tailed differential pair today, and trying to get a patent on it, with full backing from his research institute or employer.


That's not the issue. It's about whether you think that Lisp is the only objectively correct answer whenever the question arises "what language are we going to use for this?".

Willful ignorance about other languages and their features is as much a cultural failure as, the hypothecial, unwillingness to learn about Lisp.


The point is that other languages added little to what Lisp already had to offer over half a century ago.

Every language has its use, but really we ARE wasting time by splitting the worldwide community of programmers in different languages.

Look at how most programmers love one language and advocate it's the best there is. That's called a split.

Aren't we supposed to not reinvent the wheel?


This view only makes sense if you believe one language is enough. One language that has it all figured out, one language that is the right solution for any task.

Even if such a language existed (be it Lisp or not), which is unrealistic, there is still a second aspect to the whole thing: programmers' brains. Different languages map differently to different kinds of brains, and that's a very good reason to explore multiple concepts in itself.

The Split is the natural way to explore a large search space using different strategies. It happens all over nature, and it's the way human-powered research works as well. Monocultures don't perform nearly as well. Yes, there is some effort wasted, but you can rarely ever come to an objective consensus where this waste actually occurs - except, typically, in hindsight.

Also, there is quite a bit of cross-pollination of ideas happening among different environments and languages, so advantageous traits do get passed around beyond their initial ecosystem.

I imagine cross compilers and common runtimes will get more popular, too, now that we have the processing power - and that's also a good strategy do deduplicate effort.

The only thing that really strikes me as a bad strategy is militantly advocating one programming language as the master race. You're not even doing the "pure" in-community a favor by denying that concepts from the outside world might occasionally be useful. Instead members are reduced to armchair criticism along the line of "yeah, nice library, but you didn't write it in Lisp, so at the end of the day nothing at all was achieved."


One language might not be enough, but one nice language plus C --- now you're talking. :) :)


There's a lot of religious imagery in the text with discussion about fractal cosmology, mysticism, Lisp's natural connection with the human mind, etc.

It seems as though the author is trying to sell a religious experience to his readers. If that is the case, that's interesting in the sense that it is certainly unlike any other programming text I've read. I personally think evangelizing Lisp should be in the form of making it more familiar, human, and relatable to the average programmer, but I can't help but to respect the sheer uniqueness of the approach.


>If the goal here is to evangelize Lisp, radiating this kind of pomposity seems like a questionable move because it reflects badly on the community you are trying to win new members for. Worse, this could be interpreted as willful cluelessness in the face of the rich multi-language ecosystem potential readers are living in.

How circular! A Lisper would respond that the very passage you critiqued is the appropriate response to your critique---that Lisp is coming, no matter the tone, and our complaints or praises will have no effect on the final outcome.

Perhaps Lispers would do well to be less pompous, but that is for their welfare, not Lisp's.


You could choose to understand it that way, but only if you want to kill the conversation. Which is fine, of course. Judging by the amount of controversy mirrored in the voting of my comment (I suspect moderator intervention was involved as well), a large number of HNers really do believe that all non-Lisp languages are abominations, that there is no appropriate paradigm besides Lisp's, and that Lisp already contains all the innovations and concepts that could ever be worthwhile. That's an almost cartoonishly narrow way of thinking.

At best, this is a religious point of view, and at worst it's also a matter of being part of the in-group - which means this opinion is calcified because it's a critical part of these programmers' identity.

I generally don't like to comment on these kinds of threads anymore than I would on political or religious ones. However, this thread is about outreach to people outside of the cult. Continually forcing the impression of being a cult might well serve to recruit more followers, but I'm wondering: does it really have to be a dogmatic movement? Isn't the larger opportunity here to try and reach another kind of person?

I know there's a taboo in this community about addressing aggressiveness and arrogance, and maybe that's an excellent policy to prevent flame wars. However, I think it's a mistake to overshoot this target by accepting abrasiveness and fervor as valid replacements for reason and reflection.


Try Lisp. You'll see most modern languages -- Objective C, Ruby, Java, &c -- and not so modern languages as well, don't have much that Lisp doesn't offer. That the pomposity may not be the best way is but a matter of opinion. But features? We can sit down and count those. I encourage you to learn Lisp. It's enlightening.


What makes you think I don't know Lisp? You didn't even read my comments, did you?


Something I find ironic is that Zed Shaw dislikes both haskell and lisp programmers for a variety of reasons that would only provoke if I put them here, some of which you already mentioned. Search "lisp" in second source.

[1]http://lemire.me/blog/archives/2010/05/31/computer-science-i...

[2]http://learnpythonthehardway.org/book/intro.html


Yeah that is kind of funny, but if he finishes it then I can update that intro to point people at his book instead.


MIRI (one of the more well known groups of people serious about the singularity) actually recommend people learn Haskell if they want to contribute to mathematical, statistical, AI research.

http://intelligence.org/courses/

https://github.com/bitemyapp/learnhaskell


You should also learn Scheme, too.

From your link:

> The first self-modifying AIs will hopefully be written in functional programming languages, so learn something useful like Haskell or Scheme.


Before asking the obvious question when noticing the "Learn [X] The Hard Way" pattern, the FAQ already addresses that :-)

Q: Is this site affiliated with Zed Shaw and Learn Code The Hard Way?

A: No. This is a separately run and managed site, based on the format of Zed Shaw's LxTHW open-source package [1] for writing your own programming language course. You should check out the project and see what others are up to! More information is available at: Learn Code The Hard Way [2]

[1] https://gitorious.org/learn-x-the-hard-way/

[2] http://learncodethehardway.org/


It's not affiliated with me other than using my starter kit and the title style.

I do support books like this as I think there needs to be more "trainer" style books, especially for beginners, because they work.


Why copy his format? Seems Zed did the hard work to establish the brand.


A few other people mentioned this but I'll say it officially since the internet has a short memory for good things:

1. You can't really trademark titles of books, and I wouldn't want to in this case because there needs to be more books in this style. This method works for beginners, and works really well, so I want there to be more.

2. I created the repository so that there's an even lower barrier to entry than having a title to copy. I actually need to update this repository, but if I made it then I want people to reuse the methodology and make their own.

3. My only complaint would be when people rip off my words. If someone wants to write one of these, they just need to do their own writing in their own words and not copy mine.

That's my stance on it. I like people copying the title and method as it means there's more books that will help people learning to code. I just don't like them copying what I wrote.



Seems a little ambiguous to me. His wording seems to me to be about how to write a "similar book". Anyway Zed is here on HN from time to time so we might hear what he thinks.


Why would he put up a public repository if he did not want the format copied?

Zed A. Shaw created project Learn X The Hard Way 2011-08-29 22:06:48 UTC This is a skeleton book project that makes it easier to start working on a "Learn X The Hard Way"...


Probably the polite thing to do would be to check with Zed first. Maybe the author already did.


I think you can copy his format, but taking his brand is a different story. Zed put a lot of hard work into that, this is less than honest in my mind.


Saying that it's a template for a "Learn X The Hard Way" book sounds to me like an invitation to write a book titled "Learn X The Hard Way" (absent any statement on his site asking that people name their book something different).


Because Zed made it open source to encourage other people to use it, and because he laid excellent groundwork so it's a good format to follow.


"Lisp is, at its heart, a very mystical language, that blurs the line between programming and magic."

I like lisp, but this kind of mystical gobbledeygook is not helpful. It's worth noticing that mystics and lisp-ninnies are alike in a very important way: promising much, and delivering little. The people who actually accomplish things in lisp (Yann LeCun, Richard Fateman) do not speak in this preposterous mouth foamy way. They also don't work for overt frauds like d-wave.


Yann leCun does not use Lush anymore.


Regarding the tone I concede it is a little over the top, but considering the author works for D-Wave[1] building the future of (Quantum) Computing I think it is not without merit.

It may be better to leave the intro part for the end as it may alienate programmers that have preconceived notions about lisp based on hearsay and not actual experience (i.e. it's enlightening, it's old, full of cruft, hard to read, it's functional, Clojure is the future of lisp).

It is also very much a WIP that the author didn't submit so keep that in mind.

I hope he gets to writing the chapter on Quantum computing: http://learnlispthehardway.org/book/3-14-0-quantum-computing...

[1]: http://www.dwavesys.com/


It's worth noting that I don't work for D-Wave. Quantum Computing is an interest of mine, so naturally I signed up for their developer program when they launched it a couple years back (which they shut down entirely earlier this year).


Sorry, my mistake. Don't know where I got the idea that I had seen D-wave on your gh profile.


Oh, yeah that was just the group for members of their developer program. It's gone now though.


The author working for D-Wave is a very illuminating fact, given the high probability that D-Wave's products are pseudoscience.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: