I do love ruby and feel that it's metaprogramming techniques to allow you to easily emulated many features of Lisp's macros.
That said the author missing an obvious thing here. They key with macros is that they allow you to alter syntax (not calculate values as many who try initially misunderstand them), and s-exps are essential to being able to do this (because they are effectively an abstract syntax tree).
I say this is obvious because the example itself demonstrates this.
The lisp code in the end looks very much like the ruby. Being able to extend syntax means that if you like ruby you can make your lisp work more like it. Now try to reverse this example, make a ruby library that emulates a lisp style, I think you'd find it much more difficult, and expensive.
The other important thing to not forget is that this syntax transformation happens at compile time. One of the reasons that Ruby has a reputation for being slow is it has to keep track of a lot of metadata and all sorts of look-ups to do a lot of the metaprogramming (which is why people should make better use of it, you've already paid for it). In Common Lisp all this transformation is free during runtime. Think of a common issue with JavaScript: no implicit return. If Lisp did not have implicit return you could define a macro 'defr' which allowed you to define functions like you normally do, but always know they return a value. Instead you need to use CoffeeScript.
Finally people do still write plenty of Common Lisp, they're just a smaller community. Not long ago I wrote myself a very practical tool to process a specific file format, with it's own mini-dsl, an order of magnitude faster than similar libraries (albeit with intentionally less functionality) and all in 200 lines of Common Lisp.
It's certainly true that Lisp's super-simple syntax makes it much easier to have a powerful macro system. Dylan macros are like Scheme's hygienic macros, based on pattern-matching and not as flexible as CL's fully general code-generating macros -- but still pretty powerful. (And there's an unofficial procedural macro system too, which I haven't looked at but I understand gives you CL-like power without too much pain.)
If you like Lisp, take a look at Clojure. I know it has been highly hyped here, but seriously, a very interesting language, which combines the beauty of lisp and practicality of java runtime.
I feel for the author and have recently come to a similar (read: not same) conclusion: Lisp is pretty crappy for maybe 90% of the work being done out there. The more easily-accessible and popular a domain is, the worse Lisp will be for it. This isn't because Lisp magically gets worse; it's because other languages get better, through libraries. Even if nine of ten libraries are crappy, there are enough people in the space (remember, it's a popular domain) that something good will come out of it, and eventually everyone will basically settle on a few good choices.
Lisp programmers, when using Lisp for what it's best at, don't use libraries. There are no libraries for what they want to do, because what they're doing is obscure and/or hard.
Lisp is best at doing new things that have never been done before, because it's basically a language for writing libraries. As such, it prospers in unpopular fields.*
This makes it hard for lisp evangelists to be taken seriously. If you're to show someone a hard graphics problem written in lisp vs ruby, your reader has to understand graphics programming first. But calculating primes? Anyone can do that. Which example do you think will get more mindshare?
To summarize: Lisp is great at things you don't hear about.
* One reason Viaweb succeeded using Lisp for the web was because the web was still this exciting frontier and no one had really done anything with it yet. I'd go so far as to say that Viaweb wouldn't succeed today---they'd get trashed by the likes of Weebly, which is written in php for crying out loud.
From what I've seen this role is now played as much, if not more, by languages like Scala and Haskell. Certainly languages like that owe a large debt to Lisp but I'm not so sure what you say is as true of Lisp today as it once was.
I agree and should note that pure functional languages more suited for writing libraries than languages with some first-class functional features. This is so because pureness encourages composability of various parts of program.
The state allows parts of program to communicate through implicit information channel. One part of program could signal another to increment a variable by deleting a file. Or vice versa.
That's why I think Haskell is the best for libraries, Scala less so and Lisp even lesser, even taking into account macro system, code-as-data, etc.
I absolutely adore clojure, and whenever I do a non-sysadmin project on my own, I like to use it.
But I'm still at the point in my career where people hire me rather than the other way around, and all the hand-waving I can do about "superiority of lambda calculus over the state machine" (okay, I'm more clear and practical than that) doesn't convince many.
I think it's more subtle than that. An interesting program usually contains parts that are "easy" (e.g. interfacing with a database) and parts that are "hard" (e.g. complex algorithms). To be productive, you would want to get the easy bits out of the way so you could concentrate on the hard bits.
Making Python or Scala talk to Oracle (for example) is so trivial you can write that bit of your program in no time at all, then get onto the interesting stuff. In Lisp, you have to spend significant time on this trivial stuff. So if you are writing a program on your own PC for your own use, then Lisp is fine. If you are programming anything that is going to run on existing infrastructure or interoperate with other programs, it's very difficult to justify the additional effort of using Lisp.
And I know a bit about this: I wrote Oracle bindings for OCaml! It was fun, sure, but can I justify it when there are already Python bindings? Hmm.
> In Lisp, you have to spend significant time on this trivial stuff. So if you are writing a program on your own PC for your own use, then Lisp is fine. If you are programming anything that is going to run on existing infrastructure or interoperate with other programs, it's very difficult to justify the additional effort of using Lisp.
Your point is plain to see, and it is correct in principle, but there are plenty of bindings for Lisps too. As far as I understand, making CL talk to Oracle is a battery included in the commercial implementations, or available through CLSQL (and therefore through higher-level libraries built on top of it such as Elephant). Sure, CL may not have all of the latest and greatest, but plenty of languages don't either. While I cannot pretend to approach any sort of "hacker-level" competence in Lisp (I'm not even a programmer really), I have yet to find a relatively trivial task (where my definition of trivial is "included in Python's standard library or a very widely used / de facto standard module", since I'm coming from Python) for which there isn't a usable (and often excellent) Lisp tool. YMMV, of course.
I think I'm pretty safe saying there are a ton. Every Lisp hacker has their own.
Actually, "library" is probably the wrong word for reused Lisp code. A library is a public thing, an institution---and all that goes with it: slow to change, must be easy to understand, etc.
Instead of libraries, Lisp hackers have private collections. Like a messy desk, they are often supremely useful once you get the hang of it, but are inscrutable to others. Not exactly the best characteristics to get popular on github.
I don't know where you're coming up with this impression at all. Clojure has Leiningen and Maven, Racket has PLaneT, CL has QuickLisp, etc. In my experience Lispers do not waste time solving solved problems.
I think that Zach Beane is doing a stupendous job with quicklisp. Of course it's nowhere near CPAN at this stage, but it's a tremendous step forward compared to, say, plain asdf-install.
Having spent 3 years with Clojure, I believe that Lisp macros are just as powerful as they say. But no need to take my word for it ... checkout the paper "Languages as Libraries" by the folks behind Racket.
I've created 3 libraries that I think would be exceedingly difficult, excruciating, or impossible to write with the performance and the level of control over syntax in anything but a very good Lisp:
A ton of responses and no one mentions the one-word answer?
"homoiconicity": the property of a language whereby code written in said language is stored, in a natural and immediate fashion, as a data structure of the same language
What this means for Lisp is that if you want to manipulate Lisp code, you aren't dealing with some crazy complex AST: you can actually /see/ how the code is parsed by looking at the code itself, as the code is actually typed using the serialization format for the primary data structure of the language: S-expressions.
So, you aren't just creating a little "DSL" by using some built-in syntax tricks like "implicit last argument block", but instead are able to write code that modifies code and generates code as easily as if you were writing the original code in the first place: the comparison to Ruby is therefore fundamentally flawed.
(Finally, as an unrelated bonus: the parser for Lisp is also written in Lisp and available during the execution of Lisp, so you can have code that modifies and extends the parser itself allowing you to fundamentally alter the syntax to, for example, look like Ruby; this mechanism is called "reader macros", for the record.)
"... but instead are able to write code that modifies code and generates code as easily as if you were writing the original code in the first place: the comparison to Ruby is therefore fundamentally flawed."
This. The ability to easily reason about the code and manipulate it because its syntax is simple and predictable is the big deal to me.
I think this is analog to switching from Roman to Arabic numerals. The syntax is regular. No matter how big the number is the rules are the same. There are no exceptions. Hence doing calculations with the former is a lot clumsier than with the latter.
That's the ideal scenario at least. I do realize that math might not be as simple as it could be, but I'm not really qualified to argue about that. But what if we were still using Roman numerals today? Would we be at the level of understanding we are at right now? It seems to me that it's more or less the same thing when you start understanding Lisp and why it is the way it is.
This is just too big of a tradeoff to be ignored. In my experience choosing the simple and regular solutions paves the way to progress, in which useful things that look trivial now would be rightly discarded or would be viewed as too complex if our mental model were grounded on the previous clumsy framework.
Now, I'm not saying "just drop all your clumsy languages right now, because today we have a better idea, and start using Lisp". I certainly don't do that. I don't even work with Lisp. But my point is that not realizing that Lisp has some properties that make it special is perhaps hindering yourself of being able to see that some things can be a lot simpler than you thought they could be.
> A ton of responses and no one mentions the one-word answer?
Statements like "You can easily do this is Ruby" hint that author understood exactly nothing and focused on some random uninteresting example code while missing big picture.
Does Ruby have COND?
If it doesn't, can one implement it using existing Ruby constructs?
If it does, can one implement it using existing Ruby constructs except COND?
I don't believe this is a good example. Ruby has case..when instead of COND, though it's a language construct, not a function; but I think COND can be trivially implemented in any language that has anonymous functions. In Ruby:
> instead are able to write code that modifies code and generates code as easily as if you were writing the original code in the first place
Is this often done? I know it is conceptually possible with the advantage being that the same functions used to manipulate lists and data are available for this task, but I got the impression that not many people actually do this? For instance...
AFAIK this is actually incredibly common. The example that springs to my mind is people writing matrix libraries that manipulate the code to "compile" it to use more efficient algorithms. People do this kind of thing in C++, such as in Blitz++, but you end up having to pull heroics with the type system (and end up with some pretty abused syntax at times) to accomplish what is much easier in a homoiconic language like Lisp.
I've been using Common Lisp for quite a few years now yet I have written very few macros (although I have used a great many written by others!), however there's times when you need their power when nothing else will do.
Also because you can modify the syntax with them they can really clean and clear up your code.
The macro example used is meant to be instructive, not a demonstration of how powerful macros could be.
Consider https://gist.github.com/1119534, which demonstrates a pattern-matching syntax that (at compile-time!) constructs a minimal traversal of the data structure to find a match. The only way to do this in a language without macros is to write your own compiler.
> You can fake it anywhere else with more or less work
That doesn't make sense, because there's no way to twist it. It's more work and duplication. I want macros all the time in JavaScript and that is a pretty flexible and dynamic language.
Most of Lisp's other features are common now. Macros are still a big one but you don't need them every day. Lisp has powerful exception handling but I'd rather have Erlang style error handling and recovery.
Lisp's draw is waning but only because our languages are lispy in ways that really matter. We have dynamic, garbage collection languages with REPLs and built in high level data structures that are even better because we have native syntax for them. I don't want to keep track of N different kinds of assoc lists... and I really like Lisp.
Special variables, restarts and flexible reader are some of the basic features, that are not only uncommon, but, actually, unseen in any other language. Just to name a few.
There's nothing inherently Lispy about conditions and restarts but they are often cited as one of "Lisp"'s strengths. Sorry for continuing to conflate Lisp the concept with CL.
I had similar thoughts when I was first learning a lisp. Unlike the author, I was enamored with the lack of syntax and the expressive power that was there. Sure, it's a Turing-complete language like any other, but for me it was a pleasure to hack with. Not only that, but you can actually do things with it (manipulate the language itself, from within the language itself…whoa) that I would only later realize the power of. Turns out you rarely need to use that power.
for the same effect. And I really was happy to write that. It makes sense.
NB: I'd never put such code into production, and I think it should be a warning sign that a purported problem in a language/dialect be based around minimal experience regarding an example.
I mean, yes, the biggest win of lisp over other languages is that the metalanguage is the language. That is what is special about lisp. That is, when defining a macro, you are simply treating the program itself as data. Since code and data take the same form, this is a really natural way to metaprogram. In most other languages, it is... not.
Now, the featured article picks a... not very good example, for this feature of the language. But that doesn't mean that metaprogramming is useless. Much of a (big) lisp program is building up a domain specific language out of macros, then solving the problem at hand with it. This is the biggest power of lisp, and also the biggest weakness--every lisp program is written in a different language.
In lisp you express your problem in macros, and then express your solution in the language you've built up.
Homoiconicity is part of the answer. The other part is that Lisp is built up from a small number of axioms (probably the smallest such number) that are Turing-complete and at the same time are a language that people would actually want to use.
As pg says: "In 1960, John McCarthy published a remarkable paper in which he did for programming something like what Euclid did for geometry. He showed how, given a handful of simple operators and a notation for functions, you can build a whole programming language. [...] It's worth understanding what McCarthy discovered [my emphasis], not just as a landmark in the history of computers, but as a model for what programming is tending to become in our own time. " http://www.paulgraham.com/rootsoflisp.html
Why does pg say McCarthy discovered Lisp, not invented it? I think because it's something of such simplicity that one can imagine others inventing the same thing. So if humans contacted intelligent aliens, it wouldn't surprise me if they had independently invented Lisp, just as it wouldn't surprise me if they'd invented prime numbers, or cartesian co-ordinates.
"Because coders DO NOT LIKE LISP. Most programmers find Lisp unpleasant and unnatural to use. They're not idiots, they're not ignorant, and they're not willfully choosing a less-powerful or less-efficient tool, they're choosing tools based on what makes them productive and happy."
The "profound enlightenment experience you will have when you finally get [functional programming]" [2] is a mystery that I've been trying to figure out, albeit slowly since the day only has 24h. I've gone through the Peepcode video on Clojure and I couldn't find an answer, and I didn't even feel attracted to the language, quite unlike my first Ruby experience.
Then the other day I watched Matz - creator of Ruby - talking about Ruby 2.0, and he used the word "happy" multiple times to explain how he wants developers to feel when using his language, and I thought of how brilliantly he's succeeded. I have now spent more time coding in Objective-C than any other language (iOS development), and every hour I code Objective-C I miss Ruby and how happy it makes me feel.
I find that happiness is highly overlooked in discussions about programming.
> The "profound enlightenment experience you will have when you finally get [functional programming]" [2]
Nitpick: the quote is not exactly about functional programming, it's about Lisp. Though Lisp is often used as a functional language, there are very lisp-ish features such as macros and the (lack of) syntax that you will not necessarily find in other functional languages.
That said, if you want to learn functional programming but are put off by Lisp's feel, you could try Haskell or OCaml or F#.
Have you looked at "The Joy of Clojure"? I thought the authors did a very good job of showing why exactly they're so excited to be working with the language.
In any case, this is very much a question of discourse. For historical reasons Lisp (at least Common Lisp) seems to have this reputation of being associated with deadly serious people, or alternatively smug lisp weenies, while Ruby people talk about how happy it makes them feel all the time, even though there are plenty of people who clearly have fun with Lisp (even "crufty" "old" CL), and I'm sure many people would regard working with Ruby a chore. I mean, to each his own, I honestly can't imagine there's an objective scale on which CL (much less exciting new languages like Clojure) is "less fun" than Ruby. Things like homoiconicity, on the other, are objective criteria for comparing languages. There are plenty of reasons to like (say) Python better than (say) CL, but to say that homoiconicity or restarts or MOP are no big deal because if you try hard enough you can replicate 95% of that functionality in (say) Perl is a different question entirely.
That was pretty much my point. That maybe the solution to the mystery of the "profound enlightenment experience" around Lisp is that it makes some very happy, but not me.
Have you looked at "The Joy of Clojure"?
I haven't, I'll look into it, thanks. I haven't given up on solving that mystery yet.
I think whole point of comparing programming languages from this angle is pointless. You should not go and judge a language by several phrases. Go speak/write/read it for a while, learn some slang.
Like all other languages, programming languages are also just that, languages - tools to express your thoughts. To me and many others Common Lisp reduces the friction between those thoughts and written description of them. It is so much more to this language than just its syntax and politics. It is joy to develop in thanks to SLIME, it almost never gets in your way, it performs, it has wisdom of half a century and people who possess it. Yes, it is far from perfect, but then again - there is no perfect language! and even if there was one it would sound like those studio processed pop-star voices rather than perfection to me, because it would still superimpose its perfection over you own views.
In other words, please don't judge the language by how you can pronounce "how can I get to the city centre", it sounds similar in most.
Now all this spoken/written language comparison might sound weird to you, but to me it makes perfect sense, because programming to me is nothing but a dialogue between me, computer and the future version of me reading the source. And I like the language which allows me to do this on my terms, rather than that of Guido, Matz or whoever. And to me Common Lisp is pretty close to that.
P.S. Just as a side note, folks on #lisp and #sbcl are one of the most pragmatic and intelligent people I have ever seen, I learned more from their discussions than by reading a couple of books. To any of you reading, rock on Lispers ;)
In general, Lisp doesn't seem special anymore because (1) language implementers have taken Lisp's most important lessons and applied them to their own languages and (2) said languages have become relatively popular.
A Common Lisp variant of an excercise found in the Seasoned Schemer:
(defun sum-of-prefixes (tup)
(let ((sonssf 0))
(loop for n in tup
do (setf sonssf (+ sonssf n))
collect sonssf)))
The variable 'sonssf' is an acronym for "sum of numbers seen so far;" this function creates a list of sums of all numbers it visits as it traverses the input list.
It's a simple bit of code that I go into in more detail with an example in Python and Scheme: http://agentultra.com/?p=670
The reason why I think Lisp is a great language is that I haven't yet needed to use any "patterns" in any of my (admittedly small) projects. Patterns, IMO, are boilerplate code to work around the limitations of a language. I haven't encountered a need for that in Lisp yet. It's a good sign to me.
I also have dynamically scoped variables, generic functions, parametric dispatch (or multimethods or whatever you call it), macros, and a very powerful OO system if I need it. Best of all is that all of it is unified by a small amount of syntax, backed by a small set of axioms, and surrounded by a wonderful (but small) community.
Ruby is a denser functional language than LISP.
This is just not true! Sure sometimes you have syntax suger in Ruby that makes something smaller but othertimes you don't in lisp I can always make everything smaller with macros. I would bet that Ruby is not shorter for most programmes.
His hole argument is based around that in lisp you have wo write (lambda ....) and in Ruby you don't.
Ruby gives you about 80% of what you want from macros
Ruby may give you some of the power but there is a lot you cant do in ruby and its much, much harder to do those things.
Ruby’s libraries, community, and momentum are good
Thats nice but has nothing to do with being lisp.
Not saying anthing against ruby but this article is just very strange.
I have a question for those that have done a lot of programming in Lisp: Is macro programming a really big part of Lisp programming? I mean, what percentage of a typical project would be macros?
I ask the question because you can achieve the same results in most dynamic languages by grabbing the string representation of a function, run it through a parser, modify the resulting AST and then regenerating the function string before passing to an eval (CoffeeScript being a good example of this approach). Sure, it's messier than in Lisp, but in return for the messiness of macros, you get much easier to read syntax in most of your code. Is the use of macros really such a big part of Lisp programs that it justifies the lack of syntax everywhere else?
Macros are not something you need everyday (at least not your own macros) but when you need them you really need them. CoffeScript is a good example, if JavaScript would have been a real lisp there would be no need for CoffeeScript at all because you could build it in JS.
Your example of meta programming is very very messy and putting eval everywhere would also be a security nightmare and if you do it this way you don't end up with nice syntax.
<-- People don't really use this because of those reasons.
Macros are not messy to use they look like a normal function that meens often you don't even know or care if something is implmented in a macro or a function.
The other big part of the macros look like language build ins for example in a REST-Framework you would have something like 'defresource'. The auther of the framework can give you the best syntax to discribe what his library does. (Look on Stackoverflow for DSLs in Clojure)
Writting good macros your self is a little harder and can look wired because your just not used to code looking like this.
The USE of macros is a REALLY REALLY big part of every lisp programm because the HOLE language is build on macros. Almost everything that is normally build in the compiler is just a macro.
Firstly, CoffeeScript is built in JavaScript. Does that make it a 'real' Lisp?
Secondly, Lisp macros are every bit as big a security risk as using eval... That is what the E in REPL stands for, after all. In both cases, if you are taking input from source code, and not from outside sources, there is no security risk.
Thirdly, yes, my example is messy. But it is still doable, and I just have a hard time believing that this kind of programming is a major percentage of the code of a Lisp program. To be clear on that comment, I can easily believe that you end up invoking macros a lot, but I don't believe that a large percentage of the code written for a project is actually macros. What percentage of code in a typical project is macros? And how many of those macros can be easily reproduced by using specialised syntax of a language such as ruby (optional parantheses, blocks, re-opening classes, method_missing, etc)?
This is an important point, because if you only have a few hundred lines of this stuff in a typical Lisp program, and it can be reproduced by using a parser in another (dynamic) language, then the advantage just isn't that big. For argument's sake, imagine having a module available in Javascript that provides the Jison parser along with the Javascript grammar, which just re-emits the original Javascript source. In addition, it has a nice API to allow you to modify the grammar (adding / modifying rules). So far so easy, this stuff already exists in CoffeeScript, go copy it from there. Now, having loaded such a module, is Lisp really in a much better position than this modified Javascript?
In any language you can build a interpreter/compiler for any other language but thats not the point. The point is that you can do random AST transformation at compiletime.
You think of macros as a kind of pay of for s-exp syntax. I have to say that even without macros I would think s-exp syntax is nicer. Sure in Ruby you can do alot when you play around with that suger stuff but this stuff often doesn't come free. See this blogpost for an example of what I mean: http://briancarper.net/blog/579/keyword-arguments-ruby-cloju...
Depending on what you do you are writting a lot of macros. In lisp the interface to a library is almost always in a DSL style witch makes them easy to use. See this list here: http://stackoverflow.com/questions/3968055/are-there-any-clo.... In your own Application your maybe not going to need them that often depending on what you do.
What you discribe is just a macrosystem. Having macros in a language with syntax is duable (look at Dylan or Plot) but you will find that getting everything nice and easy to use is much harder then you think. If CoffeeScript has a macrosystem great. I don't really know CoffeeScript well enought. Could you provide me with some nice examples of how people use this in CoffeeScript?
If I where you I would just learn enought lisp that you can trie it out yourself.
How would you implement a new control structure that way? I think it won't be possible unless you write a parser for the whole language.
Take clojures "or" for example, it's just a macro. The language has only very few primitives [1] and that's the language, everything else is built out of that.
What's special about Lisp? Simplicity. No syntax means you don't have to parse code when reading it. Each construct's scope is clear. Whenever I code for a while in Lisp and then have to go back to C or Java, I find myself uncomfortable. Not so the other way around.
Really like this counterpoint after all the LISP elitists so often snub other langs. The Ruby version is much more elegant and readable, in this little example. Would love to see more comparisons, specifically hacking around the lack of macros in other langs.
It's hardly much of a counterpoint considering Ruby took a great many ideas from Lisp. If anything, it's a rant about syntax. Overall though, it shows that Lisp did get it right. People love Lisp so long as it's dressed up to look like a non-Lisp.
Being a Lisp enthousiast myself I often find those LISP elitists are people new to the language repeating the tired arguments we have heard so often before.
I "got it" after reading a bulk of SICP and watching some buddy-lectures at http://academicearth.org/courses/the-structure-and-interpret... (I've also started SICM: it's awesome how they use Scheme.[1]) Nevertheless there's still a level I have yet to reach that I hope to achieve with Clojure (which has recently jumped to the top of my list of languages to learn). While Lisp (Scheme in particular, though CL is nice too) is near my heart, my brain still thinks in Python, Python makes me Happy, and that hinders my speed and concentration when I do stuff in Lisp. I liken it to my experience trying to (unsuccessfully) master Dvorak. The layout was easy to memorize so I could touch-type, I could easily see the benefits, and if I ever get spasms in my hands I'm going to force myself to switch over, but dropping from 80-100wpm down to 10-30wpm was too much loss that I didn't let my finger-muscles relearn and so I'm still with QWERTY.
[1] Even though it's trivial I still adore this simple example:
guile> (define D derivative)
guile> (define f (literal-function 'f))
guile> (define f^2 (expt f 2))
guile> (pe ((D f^2) 't))
(* 2 (f t) ((D f) t))
Add in the little things like being able to have boolean-returning-functions ending with '?', Lisp is very free.
Both lisp(s) and smalltalk took me about 18 months of decently serious use before I had a 'I get it moment'. Stick with it and it will come.
I'm hoping that if I keep at it with Haskell, that eventually I'll have my 'I get it' moment with it as I think I can learn a ton from when I get it, much like I did with Lisp and Smalltalk.
I've learned things from many different languages but the two I've learned the most from where Lisp and Smalltalk.
That said the author missing an obvious thing here. They key with macros is that they allow you to alter syntax (not calculate values as many who try initially misunderstand them), and s-exps are essential to being able to do this (because they are effectively an abstract syntax tree).
I say this is obvious because the example itself demonstrates this. The lisp code in the end looks very much like the ruby. Being able to extend syntax means that if you like ruby you can make your lisp work more like it. Now try to reverse this example, make a ruby library that emulates a lisp style, I think you'd find it much more difficult, and expensive.
The other important thing to not forget is that this syntax transformation happens at compile time. One of the reasons that Ruby has a reputation for being slow is it has to keep track of a lot of metadata and all sorts of look-ups to do a lot of the metaprogramming (which is why people should make better use of it, you've already paid for it). In Common Lisp all this transformation is free during runtime. Think of a common issue with JavaScript: no implicit return. If Lisp did not have implicit return you could define a macro 'defr' which allowed you to define functions like you normally do, but always know they return a value. Instead you need to use CoffeeScript.
Finally people do still write plenty of Common Lisp, they're just a smaller community. Not long ago I wrote myself a very practical tool to process a specific file format, with it's own mini-dsl, an order of magnitude faster than similar libraries (albeit with intentionally less functionality) and all in 200 lines of Common Lisp.