Hacker News new | past | comments | ask | show | jobs | submit login

You're missing the point.

Nothing in your sarcastic "Uh ..." missive makes me or anyone else care about the features you just named. Yes, I know Ruby doesn't have True Lisp Macros. The point is, why should I care? What real-world problem can I not solve elegantly in Ruby because it lacks this language feature?

"It is fast enough" is a mantra you can foist off on people who haven't put up production systems on a Merb stack.

Well, seeing as how I have deployed Merb in production as well, maybe we can discuss the merits without trying to measure egos based on who's deployed what?

Again, my point is that if you can't name a single real world benefit of macros over what's already in Ruby, then why should anyone care how fast they are?




> Nothing in your sarcastic "Uh ..." missive makes me or anyone else care about the features you just named. Yes, I know Ruby doesn't have True Lisp Macros. The point is, why should I care? What real-world problem can I not solve elegantly in Ruby because it lacks this language feature?

It allows for the creation of real Domain Specific Languages and the real extension of lisp for a given problem domain. Do you need constraint propagation on a network of cells? You can make a macro that turns this into an operator in lisp. You can extract nearly any pattern out to the language and begin complex manipulations there.

Since you have a frame of reference I can use, let's talk about rails routes. Imagine if you could specify rails routes in a way at least as naturally as you do in ruby (albeit with more parenthesis, but with fewer line-noise symbols otherwise), but have this become the most efficient implementation of that specific routing table.

You get to have your cake (a syntax that is expressive and immediate) and eat it to (is transformed under the covers into the most optimal code for that task), with frosting (0 runtime penalty for this decision).

> Again, my point is that if you can't name a single real world benefit of macros over what's already in Ruby, then why should anyone care how fast they are?

I say "the language is extensible!" and you say "but what about the real world." Sir, I don't know how to get more real world than this. You use it a billion different ways all the time.

A simple example... I've been working a lot with the JodaTime library in clojure, and I got sick of having to work with the ponderous Java-centric method for building PeriodFormatters (for an example see: http://www.bestinclass.dk/index.php/2010/02/reddit-clone-in-...). So what I've done is write a macro in just a few lines of clojure that lets me say:

    (period-formatter days ("day" "days") " "
                      hours ":" minutes ":" seconds)
If that's not cleaner and more usable, I dunno what is. You only need to write one or two formatters (and typically you need a few) before the macro has "paid itself off" in temrs of line count. And to the underlying code at run time, this code and the code snippet for the formatter from my link are basically indistinguishable. There is 0 runtime cost to this abstraction, but a lot of read-time improvement.

Could you do this particular example in ruby? You could do it to some extent, yes. But not without some significant work. Note, for example, that the argument list to the macro needs to be checked for strings after lists of strings, as this case is not directly supported by the underlying formatter.


> It allows for the creation of real Domain Specific Languages and the real extension of lisp for a given problem domain.

I think the problem was that until now you weren't giving any examples that explained how Common Lisp macros were giving one any greater ability to do this sort of thing than Ruby. One could say "Ruby allows for the creation of real Domain Specific Languages and the real extension of Ruby for a given problem domain," with only a slight alteration in what one considers "real". As such, saying something like "Ruby doesn't give you real foo" doesn't tell anyone anything about what CL gives you that Ruby doesn't.

Also . . . I totally understand the desire to keep (non-earth-shattering) performance differences out of the discussion. After all, one doesn't use Ruby to write realtime systems in the first place. The performance of its implementations is simply not impressive. If I've chosen to use Ruby for something, I've already thought about the performance implications and decided that the performance penalties of Ruby as compared with something like C (or even Perl) are not limiting factors for the particular task I choose to tackle. As such, it makes sense to say "Please tell me about the syntactic and semantic value of Lisp macros, rather than the performance benefits of a Lisp implementation over a Ruby implementation."

You did, however, get into a little more explanation this time, which is good. I just wanted to point out that your disbelief at the notion that someone didn't achieve enlightenment based on your previous comment seems a bit unwarranted.


> Also . . . I totally understand the desire to keep (non-earth-shattering) performance differences out of the discussion. After all, one doesn't use Ruby to write realtime systems in the first place. The performance of its implementations is simply not impressive. If I've chosen to use Ruby for something, I've already thought about the performance implications and decided that the performance penalties of Ruby as compared with something like C (or even Perl) are not limiting factors for the particular task I choose to tackle. As such, it makes sense to say "Please tell me about the syntactic and semantic value of Lisp macros, rather than the performance benefits of a Lisp implementation over a Ruby implementation."

Well also Lisp macros are more comprehensive. Ruby can only make DSLs that look mostly like Ruby. In Lisp, you can literally drop in a new parser if you really want to. In fact, the default PLT Scheme DrScheme distribution has an Algol implementation that is basically a macro set (with some special features).

This allows you to inject whole new programming paradigms into your code. If you need a special kind of OO, you can easily create it. This is actually incredibly-hard-borderline-impossible to do in Ruby. Especially when you get into anaphora injection and complex closure manipualtion.

> You did, however, get into a little more explanation this time, which is good. I just wanted to point out that your disbelief at the notion that someone didn't achieve enlightenment based on your previous comment seems a bit unwarranted.

I had the same reaction this morning when a teenager asked me, "Okay so I get pointers. I get what they are. But they don't see good for anything in the real world." If you find this offensive or dismissive, I apologize. I am simply saying that I think you and I are operating at entirely different levels of abstraction, and bridging that gap is difficult for me.


> Well also Lisp macros are more comprehensive. Ruby can only make DSLs that look mostly like Ruby. In Lisp, you can literally drop in a new parser if you really want to.

Much better.

I haven't worked much (almost at all) with macros. How easy/difficult would it be to create a Ruby-esque DSL in Common Lisp? I'm just curious.

> This allows you to inject whole new programming paradigms into your code. If you need a special kind of OO, you can easily create it. This is actually incredibly-hard-borderline-impossible to do in Ruby.

Really? I dunno, I've seen (for example) some really interesting functional paradigm idioms implemented in Ruby, such as a lazy evaluation module.

> Especially when you get into anaphora injection and complex closure manipualtion.

I admit I haven't done "complex closure manipulation" much anywhere. I do use closures from time to time in my code, in a number of languages -- including Ruby. I'm not entirely sure how "complex closure manipulation" would look, actually, so I have no basis for comparison in that regard. I guess I'll just have to take your word for it.

> I had the same reaction this morning when a teenager asked me, "Okay so I get pointers. I get what they are. But they don't see good for anything in the real world." If you find this offensive or dismissive, I apologize.

I don't find it offensive or dismissive. I understand your perspective. I just don't think it helped anyone understand anything. I'm sure it all looks a lot more natural to someone who has done a lot more CL and Scheme coding, but it really doesn't to someone who has pretty much never touched a CL or Scheme macro in his life (or even for me, who has touched them a little). In fact, what Lisp macro experience I have is mostly limited to UCBLogo plus a light sprinkling of R6RS.

> I am simply saying that I think you and I are operating at entirely different levels of abstraction, and bridging that gap is difficult for me.

That's understandable. To some extent for my benefit, and even more so for the other guy's, I decided to explain some of where the gap lies -- so that you might find it easier to bridge. I hope.


Thanks Dave.

What I'm hearing (and feel free to correct me) is that the gain over Ruby is not as much about additional expressiveness as it is about providing this expressiveness with equivalent performance to that of in-built language operators. That's fair.

I've used Lisp quite a bit (in fact, I did almost all of my first significant programming in Scheme) and even with that background, I've never bought the claim that Lisp gives you some huge practical syntactical/semantic gain over Ruby's already extremely expressive and extensible syntax. I guess I was hoping to be swayed.

N.B. apotheon's comment sums up my perspective perfectly.


> I've used Lisp quite a bit (in fact, I did almost all of my first significant programming in Scheme) and even with that background, I've never bought the claim that Lisp gives you some huge practical syntactical/semantic gain over Ruby's already extremely expressive and extensible syntax. I guess I was hoping to be swayed.

Ruby's syntax is hardly extensible at all. All you're doing is changing the default scope with instance_eval and producing objects with the right intermediate behaviors. You can make some neat little DSLs with this trick, but it's not a real extension to the language.

For example try making the classic anaphoric if in ruby. Can't be done without resulting to cheap excuses like "Well it's a block argument."

It also frustrates me that people have thousands of objections to the pros people put forward for lisp, but no real objections except for an argument about parenthesis that's not even really true anymore. Prefix notion maybe? Oh no your arithmetic is slightly jumbled, everything else is exactly as you use it.


Ruby's syntax is hardly extensible at all. All you're doing is changing the default scope with instance_eval and producing objects with the right intermediate behaviors. You can make some neat little DSLs with this trick, but it's not a real extension to the language.

Whatever. The fact is that in Ruby you can easily write a DSL that looks as if it was custom rolled for the domain and task at hand. In fact, you can do it so transparently that people begin learning the DSL without learning Ruby (cf. Rails). If that doesn't mean Ruby's syntax is extensible, I don't know what does. (And, yes, I get the difference between Ruby's implementation of DSL support and True Lisp Macros; it's just unclear that the difference matters in any significant semantic way.)

I thought we were past trying to praise Lisp's features over Ruby's simply by calling Lisp's "real" (where "real" means exactly the same as Lisp's down to the backquotes and preprocessor). That argument is tautological: no language could ever possibly measure up to Lisp with that kind of criteria.

For example try making the classic anaphoric if in ruby. Can't be done without resulting to cheap excuses like "Well it's a block argument."

Raganwald et al seem to have managed just fine.

http://github.com/raganwald/homoiconic/blob/master/2009-09-2...

And deriding the brackets is just as meaningless as someone deriding the parentheses in Lisp. Speaking of which:

It also frustrates me that people have thousands of objections to the pros people put forward for lisp, but no real objections except for an argument about parenthesis that's not even really true anymore. Prefix notion maybe? Oh no your arithmetic is slightly jumbled, everything else is exactly as you use it.

Not my issue. Heck, I like Lisp! That said, I think Lisp evangelists are failing to make a case for it over, say, Ruby for precisely the reasons discussed ad nauseam in this thread.


> Whatever. The fact is that in Ruby you can easily write a DSL that looks as if it was custom rolled for the domain and task at hand. In fact, you can do it so transparently that people begin learning the DSL without learning Ruby (cf. Rails). If that doesn't mean Ruby's syntax is extensible, I don't know what does. (And, yes, I get the difference between Ruby's implementation of DSL support and True Lisp Macros; it's just unclear that the difference matters in any significant semantic way.)

If by "custom rolled" you mean "laden with :symbols, forced into ruby's function invocation structure."

> I thought we were past trying to praise Lisp's features over Ruby's simply by calling Lisp's "real" (where "real" means exactly the same as Lisp's down to the backquotes and preprocessor). That argument is tautological: no language could ever possibly measure up to Lisp with that kind of criteria.

Except that I don't make that claim. Dylan did it just fine. I'm asking for real modification of the syntax tree. I'm asking for a real extension of the parser. It's not tautological and there are examples in the wild of people actually succeeding here without the classic sexpr syntax.

> Raganwald et al seem to have managed just fine...

Dozens of lines to mimic at runtime what compiler extension just allows it, in a far more natural and understandable way. I didn't say it was impossible, I said it was awkward.

> And deriding the brackets is just as meaningless as someone deriding the parentheses in Lisp.

I didn't deride brackets. I said that these complex runtime proxy solutions are hacks. It's like C++ people arguing they have anonymous functions because they can write Functor classes. It's a non-argument, because it's almost certain that you _can_ accomplish it. The question is, "How much extra complexity do I have to introduce in order to make this desirable way of programming possible."




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

Search: