back
280 comments
I dislike this notion that Lisp (or Haskell or OCaml or ...) owe it to everyone else to explain and enunciate why it can be more productive to use Lisp.

""" That’s ask­ing too much. If Lisp lan­guages are so great, then it should be pos­si­ble to sum­ma­rize their ben­e­fits in con­cise, prac­ti­cal terms. If Lisp ad­vo­cates refuse to do this, then we shouldn’t be sur­prised when these lan­guages re­main stuck near the bot­tom of the charts. """

What?? Why? The problem is not and has never been communication of Lisp features. No one made a concise list of why C and Java are so great that people rushed to use them. Instead, they were pervasively used and taught in universities, and they are pervasively used in the development of most applications for e.g. Windows and Linux, and they are relatively simple languages (in theory) whose semantics most people "get". No wacko high order crap, no weight curried things, no arrows or morphisms or monads or macros.

Programmers of such languages don't owe the rest of the world anything. Everyone has a choice about what to use, and it's each individual programmer's responsibility to choose them wisely. There is plenty of material about Lisp and Scheme out there. Unfortunately, we are in this TL;DR culture where no one has the time to spend a few hours every week to learn something new, since somehow that's too big a risk on their precious time.

Now, for some comments:

1. Everything is an expression.

He says this is a boon, but it's also confusing for "expressions" which are side effectful. Too bad he did not talk about that, nor did he talk about how the expression-oriented way of thinking is really best for purely functional languages that allow for substitution semantics.

2. Every ex­pres­sion is ei­ther a sin­gle value or a list.

This is wrong, unless we devolve "single value" into the 1950's idea of an "atom". What about vectors or other literal composite representations of things? What about read-time things that aren't really lists or values?

3. Functional programming.

Functional programming is indeed great, but why don't we talk about how in Lisps, we don't get efficient functional programming? Lisp has tended to prefer non-functional ways of doing things because Lisp will allocate so much memory during functional programming tasks that for many objectives, FP is far to inefficient. Haskell solves this to some extent with things like efficient persistent structures and compilation algorithms such as loop fusion. Lisp doesn't really have any of this, and the data structures that do exist, many people don't know about or use.

4 and 5 don't really have to do with Lisp but particular implementations. That's fine I guess.

6. X-pressions.

What the hell is an X-pression?

7. Racket documentation tools.

Okay.

8. Syntax transformations.

He made the same mistake as he so baroquely outlined at the start. What in the world are these "macros" and "syntax transformations" good for? You're just telling me they're more powerful C preprocessor macros that can call arbitrary functions. But I was taught that fancy CPP code is a Bad Idea, so boosting them is a Worse Idea.

9. New languages.

Same problem as 8. You say it's useful but you don't say why. Just that it's "easier".

10. Opportunities to participate.

Nothing to do with Lisp again.

* * *

Instead of all this glorifying of Lisp and etc, why don't we spend time increasing that library count from 2727 to 2728? Or do we need to go through an entire exercise about whether that time spent is worth it or not?

""" Rather, you are—be­cause a Lisp lan­guage of­fers you the chance to dis­cover your po­ten­tial as a pro­gram­mer and a thinker, and thereby raise your ex­pec­ta­tions for what you can accomplish. """

You're repeating everyone else. Notice how difficult it is to convey such things without being hugely abstract and unhelpful? Why don't other programmers see this huge productivity benefit from these Lisp wizards in their day-to-day life? Where are the huge, useful applications? They all seem to be written in C or C++.

""" It’s mind-bend­ingly great, and ac­ces­si­ble to any­one with a mild cu­rios­ity about soft­ware. """

It is accessible to those who are intently curious about theoretical aspects of software development, especially abstraction, and who can take exercises which require mathematical reasoning. A "mild curiosity" in my experience with others will not suffice.

* * *

This post may sound somewhat cynical and negative, but Lisp enlightenment articles are almost as bad as Haskell monad tutorials. They're everywhere and by the end, still no one gets it. And I don't like the attitude that because a group G doesn't understand it, and group H does, that H owes it to G to spoonfeed the information. That's not the case.

A couple comments:

> I dislike this notion that Lisp (or Haskell or OCaml or ...) owe it to everyone else to explain and enunciate why it can be more productive to use Lisp.

There are a couple reasons why I think this happens. The first is that people who use Lisp (or any other technology) will rightfully get excited about using it. Sometimes this translates into trying to evangelize it to other people, which is not a bad thing.

The second reason is that Lisp has a long history of 1) incubating major contributions to the field and 2) being continually marginalized by commercial practice. In many cases, this marginalization is warranted... there have been many good reasons not to use the language. In that kind of environment, it's easy to see enthusiastic users of Lisp getting a little defensive and writing apologetics about their tooling.

> What the hell is an X-pression?

He describes it, in some detail, directly in his post.

> Opportunities to participate. ... Nothing to do with Lisp again.

I do think this is an area where Lisp has unique advantages. Good Lisp systems tend to have good online documentation, good access to the underlying source code, and good interactive facilities for modifying a system.

Just as an illustration, I tend to think that Emacs couldn't really work as a closed source software package, and I don't think it would be nearly as powerful as it is with a different language than Emacs Lisp. (Eclipse is also open source, written in a very different language, and not nearly as easy to extend as Emacs.)

> Lisp doesn't really have [efficient persistent data structures]

It does now: http://www.ergy.com/FSet.html

On the syntax transformation side....

I have started to get really into what you can do with closures and coderefs in Perl. It isn't a macro in the lisp sense but it really works well and you can do some incredible things with it, and with closures and lexically scoped variables....

I suppose I should probably at some point blog about it.

I think a big part of the problem is that these are not tools you had to a beginner. They are things which take a lot of time to really master.

It benefits both groups to to enlighten G. Since G is so much larger, that's how we would increase the library count from 2727 to 27280.
Great post.

> It is accessible to those who are intently curious about theoretical aspects of software development, especially abstraction

Agreed. That's why I think it's disingenuous when people complain that Haskell folks are in an "ivory tower" or they think they're the elite. I just think they're more curious and that's why they learned it.

> And I don't like the attitude that because a group G doesn't understand it, and group H does, that H owes it to G to spoonfeed the information. That's not the case.

Exactly. I always think 'I should write this and that tutorial and then people will finally see why FP is so much easier and then perhaps...' but then immediately I think 'but I learned fine with the existing tutorials, why can't others?'.

The answer is, because most people don't care or aren't curious enough. The moment I learned of Lisp and Haskell and people gushing about it I knew I had to learn them just to see what the fuss is all about, and whether people are right in their praise. And they are right in their praise.

It takes time to learn but so does everything (for me, at least), but in the end you invariably get there, and it's more than worth it.

From what I've seen out of the Clojure community over the past few years, it seems like they're far more likely (and able) to offer up concrete examples of how Clojure makes their businesses and products successful in a way that an imperative language could not. So, yay Clojure community, and boo on hand-wavy Lisp people.

e.g.:

http://www.kreuzwerker.de/en/blog/posts/why-clojure-rocks-2/

https://news.ycombinator.com/item?id=5113060

That is also a sore point from the Lisp community in regard to Clojure.

Clojure devs are willing to compromise a bit to allow a good integration within the JVM and other implementations, thus allowing some shops to buy into Clojure.

Whereas many in the Common Lisp community will not, no matter what.

> ... in a way that an imperative language could not

Perhaps a nitpick, but sometimes nomenclature is important. Clojure (like all Lisps) is an imperative programming language. "Imperative" languages are contrasted with "declarative" languages[1]. Where does functional fit in and what is the name for "non-functional"? Well, that's not clear, as "functional" (in the PL sense) doesn't even have an agreed upon definition. Is Clojure "functional", then? Well, it's certainly not pure like Haskell is (and it has explicit loops etc.), but it does encourage more uses of function composition than, say, Java, it's more declarative, and it also isn't object-oriented, but that doesn't make it not imperative. Actually, I think even Haskell still qualifies as imperative.

But Clojure can certainly be contrasted with OO and procedural languages (even though at least one of its core abstractions -- protocols -- is borrowed from OO).

[1]: http://en.wikipedia.org/wiki/Imperative_programming

I tried Clojure, and I quite like it as a language (especially the thread-first & thread-last macros [1, 2]).

I don't, however, like the ecosystem surrounding it. I find Leiningen (while an excellent tool) far too heavy for the majority of my purposes. I much prefer other functional languages (e.g. OCaml, Haskell) that don't need such an intricate project structure.

With OCaml & Haskell, I can start with one source file in one directory and gradually build up to a more sophisticated layout as needed, rather than have a complicated layout imposed upon me by the project.

[1] http://clojuredocs.org/clojure_core/clojure.core/-%3E [2] http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E

I sure hope the giant, hideous, obtrusive diamonds inserted into the text to denote a hyperlink doesn't catch on as a trend. It's a great way to break the flow of the text and irritate your readers.

As for the idea of Lisps, well, it sure seems neat. But I've literally never run across a situation where I needed my code to edit itself. I've never run across a situation where the lack of an everything-is-an-expression-is-a-list feature prevented me from doing what I wanted to do.

So I just don't really feel the need to get repetitive strain injuries in my pinky from reaching for the parentheses all the time.

> As for the idea of Lisps, well, it sure seems neat. But I've literally never run across a situation where I needed my code to edit itself. I've never run across a situation where the lack of an everything-is-an-expression-is-a-list feature prevented me from doing what I wanted to do.

This is classic Blub paradox. You don't feel like you need a feature until you start using it, at which point you start wondering how anyone can live without it. Tools you have available limit the thoughts you can have. That's why it's always good to look for better and more powerful tools :).

As someone who writes Lisp (well, Clojure) every day and does not particularly enjoy it, I find the common complaint about parentheses to be a non-issue.

In fact, I'm not sure I've heard of anyone who wrote any significant amount of lisp code and came away talking about parentheses. This seems to be mostly a reaction from people who've read a bit of Lisp without using it.

Then again, I just noticed that I type ( and ) with my third and fourth fingers, so maybe it would be worse if I typed properly :)

If you've never had the possibility to do so before it's not surprising that you never felt the need to do it. Languages affect your way of thinking and implementing algorithms.

On the other hand, once you've tried the sweet honey of lisp macros, going back to C macros makes you sad. There's not a week that goes by without me being frustrated at the rudeness of C macros. Not to mention languages that don't offer a macrosystem at all. And the parens thing is a tired meme.

I agree with you for the diamonds though, very distracting.

"But I've literally never run across a situation where I needed my code to edit itself."

Well, "need" is a strong word. I mean, you could probably argue, in a philosophical sense, you never needed to write any computer programs in the first place (plenty of people go through life without doing so).

However, it is very likely there were times in your life where having your code edit itself would have led to getting a program working in less time, with fewer bugs, or better performance. Which of these benefits apply, of course, depend on the problem you were trying to solve.

"So I just don't really feel the need to get repetitive strain injuries in my pinky from reaching for the parentheses all the time."

Um, no. Rich Hickey has pointed out idiomatic Clojure requires fewer parens than the equivalent Java.

I mainly develop software in C# and Python at work, and I sure do miss some of the convenience that lisp-inspired languages offer. I'm responsible for the overall architecture of quite some large-ish enterprise apps. There's a reason why many Java and C# business applications have tons of MySuperAbstractFactoryProvider classes and use reflection-based look-up of metadata attributes obsessively. There's just no other way to provide a flexible framework that meets the changing and often arcane demands of our customers.

About macros, in the case of C#, what, if not a kind of macro, is the 'using' statement that works with IDisposables? If it's useful here, why not in other places?

giant, hideous, obtrusive diamonds inserted into the text to denote a hyperlink

I hadn't even noticed that they're hyperlinks, I thought something had went wrong with the text formatting or character set!

I've literally never run across a situation where I needed my code to edit itself.

Needed to is too strong a statement. I've never needed to write a macro (and in Clojure, its somewhat frowned upon to write macros when normal functions will do), but sometimes it saves you from a lot of working around limitations (and every language has limitations). It also allows things to be added to the language as libraries that otherwise would have to be built in - the majority of programmers won't need to do this, but if you do, its awesome knowing that its possible. Clojure's core.async is an excellent example (Go-style goroutine's, as a library).

I've never run across a situation where the lack of an everything-is-an-expression-is-a-list feature prevented me from doing what I wanted to do.

Of course not, but you can also do everything you want in assembly. What everything-is-an-expression-is-a-list gives you is 1) uniformity - everything works the same way, so it lowers the cognitive load; 2) simpler code - if you need a statement in an expression, you can do so, and other languages don't prevent you from getting the same result - they just take more code, or the code is more complex, or you use less-than-ideal constructs, or...

So you never need these things, but they make life more pleasant to have them.

I just don't really feel the need to get repetitive strain injuries in my pinky from reaching for the parentheses all the time.

I program in Clojure fulltime and I don't find that it has any more parentheses than a language like C++ or Java does. On top of that, anyone who programs in a Lisp for a while will use some form of paredit, which makes working with parentheses a breeze to the point where I find I type less than I do in other languages because jumping between parentheses, splicing parentheses-enclosed lists, wrapping things in parentheses and such tasks are a single keypress that just isn't possible in other less-parentheses-focused languages.

In short, just like significant whitespace in Python, parentheses are a non-issue in practice (after a short adjustment period).

But at the end of the day, to each his own. If Lisp doesn't do it for you, then that's fair enough - you don't have to use it :-)

Good call on the diamonds.

Echoing everyone else, basically, your other points are a bit shortsighted.

You never need code that edits itself - completely true. Completely missing the point. Most programming features fall into this category; you don't -need- them, you could always use assembly instead. The point is that once you get them into your brain as an option, problems that might otherwise be tricky or time consuming become much easier.

To that end, everything is an expression is a list...yeah, you don't need it either. But, assuming the above (that code that can edit itself turns out useful sometimes), imagine how easy it is to metaprogram when all your executable code is just a list, and you already know how to modify lists.

In either case, you don't -need- the feature, sure, but a moment's reflection might open up the possibility that once you fully grok the ramifications, and have it amongst your other programming tools, you'll find a good use for it.

As to too many parentheses, as someone else mentioned,

  foo(a, b, c)
simply becomes

  (foo a b c)
Not really any more of them.
If you took a Common Lisp programmer from the early to mid 90s in a time machine to today, very little about current programming languages would seem novel or an advance over what he or she was using then.

I think this is a reason for much of the smugness of Lisp programmers. Whatever features you think are new or cool or advanced about your programming language, Lisp probably got there first.

Can not resist...

This article is fairly misguided. I find it painful that everybody who writes about a Lisp offshoot (Scheme, Clojure, ...) ends up misrepresenting Common Lisp.

To sum up "Why Lisp?" from a CL perspective: CL has pretty much every feature of every programming language around, only that its better designed, implemented and generally more powerful. It's just a poweruser language. Its not just macros, sexps and lambdas. Its also number types, arrays, OOP, symbols, strings, structs, dynamic/lexical variables, lambda lists, multiple return values, on-line disassemble, exceptions, restarts, MOP, metacircular definition, great implementations, great libraries...... the list goes on and on... I surely forgot a ton of great stuff. TL;DR: CL got everything. And this "everything" is designed so well that its extensible and no CL programmer ever needs to doubt that any new feature can be implemented easily in CL.

To correct a few of the wrong statements of OP:

> “Wait—I love state and data mu­ta­tion. Why would you take them away?” Be­cause they’re false friends.

CL is NOT particularily functional. Just because we know how to write good side-effect free code, doesn't mean its a functional language. (We jave SETF after all, failed to mention that aove).

> a syn­tax trans­for­ma­tion in Racket can be far more so­phis­ti­cated than the usual Com­mon Lisp macro.

Outright wrong. The only reason Scheme has weird macro systems is because its a Lisp 1. CL is designed well (thus being a Lisp 2), and thats why its simple but ultimately more powerful macro system can work.

> A macro in Com­mon Lisp is a func­tion that runs at com­pile-time, ac­cept­ing sym­bols as in­put and in­ject­ing them into a tem­plate to pro­duce new code.

This is so wrong I had to write this comment. A macro in Common Lisp is a COMPILER, it accepts arguments and returns an SEXP. It is infinitely powerful, it can do EVERYTHING.

The top reason here could been written - lisp is more expressive. You can find ways to express an idea that make sense now, and which are readable. Macros is a different part of the same idea.

--

Maybe I'm doing it wrong, but a problem I've had with racket is as you begin to build larger projects, when something breaks it can be quite difficult to find out exactly where the break happened. When you compile Java or run Python, it's almost always immediately obvious what broke.

The way I got around this was to use a methodical TDD approach. Would be a shame if that turns out to be as good as it gets for lisp.

Something I haven't done yet but am interested to get to is attaching a repl console to a running process.

The manual to this publishing system, discussing how its markup/programming language is implemented as a custom Racket language, is pretty interesting: http://mbutterick.github.io/pollen/doc/
It seems most people here have never used (and not tried) racket.

I decided to use racket for my little sides projects, as replacement for scala and clojure.

I choose it because it was clear for me i can't stand limitations other language impose to me in way of style and boilerplate, the racket macro (aka syntax transformer) system is the most advanced i know to reduce the boilerplate to a minimum and so just write what i want to express. In facts i rarely write macro because writing a good macro demand you take care of errors syntax, i am lazy in the bad meaning of the term.

I choose it because it's dynamic typed and i get more convinced that type go on your way most of the time (expect complex algorithms)(i write little projects, so refactoring argument is out). It enable me to write code and eval it on the fly with geiser (using enter! on the back), after eval the new function i test it in the repl, hack until the function meet the requirement copy paste from repl and boom i get a unit test. Because it as eval and it will become handy one time in your programmer life for sure.

I choose it because of it's sexpr syntax, as a heavy user of emacs i know that other syntax is a pity.

Also because it has (and i use):

1. llar parser (implemented through a macro).

2. A pattern matching nothing to envy scala or clojure deconstructs.

3. An optional type system.

4. A contract system.

What i find hard as a new comer (to racket, not as a programmer already now scala, clojure, half of c++ :), php) is

1. The broadness of the features the language offer, which feature to use e.g.: class or generics.

2. The documentation is rich but lack of examples for the common cases, so you need to read the doc of the function (sometime it's huge).

3. Understanding how racket module works is quite hard and you have the documentation, if you don't plan to play with the macro expander (the stuff that run your macro) and some dynamic features you don't really need to.

4. You need to 'register' the errortrace library if you want a stacktrace, quite a surprising behaviours for me.

My opinionated conclusion:

Racket is the best language design i ever see, it's hard to learn but make you feel learning an other language will just become to learn a new sub-optimal syntax. Sadly the ecosystem is lacking libraries and peoples and i am not helping in this way.

Author is wrong about hygienic macros – they are not more powerful. They are less powerful, and more complicated, in order to enforce safety. Whether this is preferable or not is a matter of debate.
Some practical features I enjoy in CL:

1. Conditions and restarts: As far as error handling in programs go this is the most rock-solid system I've encountered. You can tell the system which bits of code, called restarts, are able to handle a given error condition in your code. The nice thing about that is you can choose the appropriate restart based on what you know at a higher-level in the program and continue that computation without losing state and restarting from the beginning. This plays well with well structured programs because the rest of your system can continue running. Watching for conditions and signalling errors to invoke restarts... it's really much better than just returning an integer.

As a CL programmer using SLIME or any suitable IDE, this error system can throw up a list of appropriate restarts to handle an error it encounters. I can just choose one... or I can zoom through the backtrace, inspect objects, change values in instance slots, recompile code to fix the bug, and choose the "continue" restart... voila the computation continues, my system never stopped doing all of the other tasks it was in the middle of doing, and my original error was fixed and I didn't lose anything. That is really one of my favorite features.

2. CLOS -- it's CL's OO system. Completely optional. But it's very, very powerful. The notion of "class" is very different than the C++ sense of struct-with-vtable-to-function-pointers-with-implicit-reference-to-this. Specifically I enjoy parametric dispatch to generic functions. C++ has this but only to the implicit first argument, this. Whereas CLOS allows me to dispatch based on the types of all of the arguments. As a benign example:

    (defclass animal () ())
    (defclass dog (animal) ())

    (defgeneric make-sound (animal))
    (defmethod make-sound ((animal animal))
      (format t "..."))
    (defmethod make-sound ((dog dog))
      (format t "Bark!"))

    (make-sound (make-instance 'animal))
    (make-sound (make-instance 'dog))
Will print "..." and "Bark!" But the trivial example doesn't show that I can dispatch based on all of the arguments to a method:

    (defclass entity () ()) ;; some high-level data about entities in a video game
    (defclass ship (entity) ()) ;; some ship-specific stuff... you get the idea.
    (defclass bullet (entity) ())

    ;; ... more code

    (defmethod collide ((player ship) (bullet bullet))) ;; some collision-handling code for those types of entities...
    (defmethod collide ((player ship) (enemy ship))) ;;; and so on...
Conversely...

    Ship::collide(const Bullet& bullet) {}
    Ship::collide(const Ship& ship) {}
Where collide is a virtual function of the Entity class requiring all sub-classes to implement it. In the CLOS system a method is free from the association to a class and is only implemented for anyone who cares about colliding with other things.

The super-powerful thing about this though is that... I can redefine the class while the program is running. I can compile a new definition and all of the live instances in my running program will be updated. I don't have to stop my game. If I encounter an error in my collision code I can inspect the objects in the stack trace, recompile the new method, and continue without stopping.

3. Macros are awesome. They're like little mini-compilers and their usefulness is difficult to appreciate but beautiful to behold. For a good example look at [0] where baggers has implemented a Lisp-like language that actually compiles to an OpenGL shader program. Or read Let Over Lambda.

One of the most common complaint I hear about macros (and programmable programming languages in general) is that it opens the gate for every developer to build their own personal fiefdom and isolate themselves from other developers: ie -- create their own language that nobody else understands.

Examples like baggers' shader language demonstrate that it's not about creating a cambrian explosion of incompatible DSLs... it's about taming complexity; taking complex ideas and turning them into smaller, embedded programs. A CL programmer isn't satisfied writing their game in one language and then writing their shaders in another language. And then having to learn a third language for hooking them all up and running them. They embody those things using CL itself and leverage the powerful compiler under the floorboards that's right at their finger tips.

Need to read an alternate syntax from a language that died out decades ago but left no open source compilers about? Write a reader-macro that transforms it into lisp. Write a runtime in lisp to execute it. I've done it for little toy assemblers. It's lots of fun.

... this has turned into a long post. Sorry. I just miss some of the awesome features CL has when I work in other languages which is most of the time.

[0] https://www.youtube.com/watch?v=2Z4GfOUWEuA&list=PL2VAYZE_4w...

A good list of some interesting 'day to day' benefits of Lisp. Maybe that is something that would appeal to beginners especially.

From my perspective Lisp is a powerful language because of its genesis in research. The question wasn't "How do we make a tool to make this hardware do what want?" but rather for a research goal.

If you want to read the actual original Lisp paper look up: Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I John McCarthy April 1960

Paul Graham covers it nicely in this essay, especially the "What made Lisp different" list about 1/3 in http://www.paulgraham.com/icad.html

Lisp has had expressiveness we're only recently seeing in popular mainstream languages now. It has to do with the design, the simplicity, and how Lisp expresses problems. I've often heard it described as "the language gets out of your way." That's why Lisp.

Why Lisp? That is understood.

Why Racket? From an ignorant outsider's perspective, all Lisps seem to be more or less interchangeable when it comes to the language. They only differ in the details, and each seems to be about as difficult to learn as the other. Although this article does make somewhat of a case for specifically Racket, it seems to be a rather weak one - tools are nice and some language details are nice. But the same general arguments can be made for other Lisps, most notably Clojure. It seems to me that Clojure is a lot more practical: it has many good libraries in both Clojure and Java, it has some great tools, there's a lot of momentum, and it can be deployed everywhere (including the browser).

So, being an ignorant outsider, is there any reason the Lisp I should learn isn't Clojure?

RacketCon is being held in Saint Louis, Missouri, USA the day following the Strange Loop 2014 conference (also in Saint Louis):

http://con.racket-lang.org/

I hope to see some of you there!

Check it out. For five years I have been developing a tool called TXR. It's a "Unixy" data munging language that is ideally suited for programmers who know something about Lisp and would like to move away from reaching for the traditional stand-bys like awk, sed, perl, ...

You do not have to know any Lisp to do basic things in TXR, like extracting data (in fairly complicated ways) and reformatting it, but the power is there to tap into.

In TXR's embedded Lisp dialect, ("TXR Lisp"), you can express yourself in ways that can resemble Common Lisp, Racket or Clojure.

You can see a glimpse of this in this Rosetta Code task, which is solved in three ways that are almost expression-for-expression translations of the CL, Racket and Clojure solutions:

http://rosettacode.org/wiki/Self-referential_sequence#TXR

Or here, with syntax coloring:

http://www.nongnu.org/txr/rosetta-solutions-main.html#Self-r...

If you closely compare the original solutions, you will see that certain things are done more glibly in TXR Lisp.

> If Lisp lan­guages are so great, then it should be pos­si­ble to sum­ma­rize their ben­e­fits in con­cise, prac­ti­cal terms.

His list is concise but man did he take a while to get to it!

Seriously though. The introduction was super relevant as I have wondered the exact same question about Lisp myself. What features make it so praise-worthy? Maybe X-expressions isn't a core feature for everyone to appreciate, but the fact that everything is an S-expression is an understated value. People complain about its syntax, but alternate versions (so many reincarnations of parentheses-less Lisps) have never caught on.

The thing is, Lisp is no longer unique in its feature set, and languages with more standard forms of syntax have incorporated some of its features. But it is uncommon to find all of these listed features in one language. In the domain of data analysis where I do most of my work, it still makes me sad that XLISP-STAT has been supplanted by other languages which leave the user wanting.

Agree with some of the earlier comments: the diamond-shaped thingies inserted are really a nuisance and breaks the reading flow.
Does anyone else find it difficult to highlight things on this page? Specifically, 'kvetchery' which is found in the third paragraph.

I believe the author is the one responsible for the facelift of Racket's documentation. He may belittle his own lack of formal programming education but I am thankful for his design chops.

I am learning Perl's FP features and really liking it, and teaching myself common lisp. I enjoyed the article quite a lot actually.

I find it is very hard to define functional programming for many people but this is what I have come to explain to people:

Functional programming means thinking in terms of mathematical functions in the f(x) sense. Once you get that basic promise, that for any given input you have a single correct output, then it transforms the whole way you think about and designing your software.

The better I get with lisp, the more everything else changes. I may have to try Racket.

I tried somewhat Pollen and it's kind of fantastic, the only thing is getting to work with a new project in a language that I don't know very well is difficult for me. That's why I started a similar project in Python, watch https://warehouse.python.org/project if you interested /azoufzouf/
Not sure how closely you have read Siebel - your 1st few points are covered pretty comprehensively at the start of his book
I think it's kind of sad that most of the comments in this thread are about other languages than Racket and only barely touch on the articles points (mostly the stuff you don't need to actually try the language (or any lisp) to comment on). I think it says a lot about what the crowd on HN is really all about.
My personal experience with Clojure has been that it 'bends' the brain - in a good way, and it forever changes the way you program. It is extremely difficult to go back to the style of coding I did before my exposure to Clojure. I guess other Lisps would provide a similar experience.
Nice write-up. I really like Racket, but never had a chance to use it in a professional project so far.

By the way, Scribble (item 7) is an implementation of Literate Programming - a feature is some other languages too. In Haskell, for example, you can write programs in Latex with embedded code.

Re 1. everything is an expression benefit, condition example:

C-like languages often have the ternary operator, cond?exp1:exp2, that is exactly this. I feel clever using it, but I consider it a hack, because it's (usually) less clear. A microcosm of lisp, clever but unclear.

Many of the last items in the list should be in the category "Scheme". Racket is a dialect from Scheme, but it still is a Scheme. The syntax-case macro transformations are available in most Scheme systems.
Is it just me or is this page entirely blank? I poked through the source for quite a long time, but couldn't undo it. The text is there. There is something in the CSS that obscures it in Chrome. So annoying.
Why does Racket perform so slowly on benchmarks compared to Clojure and SBCL?
When visited with w3m I got spaces breaking words frequently. Is there any justification to use complex html to control intra-word spacing for a web page?
Many of the reasons you wrote are the same that got me attracted to Elixir. That and of course erlang interop and OTP.
It's kind of interesting that the author's examples of 'woah! look at all these cool packages' include plotting, unit testing, and a gui. Those standards feel a little low to me.
"Clarity is an evidence" as the saying goes. This post only proves its correctness.)

The distinct feature of Lisps and good lispers is clarity of thought and conscience of writing.

That's some pretty ugly text for a site called 'practical typography'.
Please.... text-align: justify; ...