back
164 comments
It's about a month since I've started seriously diving into lisp.

The last couple of weeks I've spent my days reading 'The joy of Clojure', Structure and Interpretation of Computer programs, lots of tutorials and documentation, playing around in the repl + experimenting with all kinds of frameworks and libs in clojure (eg. Om).

I've spent today implementing the brainfuck interpreter in Racket.

I can't explain it, it's like something is calling me - 'learn lisp. now.'.

Given the amount of Lisp code read/written and the relative novelty of it, I'm dreaming lisp code and the arguments to functions are actual physical things, which are then mapped, reduced, recursed or expanded.

Literally, I think I'm going crazy.

I can fluently write x-platform C++, Javascript/CoffeeScript, Objective-C, Java, Pascal, VB and everything in between.

But never have I experienced this kind of mental strain/obsession as I do now with lisp.

But.

Seems like I'm not alone! Given the amount of lisp news lately on HN, I fell like more and more people are going through what I'm going.

Seems like we here on HN follow a common mental pattern and suddenly everyone's talking/learning lisp.

As interesting as learning lisp is, this 'group preference' thing is even more interesting to observe.

It's not so sudden. HN itself is written in a LISP [1], and Paul Graham's pre-YC claim to fame was Viaweb, a store platform written in LISP that became Yahoo Stores. This community has been above-average LISP friendly for a long time.

LISP's also has a long history of popping up all over the place because they are extremely implementation-friendly (if you want to write a simple language; if you want to make things fast they get trickier, thought by no means impossible) given the simple syntax.

So you'll also find a lot of people (like me) who don't really like LISPy languages, but who still end up dabbling with related technologies occasionally (my very-slowly-in-progress Ruby compiler uses s-expression syntax (though no LISP semantics to speak of) to express a tiny language to implement some of the lower-level plumbing to bootstrap the Ruby core classes, for example)

[1] http://arclanguage.org/

>But never have I experienced this kind of mental strain/obsession as I do now with lisp.

That's why it's so valuable as a right of passage. If you've spent your career writing simple iterative imperative loops, suddenly you're a newb again with map/filter/reduce this, partial that, and recursion and lambdas and closures and finally after your 20th time staring, dazed at 3 measly lines of nested composed recursion - it all starts to flow, and boom, you have a new way of approaching every problem.

And even if you don't live in the lispy functional realm after that you'll always be better off for having crossed that threshold.

Every once in a while, I like to sit with a cup of hot tea or coffee, in my bathrobe, in read about Clojure. Algorithms, ideas, data structures - it's so .... just...clean and well thought out. There's something really nice about LISPs, and it's drawing me into it as well.

I still do C#/Javascript/Java/whatever in my day job, but LISP is just...sexy.

And for those that hate parens - Emacs paredit. Nuff said.

I went through a Lisp phase exactly like that. Currently I'm going through an extremely similar Haskell phase. I've learnt half a dozen languages before these two, but I've never experienced the satisfaction and obsession I've experienced with these two. My Lisp phase went on for the better part of a year, and I've been learning all the Haskell I can for 11 months now, but my obsession is still in full force. Haskell also turned me towards maths, and now I'm reading a book about category theory and a book about type theory.
I had this experience, too, years ago. I felt like my brain was getting rewired. I loved it. I also noticed that I was thinking in Lisp relatively quickly. To this day when I have a really hard problem I want to solve I write the code in Lisp because it makes hard things easier to understand. Then I implement it in the language I'm using.

You begin thinking "naturally" in Lisp because there's no syntax to memorize, it's all data and / or semantics. You can literally write the code in your head. Languages I've used for years and years don't do this to me like Lisp does.

It also made me feel more confident about programming in other languages and not to get distracted by "fancy" syntax or features that are just warmed over scraps from the floor of Lisp's feast on the table.

My first exposure to Lisp was through a combination of Hacker News, SICP, and Paradigms of Artificial Intelligence. Also, there may have been a blog post by one of the Posterous (or a similar company) guys about getting started with SBCL for web services.

At the time, although I could read the material, it seemed to require too much mentally to actually Get Things Done. I think it was a deep misunderstanding about how to structure a program that is independent of state.

Later, after playing with Scala, amongst other languages, I came to understand that state exists in functional programs. It's not conjured up out of nowhere, spontaneously brought into existence, but rather, it exists as data, and it is the job of the program to direct the flow of data appropriately - like a plumbing system, so to speak.

When you start to reach to point where metalevel, evaluation, transformation, compilation all fit into your mind you feel even weirder.
"Paul Graham’s programming language Arc, a dialect of Lisp, was built on top of Racket."

Since that statement occurs in a section about Racket languages, I should probably clarify. Arc isn't technically a Racket language—that is, it doesn't use any of Racket's facilities for defining new languages. It compiles to Racket (and so you're all using it right now), but has its own distinct implementation.

Historically, Arc wasn't built on top of Racket. I think pg may have started on Common Lisp, then went to Scheme 48, Mz Scheme, and so on. Probably the most accurate thing to say is that Arc was built in pg's head after years of thinking about Lisp. It doesn't have a particularly close relationship to any of those underlying platforms. Semantically it's closest to Common Lisp, but don't tell pg I said that.

This is Matthew Butterick. I wrote “Why Racket? Why Lisp?”

As I allude there, Paul Graham’s writings about Lisp (mostly in Hackers & Painters) helped persuade me to explore Lisp languages. (Those writings have also persuaded many others.)

In particular, Arc's reliance on Racket persuaded me to take a serious look at Racket. So leaving aside quibbles about what “on top of” means — is Clojure not built “on top of” the JVM? Python “on top of” C? — Paul’s choice of Racket was influential in my choice too. (As it has been for many others.)

As for software being “built in [one’s] head,” that seems facially true of any software. The core thesis of “Beating the Averages” is that the tool you choose to get it out of your head and into the world matters. Having now had my own Lisp revelation, I not only buy Paul’s thesis, but I even think it could be strengthened: Lisp permits the implementation of a whole category of ideas that aren’t possible in other languages.

Moreover, Paul wrote that essay nearly 14 years ago. Since then, Lisps have gotten somewhat more popular (Clojure has led the pack). But as I say in the article, as a group, Lisps remain way behind the programming mainstream. So ultimately, my goal is not to evangelize for Racket and exclude other Lisps. I know Racket better because that’s what I use. But more people using all of them would be a great thing.

Good discussion of the advantages of Arc versus Racket. http://stackoverflow.com/questions/8555440/the-advantage-of-...

"I wish they had implemented Arc as a Racket module language since then you could actually develop in DRracket, debug, and make executables."

MZ Scheme was a precursor to Racket. Same people, AFAIK same core codebase.

http://docs.racket-lang.org/mzscheme

I think it compiled to MzScheme first.
Previous discussion can be found here: https://news.ycombinator.com/item?id=8206038

Have noticed quite a bit more buzz about Racket and Lisp very recently around here. It's always been something I mean to explore.

We seem to be on a Racket buzz lately, and I like it. I feel more inspired to dig further into Racket.

I'm already pretty good with Clojure, so can anyone who knows both languages well comment on the ups and downs of learning Racket after learning Clojure?

I think it's because of this: https://news.ycombinator.com/item?id=9220468
I go to my local Clojure meetup. Last time I sat next to a guy who uses Racket in his day job. He said "If I didn't know what the problem was and was asked to pick the language beforehand, I'd pick Racket. I still like Clojure a lot." Didn't get a chance to unpack that with him.
How production ready or mature are Racket libs for creating CRUD web services? skimming through the Racket website one can see Racket has the basics, a http server and a library for interacting with databases like postgresql, as someone relative new to programming/webdev, would I face to much "reinvent the wheel" versus Clojure or Javascript?
Depends what you're doing. It doesn't have the depth of libraries of the JVM or JS, so there'll be lots of "oh, can't use that technology" or "is this 3-year-old unmaintained library still going to work with Mongo?" moments.
Why hasn't XML been matched to Lisp very much? I think it's because Lisp programmers recoil in horror from XML. I mean, if you're already used to S expressions, XML looks disgusting. As verbose as Java, and less expressive. So I think most Lisp programmers look at XML and think "Ugh, don't get any of that on me..."
IIRC, it was Naggum that said the issue with XML is the useless distinction between elements and attributes, leading to countless discussion, bikeshedding etc etc instead of actually solving problems.
See the resources organized under XML and Scheme, by Oleg Kiselyov:

http://okmij.org/ftp/Scheme/xml.html

There is a Racket "package" (not quite a port) of SXML and SXSLT:

http://pkg-build.racket-lang.org/doc/sxml/

Tho in its infancy, Kawa scheme can "paper over" some of the XML in Android dev[0].

[0] https://www.gnu.org/software/kawa/Android-view-construction....

Has anyone tried to use Butterick's Pollen and written about it? The idea of debugging your website with racket as you write markup and styles seemed really interesting alternative to what I do; write styles, refresh, and then refine the stylesheet by incrementally adding changes with the inspector and then copying them to my stylesheet.
I'm working on converting a fiction ebook to web-based with Pollen and may later launch a fiction magazine using it, although I'm undecided about that technology choice.

I think Pollen's biggest strength is that you can reprogram its markup -- as its documentation puts it, you can attach behavior to tags. I haven't taken much advantage of that yet, but you can do things like create a "TOC" tag that builds a table of contents by inspecting child documents and looking for h1 tags (or looking for, say, "chapter" tags, which you've defined to expand to "<h1 class='chapter'>"), or inspect the contents of paragraphs and subtly shift the first line margin to the left if the first character is a quote mark (which Butterick's Practical Typography does). You could replicate some of that with a template language that allows user-definable tags, but I don't think you could do all of it.

Its biggest weakness, at least for me, has been finding a pleasant workflow. Despite having a built-in web server it feels kind of clunky compared to other static site generators. You're largely on your own for writing a deployment script ("raco pollen clone" is not a valid substitute). The DrRacket IDE is virtually a requirement for Racket programming, but it sucks teabags for editing long prose documents; you'll likely find yourself working in one editor for Racket language files and another for Pollen source. This isn't necessarily a dealbreaker, but it's at the least annoying.

I'm working through the admittedly beautiful and very thorough documentation [1].

It's a very simple idea, really: you write your document and sprinkle racket s-expressions wherever you want. You can put your definitions at the top of your document, or in another file. You describe your templates in Racket also, because like Butterick says in his RacketCon video [2], "S-expressions and XML are the same thing". You can use tags that you haven't defined, they just get placed in the resulting HTML.

You still have to roll your own CSS and any JavaScript. As far as I can tell it doesn't help you out with things like keeping track of footnotes numbering or citations and such: you roll your own for things like this, Pollen is no LaTeX. This is partly why I say it's a really simple system. It makes a certain set of web authoring things simple, but it doesn't try to be a one-stop shop, which is excellent because this makes it a supremely flexible tool.

It also has some backend fancy sauce where you can save your file and refresh the page [3]. Also I admit I'm not really a big fan of DrRacket: I've just been using it for the tutorials because I have no idea what to expect from Racket, but I'm slowly moving to Emacs, and Racket seems to work fine there.

Definitely worth checking out Pollen if only to get a light introduction to the thoroughness of Racket documentation (they definitely do things differently in Racket-land!), but stay for the tools you need to roll your own ultimate static blog generator.

(Also, completely unrelated: cool video and cool title at another RacketCon 2013 talk: "Racket on the Playstation 3? It's Not What you Think!" [4].)

[1] http://pkg-build.racket-lang.org/doc/pollen/

[2] https://www.youtube.com/watch?v=20GGVNBykaw

[3] I've made a request for no-refresh updates: https://github.com/mbutterick/pollen/issues/35

[4] https://www.youtube.com/watch?v=oSmqbnhHp1c

As someone who thinks Lisp is pretty cool and uses Emacs to study it and is about 100 pages into SICP: I still don't get it. Common Lisp macros went entirely over my head too. A programmable programming language? Aren't all languages like that? I've only been programming for a couple years so I'm afraid I might not recognize the value of Lisp until I use more of the "less powerful" alternatives.
The principal data structure of Lisp is a list which is written like this: (a b c d). Like the article mentions, when you see Lisp code you're in fact reading the same list syntax, only that, when the list itself is not quoted, the "a" is evaluated as a function, which is why (+ 1 2) behaves the way it does. If you quote the list by saying "'(a b c d)" then it is a list of symbols, so "'(+ 1 2)" does nothing.

Hence, Lisp code is made of nested lists. When you think further about it, it means that Lisp metaprogramming facilities may do things just with plain list manipulation functions! So it's not about metaprogramming itself, it's that it's incredibly easy. This is what people refer as "code as data" and "homoiconicity" and so on.

Lisp "advocacy" often touts the power of macros in an abstract and unconvincing way. Persuasion by explanation isn't very effective. I'm not very interested in persuading others that Lisp macros are necessary, and there are many languages I like to use that don't have macros. However!

Yes, all programming languages are programmable. But Lisp tends to be unlimited in its programmability, in almost the same way that Unix is: if you have root, you can change anything. I'm pretty sure that in most Common Lisp systems, you can redefine large parts of the compiler at runtime. And so on.

Syntactic macros are just one part. They can be extremely handy. Lots of Lisp systems use them well. Random examples: the DEFSYSTEM macro of ASDF; the DEFINE-EASY-HANDLER macro of Hunchentoot (a Common Lisp web server); the (controversial) LOOP and ITERATE macros; etc.

Another somewhat random example: Movitz was (is?) a project to write an x86 kernel in Common Lisp. It actually included its own compiler. It defines a lot of macros for instruction definition [0] and uses them in code that I don't understand anything of [1] but is probably very clear to someone versed in assembly.

Recently I've been trying to add some nice logging to a JavaScript program, and it's a typical scenario where the normal syntax is just annoying enough to make the code ugly and hard to scan—if I had macros, I could invent some other syntax.

How to use macros is a tradeoff that I guess comes with Lisp experience, but they can be a powerful escape when the standard syntax is annoying, and a way to define your own DSLs without restriction.

[0]: https://common-lisp.net/viewvc/movitz/ia-x86/def-instr.lisp?...

[1]: https://common-lisp.net/viewvc/movitz/ia-x86/instr-add.lisp?...

> A programmable programming language? Aren't all languages like that?

How would you write a program to write a program? How can you use this generated program in your other code? It's really hard to do with a lot of programming languages, even those that have eval like JavaScript, so it never occurs to people that something like a template system or a code translator/DSL should be trivially easy to write.

I found the "Little Schemer" an enjoyable tour on exorcizing the power of lisp. Depending on how far down the rabbit hole you want to go there are a plethora of information in various AI memos as well as the READscheme web resource with the original LAMBDA papers (readscheme.org) which most certainly worth PRINTing if anything to get primed for SiCP.
Lisp doesn't have pattern matching. With optima[0] it does.

Lisp uses prefix notation. With mexpr[1] it uses infix notation.

And so on.

[0] https://github.com/m2ym/optima

[1] https://github.com/tmccombs/mexpr

I have a feeling people tend to over estimate the importance of language choice. Might be just me though.
Many people agree with you but I have the opposite view. Of course you can write any program in any Turing complete language, but the programs people do write in a given language tend to have a family resemblance to one another. Therefore if we want different kinds of programs we should have different languages.

A given language makes certain ideas easier or harder to formulate, and thus easier or harder to have in the first place. So the language constrains not only how you think about your program, but what you think—and thus what the program itself becomes.

Platforms, communities, and culture also help determine these things, but they're not independent of the underlying language.

Would you have a look at this?

http://www.paulgraham.com/avg.html

I find all his digs at javascript funny since, at least the way I use it, javascript is basically an ugly-looking scheme. Javascript is responsible for my 'lisp enlightenment' with the language using first-class functions and closures, and the wide variety of precompilers. It strikes me as fashionable to hate on javascript.

Java on the other hand, now that's a horrible language ;) ;)

I think the hardest thing for people to get for programming in Lisp is the immutability. Once you get over that hump, everything is downhill. From the outside, the parenthesis seem pedantic but it's completely superficial. You will stop noticing them in a few hours, if not days.
> What's in it for me? Expressiveness.

I appreciate the author's wanting a more explicit and practical answer to this question, but I don't think his answer here ("expressiveness") does any better job than the other explanations he criticizes.

> But [learning Lisp] also requires an investment of about 100–200 hours. That's asking too much.

No, it's not. That's how long it takes sometimes, or longer. Why do we all expect answers and understanding to come so quickly and easily? It'd be a nice world otherwise, but almost always enlightenment comes at a cost: patient focus and study.

I have so far stuck with Clojure instead of a Scheme primarily because of the nice literal syntax for maps, sets, vectors, and regexes that Clojure supports. I don't want to give that up and just use cons/car/cdr.

And also, last time I looked at Racket, it seemed very focused on academics. I just wanted to write some simple Scheme in a .scm file and try it out (a script), but I think I had to choose a language first (maybe a line at the top of the file? Don't recall) --- the Racket ecosystem seemed off-putting.

What is a good resource to learn Lisp for an advanced (non Lisp) programmer? Most guides for most languages only cover declaration, simple functions and tiny applications. I want something that quickly goes through the basics and skips to advanced uses in bigger codebases.
I love this site, it's so simple and beautiful
> (x + (if is_true(): 1 else: 2)) [is invalid in Python] be­cause the if–else con­di­tional is a state­ment, and can only be used in cer­tain positions.

Point taken, but troll-mode pedantry: (x + (1 if is_true() else 2)) would be valid :)

    For more on the per­-
    ils of tax­ing reader
           pa­tience, see
            WHY DOES TY-
           POGRAPHY MAT-
                     TER
This quote, hyphenated as is, provides all sorts of opportunities for snark. Instead I'll just note that it seems Pollen needs work. It's far too eager to hyphenate; doesn't protrude hyphens, commas, etc.; and doesn't use TeX-style paragraph-level optimization. Not being able to identify the bounds of hyperlinks is also a strong source of irritation.
I'd be more interested in a "Why Pollen over Scribble?"...
How does Racket stack up against Clojure? I like some of the special extended reader support for data structures, I dig the immutability, some of the concurrency stuff....I don't think immutability/concurrency is that typical for LISPs...for people who've tried both, which one do you prefer?
is there a tl;dr. After about 45 secs of reading author did not answer why racket or why lisp
Don't waste your time with lisp. Learn lambda calculus and then see how these ideas are applied in actually useful imperative programming languages.