Hacker News new | comments | show | ask | jobs | submit login
What Pythonistas Think of Ruby (peepcode.com)
188 points by sant0sk1 2847 days ago | hide | past | web | 235 comments | favorite



As someone who did nothing but Rails since 06 (two Rails-powered startups, plus some Rails contracting), allow me to explain why I dumped Ruby/Rails and switched to Python/Pylons.

Batteries. Ruby is great, but outside of Rails you are on your own. Even basic things like geometry needs to be coded by hand. Python (and almost anything else) simply destroys Ruby when it comes to generic non-web centric libraries. And the situation isn't changing: most new Ruby "libraries" are just add-ons to Rails, seriously, how many Rails unit testing frameworks, paginators and file upload handlers do we need?

People. Python hackers are much, much nicer folks to hang around with. I don't like to start a war here so I'll refrain from going further with this point. Besides, I feel like Zed Shaw said it all.


Do you really have to switch from one to another? I learned both languages, love them both, and use them both. There's too much hate in the world of programming languages.


The fights are so vicious because the stakes are so small. (Originally said about academics, but works for programmers, too.)


Sayer's Law: "In any dispute the intensity of feeling is inversely proportional to the value of the stakes at issue." http://en.wikipedia.org/wiki/Sayre%27s_Law

Special case in programming -- "colour of the bikeshed" http://en.wikipedia.org/wiki/Parkinson%27s_Law_of_Triviality


Offtopic question: where can I get a hierarchical category/index/guideline to many of these * laws ?

I'd like to quotes these cool stuff as well, just need a way to look it up :)


This is pretty close to what you're looking for, I think: http://en.wikipedia.org/wiki/Category:Adages


that's exactly what I am looking for. Thanks


I don't think the fights should be vicious, but I think the stakes are fairly high, and even though Ruby and Python are close cousins in the grand scheme of things, they really do represent profoundly different philosophies when you look more closely at the languages. It would be nice if these differences could always be discussed with civility, of course.

I use both Ruby and Python enough to appreciate that both languages generally make important tradeoffs with good intentions, but I don't always agree with the results (in either language). I also find Javascript often has an interesting relationship to both languages.


That's just another reason for vicious fights besides small stakes, small differences.

Just ask the protestants and the catholics.


It is true that small differences can mean large conflicts, but I think Catholicism and Eastern Orthodoxy is a better illustration of this. The only doctrine that the two denominations disagreed on was the exact way in which the Pope is higher-ranked than the other metropolitan bishops; this plus language barriers and differences in cultural atmosphere produced something like 1500 years of mutual hostility which were only ended by John Paul II.

However, we can sometimes mistake _subtle_ differences for _small_ ones; but just as there's a substantial difference between the Mac OS and Windows, there's a substantial difference between Catholicism and Calvinism (which was the most successful form of Protestantism) -- the difference between God seeing that you went to Hell, and God sending you there. I could go into much greater detail (I count nine paragraphs in how I'd previously structured this comment), but that's the nutshell of the nutshell.


When looking at this from an atheists perspective it looks like very minor differences to me.

There's a joke about that, I looked it up:

I was walking across a bridge one day, and I saw a man standing on the edge, about to jump off. So I ran over and said “Stop! don’t do it!” “Why shouldn’t I?” he said. I said, “Well, there’s so much to live for!” He said, “Like what?”

I said, “Well, are you religious or atheist?” He said, “Religious.”

I said, “Me too! …Are you Christian or Buddhist?” He said, “Christian.”

I said, “Me too! …Are you Catholic or Protestant?” He said, “Protestant.”

I said, “Me too! …Are you Episcopalian or Baptist?” He said, “Baptist!”

I said, “Wow! Me too!…Are you Baptist church of God or Baptist church of the Lord?” He said, “Baptist church of God!”

I said, “Me too! Are you original Baptist church of God, or are you reformed Baptist church of God?” He said, “Reformed Baptist church of God!”

I said, “Me too! Are you reformed Baptist church of God, reformation of 1879, or reformed Baptist church of God, reformation of 1915?”

He said, “Reformed Baptist church of God, reformation of 1915!”

I said, “Die, heretic scum” and pushed him off.. — Emo Phillips


@jacquesm: At least from my perspective, "God wants everyone to go to Heaven" and "God wants some people to go to Hell" are further apart than "God wants everyone to go to Heaven" and "there is no God, and the universe developed through chance and emergent patterns."

Calvinism had _huge_ practical consequences -- in social policy, it's the difference between ensuring that the poor are fed and sheltered, and kicking them into the street; and you can only imagine what it meant for the laws of war...

Edit: And the joke you mention is only too recognizable, but it's more like the Catholicism-and-Orthodoxy situation, where it's a matter of tribal loyalties more than views of the world...


I thought that was originally said about college student government/politics...

Then again, programming language is a very personal choice for many, so if you insult a language, you insult the person. There aren't many polyglot programmers that are detached from their preferred language.

For me, I prefer Python, but I'm not going to blindly defend it.


I have the definitive impression that the Pythonistas are more interested in this fighting than most other language cultures.

I might be wrong, but I really can't mention any other group of people trolling Perl discussions. It is the same for Ruby?

It really seems strange for a language which got the name from Monthy Python. (-: Is it some inferiority feelings to environments which are fun? :-)


I might be wrong, but I really can't mention any other group of people trolling Perl discussions.

Everyone is out trolling the Perl discussions. PHP developers hate us, Java developers hate us, Ruby developers hate us, and Python developers hate us. I think this is funny, because we generally don't hate the other languages, we just embrace and extend their good ideas for Perl. (The Perl community has come up with a few good ideas on their own, but the best ideas have been borrowed from other languages. Moose is from Smalltalk and CL; PSGI is from Python; Plack is from Ruby; Catalyst is from Java; etc. I think, in general, the stolen ideas have been improved upon in Perl; I like using Moose a lot more than I like using CLOS -- and I like using CLOS a lot.)

The only place outside of the Perl community where I can admit to liking Perl (and not be flamed) is #haskell. But everyone is nice there.

(I've even been trolled in real life over my like of Perl. I was going after some girl, who apparently had a friend that was a Java developer. Perl came up, I came up, and it was resolved "he must not be very good at programming if he prefers Perl over Java". Guess who got the girl? Not the Perl programmer.)


> PHP developers hate us, Java developers hate us, Ruby developers hate us, and Python developers hate us.

Wait. Ruby? What? Did you have a bad experience with some Rails people and decide that Ruby developers hate Perl?

As someone who loves both Perl and Ruby, I haven't seen any Perl hate from Ruby developers in general. I can't vouch for Rails people, though. There are some serious social dysfunctions in that community.

> The only place outside of the Perl community where I can admit to liking Perl (and not be flamed) is #haskell.

I haven't gotten into Haskell (yet) -- but I've never gotten any shit on the ruby-talk list for "admitting" that I like Perl.

> (I've even been trolled in real life over my like of Perl. I was going after some girl, who apparently had a friend that was a Java developer. Perl came up, I came up, and it was resolved "he must not be very good at programming if he prefers Perl over Java". Guess who got the girl? Not the Perl programmer.)

Wow. WTF?

I have gotten shit from Pythonistas in person a couple of times for liking Perl, but nothing nearly that bad -- just as I have for preferring FreeBSD over "Linux".

In general, the hackers I know dislike Java, so I haven't really had the opportunity to get treated that badly by a Java developer. Maybe I'm just lucky.


> Moose is from Smalltalk and CL...

... and Perl 6.


Yes, you're right. Adding state to traits is definitely a Perl 6 innovation.


I've found quite the opposite; my experience with Python users has been consistently personable. If anything, the party line seems to be "this is the way we do things, if you like what you see, come on in, if not, no worries". I mean, this whole article is really just a troll post on Python by a Rube (that's what they're called, right?)


" ... just a troll post on Python by a Rube (that's what they're called, right?)"

Speaking of which ...


It was just a joke, no offense intended. Apologies to any Rubyist who was offended.


I love Ruby. I don't really like Python as much (Python and I have irreconcilable philosophical and code-formatting differences). I was not offended.

I was, however, saddened by the fact that almost every single time I've seen a Pythonista talk about how nice Pythonistas are, the comment has included a dig at people who use other languages like that. The probability seems to run in the 90%+ range.


I don't think anyone was offended, but it's exactly the sort of thing some people like to jump on and say, "See? See? That's what I'm talking about!"


    the party line seems to be "this is the way we do
    things, if you like what you see, come on in, if not, 
    no worries"
That is absolutely not the case; Python is the anti-TMTOWTDI. The Python community is very vocal and explicit about the conventions developers are expected to follow, more so than any other language I'm aware of: PEP 8, Zen of Python, non-stop critiques about whether some code is "pythonic" enough.


The Python community is very vocal and explicit about the conventions developers are expected to follow, more so than any other language I'm aware of: PEP 8, Zen of Python, non-stop critiques about whether some code is "pythonic" enough.

Yeah, that's the "this is the way we do things" part, but that's a different issue. Things like PEP-8 and a measure of how "Pythonic" something is helps make one of Python's biggest strengths, the "batteries included" easier to accomplish and easier to understand, because there is a consistent standard. Of course, not all code, even in the stdlib, is up to that standard, but it's more consistent than a lot of libraries you'll find.

The point I was making, and the difference from a lot of language communities I've seen is that there is little of this hyperbolic "That's not even possible in [insert-language-here]" nonsense. The Python programmers I tend to interact with don't really mind if you don't use Python, because at the end of the day, almost every language has the necessary features to Get Stuff Done.


There's a difference between "why aren't you using Python?" and "why aren't you following standard Python coding conventions?".


Ah, I see. So what you are tying to say is that the non-stop bashing of Perl, PHP and Ruby from Python developers should be interpreted as just a friendly "if [you don't like python], no worries."

After all, one would have to be a "Rube (that's what [Ruby developers are] called, right?)" to think that Python developers aren't friendly to people who don't worship Python.


I just browsed over this entire thread, and you're by far the flamiest person here.

There are always bashers. Their existence proves nothing. The question is whether they represent the bulk of the community. It's hard to speak for an entire community, but it is certainly true that the Python community leaders are not into bashing other languages routinely.


    you're by far the flamiest person here.
Flamier than the person who called Ruby developers "Rubes" after claiming Python is friendly to other developers? Interesting.

    Python community leaders are not into bashing other languages routinely
Indeed, this is true. It's unfortunate that so many python developers don't follow suit.


The "Rube" comment was a joke, not a serious insult. If it genuinely offended you, I apologize.

On the other hand, if you're looking to be offended to prove a point about who is "flamier", you've succeeded.


Does 'Rube' have a negative connotation attached to it? I mean we're calling Python devs 'Pythonistas,' which I also don't necessarily associate with negative connotations. Maybe I just haven't participated in enough Python-Ruby flamewars to know all of the 'secret' lingo that's only offensive to you if you are already part of that flamewar culture?

> Indeed, this is true. It's unfortunate that so many python developers don't follow suit.

Do you have any numbers to back any of this up? Is it possible that Python just happens to have a small number of really vocal hyper-proponents that feel the need to bash everything else? Could it just be that you aren't a Python programmer so you take more offense to your language being bashed and therefore notice if more often than others?


> Does 'Rube' have a negative connotation attached to it?

Yes, it does. Rubyists are typically called Rubyists or Ruby hackers if one does not wish to insult them. Calling a Rubyist ia "Rube" would be like calling a Pythonista a "Pyker" (reference to [piker](http://education.yahoo.com/reference/dictionary/entry/piker), definition 2).

> Maybe I just haven't participated in enough Python-Ruby flamewars to know all of the 'secret' lingo that's only offensive to you if you are already part of that flamewar culture?

There's nothing "secret" about the insulting character of the term "rube".


    Does 'Rube' have a negative connotation attached to it?
Yes, and it's been a common insult for at least a century: http://www.google.com/dictionary?aq=f&langpair=en|en&...

    Do you have any numbers to back any of this up?
We don't need to look any further than this thread: 30 points on the initial Ruby/Rails-bashing rant that also insults Ruby developers, 6 points on tghw's comment that insults Ruby developers with outright name-calling. Par for the course.

    Could it just be that you aren't a Python programmer
No, considering I've been using python on and off for almost a decade now.

    your language
Or it could be that there is no "[my] language" and I'm just willing to call out rampant hypocrisy and language-bashing when I see it.

Honestly, I find it interesting that people assume someone doesn't use Python just because they call out Team Python on their non-stop trolling and language-bashing. "Either you're with us or against us," apparently. Big surprise.


> the non-stop bashing of [...] PHP [...] from Python developers

You lost me here. PHP is the favorite flogging-boy language of a lot of developers from a lot of different environments. Trying to peg this solely on Python developers/flamers is disingenuous. You might as well try to claim that Python developers are responsible for all of the Microsoft (and/or .Net/ASP/C#) bashing that goes on around the web.


I thought including PHP in that litany of crimes was a little weird, too. I mean . . . PHP actually deserves it.


Nah. Anecdotes are anecdotes.


Python is a dogmatic language. For the language, this is a good thing, helping it stay clean, simple and yet still powerful. But for the community, it breeds rabid fanboys, just like everything else that's dogmatic.


I don't know. Haskell is quite dogmatic in some ways. The people on the Haskell cafe mailing list don't strike me as rabid fanboys.


You must be joking. People like Dons run or use a blog spidering program for anything that mentions Haskell.

In less than 10 minutes after posting anything remotely negative about Haskell, I have a horde of angry fanboys telling me how I am an idiot.


Really, now? I can't say I've ever seen dons be anything other than polite and helpful. Not to mention that he's one of the most knowledgeable Haskell programmers out there, especially on the "practical real world use" front.


You may be right. That's why I only talked about the stuff I have some experience with, and that's the civilized Haskell cafe mailing list.

I guess that may (or may not) show that a single language can be part of different cultures.


I've seen one Pythonista troll the ruby-talk mailing list. I have no idea whether any Rubyists troll Python's main community venue -- but if there are any, I'm pretty sure they're probably Rails people, which really have their own, separate community.


Switching between languages based on context is good; you might have a favorite pet language for desktop work, embedded work, iPhone work, and web work. But splitting your brain cells between languages for the same sort of task, in the case web development, isn't very efficient.

I have to do it, for different platforms, but that means I'm constantly switching between design techniques and I can't reuse one body of common code.

It just makes sense to put all your eggs in one basket and make the switch. However, it's important to have a healthy respect for other languages and their pros and cons compared to your own choice.


I reuse code a lot. If I write code in Ruby, I can't reuse it in a Python project. Since Python and Ruby occupy the same niche, I will often want to reuse code.

(This is less of an issue if I want to use Python and C++. I'll rarely want to reuse linear programming code or a PDE solver in Python, and if I did, I would just wrap the C++. Similarly, I never want to use code I've written for the web in C++.)


And if you did, it isn't really that hideous to embed the python interpreter in your C++ app...


Using a dynamic loadable C library from Ruby is neat and easy.


You don't have to choose a single option, even for a particular project. I've worked on websites/apps that have integrated 2 or 3 different server-side languages and frameworks. If you have a programmer that says "eww I'm not touching the WordPress part because it's in PHP" they just aren't the kind of programmer I want working on the project. Also, if you have a programmer that goes out an freaking re-implements WordPress in Ruby on Rails simply to avoid using a second tool, they probably aren't commercially viable and I don't want them either.


There is a drawback to this, obviously. If your codebase is some scattered mish mash of Python, PHP, Actionscript, Javascript, Java, etc, your ability to reuse code diminishes at the language boundaries. You end up having to write very similar code to deal with the same objects on the client side and the server side in multiple languages, producing more code to maintain overall.

Unfortunately because of the nature of the web I haven't seen any real good solution to this yet. At minimum, you're usually dealing with some combination of Python/Ruby/PHP backend and some amount of Javascript/Actionscript on the frontend.


True, though I don't want to leave you with the impression that it's a mish mash implementation. It's more of a silo'd approach. One section of the website might be a wiki, so we use a particular tool there. It's a self-contained unit but perhaps pulling in some common stylesheets to retain a consistent look and feel. Another section might be a blog part of the site. Again, it might pull in some common assets for the consistent look and feel.

Instead of thinking of code re-use, we're left with a UNIX style resource re-use. Every component can stand alone, but they all work in conjunction with each other and can be re-arranged to work in different ways.


If I start every conversation with Python developers with a rant about how their language/frameworks suck I'm sure they wouldn't be very friendly with me.


What if you start a conversation without any mention of Python at all?


> People. Python hackers are much, much nicer folks to hang around with. I don't like to start a war here so I'll refrain from going further with this point. Besides, I feel like Zed Shaw said it all.

I don't buy this point. I think you're confusing what Zed said about the Rails community with the reality of the Ruby community. Frankly, from what I've seen, the Rails community is a bit of a ghetto within the larger Ruby community.

I've also seen a lot of what amounts to acrimony and vitriol from Pythonistas when discussing other languages, where Rubyists (not Rails developers, specifically, but people in the broader Ruby community) have tended to be much more appreciative of what developers in other language communities, and other languages, bring to the party.

What's the difference between a Rubyist response to a Python way of doing things and a Pythonista response to a Ruby way of doing things? In my experience, the Rubyist says "Hey, that's kinda neat -- but it's not for me," but the Pythonista says "You're doing it wrong."


I never choose python like my script language because I don't like the arrogance of pythonist, more now when everybody knows google use python for everything, in python all is perfect and the other languages are crap, I always read articles like this o like python paradox or any other superficial article where the author try feign know others languages for criticize it with "solid arguments" ruby is a infant and don't try compare his libraries w any other language because It's very unfair, but really my questions is WHY PYTHONIST CONCERNED SO MUCH THE OTHERS LANGUAGES?, why they need type all days a new article explain the good language is python or the bad are all others (like java, c#, ruby, perl) I don't kwnow, please explain me it...and don't say the python hacker are much nicer because they are nicer only inside conversations with others pythonist......


> Ruby takes full advantage of the Lisp chainsaw.

I always get a little sad and slightly irritated when I hear people say things like this. This is a statement born from ignorance and misunderstanding.

What ruby does to present micro-DSLs are what any language that lets the programmer influence the scope of single dispatch and has a lightweight syntax for function calls can do. They are not what Lisp macros do, and do not even approach all the common "easy" uses cases for macros. Further, they also incur a much larger runtime performance penalty, whereas macros incur none.

Ruby has so many merits on its own. There is no need to drum up nonsense about how it's a "lisp without the parenthesis".


You might be taking the statement out of context, and you are certainly quoting it out of context (although brevity is appreciated.)

The statement in the talk was made to illustrate the differences between Ruby and Python, and it was not made to suggest that Ruby was replicating all the benefits of Lisp.


I understand the intent, but I do not feel that it loses its incorrectness by taking it out of context.

That people even feel this comparison is appropriate is what has me depressed. It represents a fairly fundamental set of misunderstandings.


> That people even feel this comparison is appropriate is what has me depressed.

I agree; you can replace the term "DSL" with "API" in almost every case without losing any essential meaning. (You have to give the hipper-than-thou language pseudo-advocacy, but that's no loss.)


I think in those contexts, DSL is more a description of how an API feels to use, than a precise technical categorisation.`

Ergonomic distinctions are useful though, as is the distinction between declarative-style APIs and more imperative ones, which 'DSL' is often used to make.


I have yet to see a Ruby "DSL" that didn't feel like Ruby. That is,

  unless you.talk :like => "this"


Those are just the "english-y" DSLs. Not all are attempting to read like english. And even for those that are, the point isn't to be writing in english, the point is to be at least halfway readable to a non-programmer reading over your shoulder.


Okay, but it's not really all that clear that "sum.should == 3" is actually any more readable than "assert(sum == 3)". (Do you really have non-programmers reading code over your shoulder? I can't think of any case in a 10+ year career where that's happened.)


I don't personally use the stuff. :) But I have seen environments where that does happen, and it works pretty well for them.

If you're not doing that, I think they're kind of silly.


> ... the point is to be at least halfway readable to a non-programmer reading over your shoulder.

That's the same argument for filing the serial number off of TDD and calling it BDD: sometime, somewhere, somehow eventually some non-programmer is going to have to maintain source code without a trained professional programmer around to help.

I don't get it; FIT's been around much, much longer. What kind of non-developer business rule expert can read the punctuation-sprinkled pseudo-English pidgin Ruby spreads around but doesn't know how to manipulate tabular data in a spreadsheet?


The BDD reference is not just an analogy, it's what these are for. And it's not about non-programmers maintaining the code. Not at all. It's about a business owner and a programmer sitting together and making executable specs together.

I don't really get it, but I'm curious. People I respect swear by it.


I have yet to see a Ruby "DSL" that didn't feel like Ruby

There are some out there though, for eg. FancyRoutes: http://www.railsinside.com/plugins/252-fancyroutes-a-nicer-d...


Really? That's the example you want to use. First thing I see on that page:

  get / 'orders' >> :orders > :index

  with route / :slug / 'order' >> :orders do
    get > :show
    put > :update
  end

  get {'item_images' => :controller} / :image > :show
That looks like Ruby all over the place. Yeah, it overloads operator methods more than most Ruby code, but it's very clear that it's Ruby.


I and i think most people would disagree with you because above does not "feel like" Ruby.


haml, sass, cucumber...


They are not what Lisp macros do.

True.

What ruby does to present micro-DSLs are what any language that lets the programmer influence the scope of single dispatch and has a lightweight syntax for function calls can do.

They are not what Lisp macros do, and do not even approach all the common "easy" uses cases for macros. Further, they also incur a much larger runtime performance penalty, whereas macros incur none.

I think that part of the problem is that no one (whom I've seen, at least) has explained in a brief, easy to follow manner just what the Lisp macros get you beyond all of the parse tree manipulation, code generation, and "metaprogramming" you can already do with Ruby. If you could explain the extra benefit succinctly, I'd love to hear it. In other words, I'd love to see an essay or blog post that makes me wish Ruby had true, Lisp-style macros.

Performance, by the way, won't be enough: language implementations are always getting better.


> I think that part of the problem is that no one (whom I've seen, at least) has explained in a brief, easy to follow manner just what the Lisp macros get you beyond all of the parse tree manipulation, code generation, and "metaprogramming" you can already do with Ruby.

Uh, the stuff you can do with ruby (short of the Ruby2Ruby parse tree generation) is incredibly limited compared to the arbitrary transforms that macros, especially tools like macrolet (lexically scoped macros) and symbol-macrolet (lexically scoped symbol expansion) allow you to do.

Ruby2Ruby lets you do almost arbitrary parse tree transforms, but again it does this at runtime. Unless you specifically architect your program in a somewhat non-rubyish fashion to have a sort of "compile" phase where your transforms are completed.

> Performance, by the way, won't be enough: language implementations are always getting better.

... I say this as a fan of ruby who's made a career out of it for years. Ruby's performance improvements move at a snail's pace. If someone said, "Hey, you can do everything Ruby2Ruby can do, but with 0 performance penalty" then that'd be a huge value add. If you say it isn't, you're being unreasonable. "It is fast enough" is a mantra you can foist off on people who haven't put up production systems on a Merb stack.


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."


I am one of those people who accepted the lisp religion of "syntax is evil". I have a descent knowledge of python, and I've read a few ruby tutorials.

Neither python nor ruby are lisp. Python is not cool because of generators, list comprehensions, decorators or any other feature. Ruby is not cool because of blocks or monkey patching(im suspicions of anything called MONKEY patching). Ruby and python are cool because of really cool libraries and the way people use these languages, not because they have especially well designed syntax.

Instead of arguing about how cool your crappy syntax is, argue about which has the better libraries, which implementation is better, which is used for cooler projects. Non of these languages can top lisp when it comes to expressiveness and flexibility.


Syntax is human. Syntax is ergonomics. A programming language is the bridge between man and machine. Lisp, I would argue, is far more about the machine than the man and that is the simple reason why it's not more popular.

Python was cool before the libraries; that's why those libraries got written in the first place. Lisp has been around forever and is still lacking in libraries and other support.


I'm sorry having dabbled in Ruby and having actively coded in Python and Lisp (Scheme, Clojure) you and the OP are laying the FUD on thick. I would argue Lisp has been able to stay relevant for so long because it's syntax assumes nothing about what domain you might be modeling. On the other hand, so little syntax means less "landmarks" and lot of programmers are put off by that.

Syntax is human and syntax is ergonomics. That's why languages with good syntax are so popular and deservedly so.

At the same time I think the number one reason languages eventually die off is because of syntax. A particular syntax was designed for solving specific kinds of problems. Then people realize there are deeper or different problems that the syntax cannot adequately address. Since the language is not a Lisp it cannot be repaired.

I think Python and Ruby are cool and useful tools, but I don't think their design will last another 50 years as Lisp probably will.


"Lisp, I would argue, is far more about the machine than the man and that is the simple reason why it's not more popular."

Pleas do, i would love to hear your argument. I fail to see how lisp is less humane than python, when i find it to be exactly the opposite.

Edit: what i meant was that lisp is more about the human, not that python is more about the machine, i hope i don't get misunderstood.


As a non lisp programmer, it is hard for me to automatically see what is going on in a lisp program because of mismatched " ' " and a lot of parenthesis. I believe this is one of his points. When I was learning python, or ruby, for that matter ( I use both! ) I never felt like I had no idea what was going on in the code even before I learned the languages.


Should this really be so surprising, though? Lisp is based on a different model of computation than Python and Ruby. You can't follow non-trivial C code without understanding pointers, or Prolog without understanding unification.

Syntax aside, the semantics of Python are intended to be unsurprising to people with a conventional programming background. I don't have any practical experience with Ruby, but it looks like a mishmash of Smalltalk and Perl to me, and I can usually get the gist of code snippets. Likewise, I can kinda-sorta follow written Dutch (since I've studied German and speak English fluently), but I wouldn't expect to be able to just read Thai.


> I don't have any practical experience with Ruby, but it looks like a mishmash of Smalltalk and Perl to me

Those are, I think, probably the two most influential sources of inspiration for how the language is put together, in terms of the actual end result.


Oh, Lisp isn't so difficult once you get used to.

Interestingly I find myself equally baffled when I have to read code with side-effects. There's just so much implicit state (and state changes going on in the background), you have to keep in your head. Pure languages are so much easier to understand.


I should probably try to learn lisp. I primarily use emacs, so it would make a lot of sense. Some of the ruby/rails stuff out there for emacs really isn't very good.


Emacs lisp is handy for toying around with the editor, but it's a horrible Lisp. It does not even have lexical scoping. You are much better off in terms of entertainment (through learning interesting stuff) with e.g. PLT Scheme or perhaps Arc.

(My comment about pure languages above was meant to highlight the joys of Clean and Haskell. Curry may also be worth a look. And Prolog, if you dare.)


I'd say that learning Scheme is more likely to convey what's interesting about Lisp, and there is quite a bit of great programming literature associated with Scheme. I'm not sure if it's easier to learn CL after Scheme or vice versa, though.

I still haven't done anything with Prolog past using it for prototyping, but it has some really cool ideas, and I hope to have a good excuse to play with it more soon. (And it, too, has some great books.)


> You are much better off in terms of entertainment (through learning interesting stuff) with e.g. PLT Scheme or perhaps Arc.

. . . but if you want to actually use a LISP for practical programming, and you start out with any Scheme, you're going to have to follow that up by learning another (non-Scheme) LISP. You might as well just start out with Common Lisp and be done with it.

Judging by my experience, Scheme is not a language one should set out to learn so much as a language one should learn as a side-effect of going through a book like SICP or The Little Schemer. Trying to do anything "real" with Scheme is an exercise in frustration, especially if you want it to be portable across Scheme versions, since the biggest names in Scheme implementations appear to be entirely uninterested in library portability except where "portable" means "Well, we can use it, and don't care whether you can."

Scheme itself is an excellent language, though. Too bad that, alone, is not enough.


What happened to the library situation in Common Lisp? Your comment looks like it improved since the last time I checked. That would be nice. (Though I fear Common Lisp is still too ugly for me to enjoy it. Perhaps some reader macro magic could rectify the situation. ;o)


I don't know if the library situation is good in Common Lisp. It's just enough worse in Scheme that it's kind of ridiculous to consider actually using it for other than academic purposes.


I tend to prefer languages which are expressive.

"Brevity is the soul of wit."

Therefore I like Python for imperative programming and its extensive libraries and far prefer Haskell to any LISP dialect for functional programming. Haskell is elegant in a way LISP wishes it could be.


I wholeheartedly agree that all languages should be judged on the quality of their libraries and implementation, as well as the success of the projects implemented on top of them. Ruby and Python have a pretty good track record there.

One of the themes of Gary's talk was that Ruby is more expressive/flexible than Python, and lisp was thrown into the discussion as sort of a "gold standard" of expressiveness/flexibility, without necessarily passing any judgment on overall merits of the three languages.

To the extent that Ruby strives for more flexibility, it is probably way more influenced by Perl than lisp.

As somebody who has used both Ruby and Python fairly extensively, I think Ruby is undeniably more expressive than Python at times, but also more arcane at others. Some of the differences probably come from irreconcilable tradeoffs, where you cannot have your cake and eat it too, but other tradeoffs are probably less necessary, which is why people continue to discuss it. In the case of Ruby, it's a pretty young language, so there are probably opportunities to make it more appealing to a Python mindset without losing its great flexibility, although I do not have specific proposals.

The conference Gary spoke at was a Python conference, so most people were more interested in ways that Python could learn from Ruby, without sacrificing Pythonicness. Gary seemed to reach the conclusion that the number one feature he envied in Ruby was blocks. Speaking for myself, I wish Python just had some kind of anonymous function syntax that was more rich than lambdas, even if it were not exactly semantically similar to Ruby blocks.


> I wish Python just had some kind of anonymous function syntax that was more rich than lambdas

A lot of people keep saying this, including the article author, and I'm having trouble understanding why. Lambdas are for "one-liners", functions are for more-liners.

Any time you want to write multiple lines in a lambda it's trivial to make it a named function.

    def listSomeTable(name):
        print name.center(40, "=")
        def getWeirdNumberPair(cap):
            while True:
                a = random.randint(1, cap)
                b = random.randint(1, cap)
                if (a==1) and (b==1):
                    continue
                return (a, b)
        for i in xrange(20):
            print getWeirdNumberPair(i)
        print "="*40
What do you want to use multiline-lambdas for that you can't do (equally simply and elegantly) with named functions?


First of all, your objection to anonymous functions with an example that names the function in two different places kind of takes us off topic from the discussion of "anonymous" functions, but I will still respond.

Second of all, multiline-lambdas are already possible in Python, but they are not anonymous functions.

Anonymous functions, as I said, allow for rich syntax; they do not affect the Turing completeness of the language. The context I am speaking of is "expressibility" in the sense of natural language, not whether or not something is expressible at all.

Ruby allows you to do stuff like this fairly naturally:

def process_event_until_timer_expires # check time, then call block only if # timer not expired end

process_events_until_timer_expires { |t, event| puts t fire_event_downstream(event) }

Having an anonymous function here allows you to read from outside in, which is more natural. From the outside, you know you are in some event loop, then you can look inside the block to see the details of how the event are handled. It's really that simple. Not earth-shattering different than Python, just subtly different and more expressive.

I've been using Python for a decade, and Ruby's still overly exotic to me, so I am sympathetic to people that defend the more Pythonic approach. But Ruby does allow for a different kind of expressiveness here.

Javascript also makes heavy use of anonymous functions, and if you use anonymous functions in other languages, you realize that they have value, even if they are occasionally abused and technically unnecessary.


The real problem with lambdas in Python isn't that they're restricted to one expression, but that Python's implementation of closures is clumsy (due to a scoping ambiguity). The argument about whether lambdas should be named or not is a canard. In languages that make heavy use of lexically scoped functions defined on the fly (Scheme, ML, etc.), they're often given local names. The problem is that Python's locally defined functions are less expressive. Apparently making heavy use of closures is not "pythonic".


You are correct. There is no reason not to just use an inline function that happens to have a name. I think the "lambdas can only be one line" is a newbie python mistake.


Personally, I dislike naming things that I won't use again. It feels like a waste. And then, since I have to name things, I have to come up with a _good_ name.

Just a matter of taste, mind you, but it's my reasoning for preferring anonymous functions.


They do make code more readable sometimes... but I think they are often used in Ruby as an alternative to @obj.method(:foo) -- in other words the Rubyist would use lambda{@obj.foo} and the pythonista would use obj.foo


> Lambdas are for "one-liners", functions are for more-liners.

The problem, though, is that this is entirely a Python conceit. It is in no way, shape, or form any kind of programming truism. In fact, taking a more principles-oriented approach, a named function is really just a special case of a lambda. I think this may be one of those things that using a LISP (such as Scheme or Common Lisp) helps people realize.

This:

    (define (foo n)
      ( . . . ))
. . . is just syntax sugar for this:

    (define foo
      (lambda (n)
        ( . . . )))
The fact that the syntax sugar is all many languages expose to the programmer doesn't change that fact, and the one-line restriction on "lambdas" in Python seems quite arbitrary.


Giving people concise syntax for passing anonymous functions allows one to implement a lot of control-flow operations, and combinators from functional programming, as libraries, rather than language constructs.

In python, although they could technically be done as libraries, from a syntactic point of view, having to declare named functions and pass them explicitly as arguments rather defeats the elegance of the approach.

So instead we have special features and syntax added to the language, like with statements and list comprehensions, which are limited special cases of what can be expressed more generally with a nice syntax for passing closures as arguments.

Not that it necessarily matters, there's always a pythonic way to do the equivalent thing. Although a lot of the time it's more imperative, and my taste is for functional programming idioms where possible.


Yes, Python's functions are meant to be named.


Python generators (the ones you can get with "yield") are not just syntax. They can be viewed as a distant relative of continuations or lazy evaluation.

Lisp (or lets say Scheme, because Common Lisp is ugly and imperative) does have some nice points. I rather like the syntax. But e.g. strict evaluation by default and lots of side-effects hamper the expressiveness and flexibility of the language.


You do Haskell don't you? :-)


Yes, and Clean.

I just like to counter those smug Lispians. Lisp has nice syntax, but the underlying semantics is nothing to write home about any longer. Add tail call optimization to Python (and perhaps continuations) and you have something similar to Scheme modulo syntax.


How a python vs ruby thread turned in to Haskell vs Lisp argument i will never know. The essence of Haskell is that its a lazy statically typed functional language, the essence of lisp is that it treats code as data. There is NOTHING stopping someone from making a Haskell with lisp syntax, and calling that lisp, in fact i think there is such a thing. Code as data is such a powerful idea, it is independent of the underlying paradigm of the language, you can have an algol with lisp syntax and it would be lisp, you can have smalltalk with lisp syntax and it would be lisp. Code is data is the only lisp feature you can't take away from lisp, because if you add it to your language, you don't have a new language, you have a new lisp.

Thats why lispers are smug sometimes, they know that their language will change dramatically in the future to adapt to the new environment, its the source of lisps immortality, it is destined to be reinvented.


Oh, I did not want to create a `versus' argument. Please pardon me, if I did.


>Neither python nor ruby are lisp.

You may or may not agree, but you'll probably be interested in Why Ruby is an acceptable Lisp: http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-a...

Covered on HN previously here:

http://news.ycombinator.com/item?id=416589


Yes, i have read that article. Here is my humble opinion: Having 80% of the expressibility, even if you don't need the other 20% that often, does not make you lisp. Which is why the title is not "Why ruby is lisp", but uses the word "acceptable". Its just semantics, and i don't want to argue about what makes something lisp, it wasn't even my main point.


I think "Why Ruby is Good Enough" makes for a better title, I'd agree. I don't think Ruby is Lisp either, I just felt that it went along with your point, that's all.


Does this boil down to a case of Worse is Better?


That is a good question, and worthy of an upvote. My first inclination is to say it is not, because if Ruby really were the "worse" to Lisp's "better" in some measurable, objective sense, then presumably Matz would have created something like Clojure rather than Ruby.


And not being Lisp is one of the big reasons for the success of both Python and Ruby. :-)

FLAMEBAIT -> FLAMEBAIT


I fail to see how that is flame bait. It's actually a quite insightful statement that is worth repeating: Python, Ruby and all other languages exist for a reason. The reason is that other languages, including Lisp, are not considered to be equally useful for the tasks for which a specific language is being used. Python is not only not Lisp: it's not Java, not Haskell, not Erlang, not ...

Whether it is a good reason, and whether these considerations are sensible, is a separate discussion. Whichever way you put it: they exist and should be acknowledged.


I agree. Lisp just plain looks weird because of all the parentheses and the prefix notation. I also can't help get the feeling that even with macros available to me, coding directly in the form of parse trees just might not be optimal. Also, it makes my head hurt sometimes.

As I sit here writing this, it strikes me that someone who's using these kinds of things to avoid learning Lisp is a lot like the Python newbie who's discovered the language and wanders on to comp.lang.python complaining about the syntactically significant indentation. As with most matters, I'm inclined to believe that Lisp's problem here is primarily a people problem rather than a technical problem.


Wow. First a post on awesomeness of Haml, leading to the usual "Is not!", "Is too!" discussion.

Now a post on Python v. Ruby?

It must be Shark Week on HN.


Not related to the article, but I really like the setting and layout of the top section. Felt like I was reading a magazine!


These fancy new blogazines, as the kids are calling them, make me really wish I had design chops. My regular old blog looks so lame and uninteresting by comparison.


Raganworld's markdown rendered blog @ github http://github.com/raganwald/homoiconic has convinced me that while eye-candy and design is great, it is the content of the blog post itself that is of more value to me as a reader.


Ironically, it did the opposite for me. I used to read and enjoy Reg's blog posts. Since he made the change to the new format, I don't think I've read anything he's written there: it doesn't work like anything else any more, and while his blog was one of those I enjoyed, I rarely go out of my way to find content like that when there are many other blogs competing for my limited spare time.



I like the choice of image--a king snake. Looks venomous, but is harmless.


The caption says San Pueblan Milksnake, but still.


Milk Snakes are a kind of King Snake. I had way too much time on my hands with Time Life's "Reptiles" hardcover when I was little...

The poisonous snake the stripes are thought to mimic:

http://minuet.dance.ohio-state.edu/~gallo54/images/words/sna...


Something weird is happening in that layout though. Maybe it's just Chrome/Webkit but if you double click anywhere a grid overlays itself onto the page. It seems to be on purpose ( background-image: url(http://blog.peepcode.com/images/grid/27px-leading-w-60-80-gr...); ) but it seems quite bizarre.


from the bottom of the page: "Double-click anywhere on this page to see our typographical & layout grid above."


Python versus Ruby has always struck me as one of the absurd battles ever. The two languages seem to address a very similar space and have broadly similar features sets.

Yes there are points of variation but both seem to work really well. People build cool and useful stuff in both. People are productive in both.

As for me - I personally like the syntax of Python better. That could be because I learnt it first - or it could just be something in me. Who knows?

and who cares...


I think a big reason why it comes up so often is that it's rarely worth the mental real-estate to become proficient in both since they are so similar in design and problem domain.

There is significant diminished utility in learning python after knowing ruby or vice versa. You're better of learning something totally different (like haskell!) since you already have a flexible modern scripting language with a great web-framework in your toolkit.

However since each language has its trade offs, people have to keep convincing themselves (loudly and publicly, usually) that they made the right decision.

So basically, it's contentious and will always be that way for the same reasons that people still debate vim vs emacs after twenty years.


I think you're absolutely right, here. Once you know one, you'll probably have much better returns from time spent learning a very different language (such as Erlang, OCaml, or C) than learning the other, barring exceptional circumstances.


This right here is the exact reason that I, as a fairly experienced and hopefully pretty good Python programmer feel absolutely no desire to learn Ruby. It doesn't offer me anything in terms of making me think differently about programming than Python, and I don't see any particular domain (other than, of course, Rails) where it offers an advantage in libraries or anything. On the other hand, had I stumbled upon Ruby first and then found out about Python, I'm sure I probably wouldn't feel any need to learn Python, either.


As a "battle" I think it is stupid. Otherwise, I disagree with you. They're very different languages. Python is great for people who are accidental programmers or non-programmer programmers, especially ones who think mathematically and analytically. It's popular among scientists and engineers who need to understand a language pretty completely in a top-down way, but who want to waste as few brain cells as possible on a programming language because their brainpower is primarily applied to other things.

Personally, I've always programmed primarily in other languages (C++ being mein liebster Feind) but I've relied a lot on Python (and occasionally Jython) for day-to-day scripting and for delivering code to customers that reorchestrates existing code to do new things. Python has never lit a single creative spark in me, but it has always delivered for me without demanding much in return. Now, that is a statement you will never hear applied to Ruby.

I don't know much about Ruby, but the things I hear about it remind me of Perl in some ways. Back in the day, I spent a lot of time learning Perl, promptly forgetting it, and going back to Perlmonks to learn it yet again. Perl comes naturally for impressionists who love to program by instinct, pattern-matching, and trial-and-error. They love it when something new pops into their head and they type it in and it just works, and they aren't immediately sure how or why. Perl is also for dedicated professionals who want a tool that rewards more study and practice with more and more power -- mastery of Perl is a never-ending road with a seemingly never-ending escalation of power and awesomeness.

Ruby seems to be a much more easily understood language than Perl, but (from the outside) it seems to share Perl's magical flavor and open-ended approach to mastery. Python is better for people like me who want working, understandable code for the smallest lifetime intellectual investment.


> Perl is also for dedicated professionals who want a tool that rewards more study and practice with more and more power -- mastery of Perl is a never-ending road with a seemingly never-ending escalation of power and awesomeness.

That sounds more like programming (which you can teach yourself in ten years) than any specific language.


That's a trite response. Complexity, power, and culture differ between languages. In Perl, people make a game out of doing as much in a single line as possible. Experts do things that are mystifying to a beginner. In Python, an expert would be expected to produce a solution that is comprehensible to a less-expert programmer, spanning however many lines as are necessary. It would be un-Pythonic to write code that a less expert programmer couldn't understand.


In Perl, people make a game out of doing as much in a single line as possible.

Wrong. It's not 1995 anymore.

Experts do things that are mystifying to a beginner.

And this is a Perl thing? What I've found from listening to beginners is that they accuse every programmer of intentionally mistifying them. OO is too hard. Macros are too hard. Monads are too hard.

Unfortunately, the experienced programmers use these features because there is a significant productivity advantage in doing so. They don't use the features to intentionally confuse beginners. The good news is that the beginners can use these features too, as soon as they are willing to admit that maybe the experts aren't actually out to subtly screw them over.

In Python, an expert would be expected to produce a solution that is comprehensible to a less-expert programmer, spanning however many lines as are necessary. It would be un-Pythonic to write code that a less expert programmer couldn't understand.

<picture of lolcat>.


I don't think you get that cultures differ, or that Perl one-liners capture something about the Perl culture. There's nothing wrong with the Perl culture, and the Perl language is well-suited to it. It's certainly different from the Python culture. Not only that, the "Python culture" in the sense of people who write about and influence Python is not synonymous with Python programmers, not by a long shot. Programmers are different -- "programmers are programmers" only if you define programmers fairly narrowly as professional programmers who measure their worth by their ability to use programming languages in the most elegant and powerful way possible.

Among software developers, Python programmers are of course keen to demonstrate that Python is just as awesome as other languages. That isn't really the point of Python, though. Python's value was never in how it served people who could afford to devote a lot of time to mastering it. You wouldn't judge a Prius by how fast Michael Schumacher could drive it around a track, would you?

There is a whole population of programmers out there who really don't give a damn about programming languages and who rightly don't invest a lot of time in mastering programming. They exist, they do important work, and Python's ability to serve them is important -- that's the bottom line and the truth, even if this audience isn't eager to hear it. People like that are sensitive to the difference between Ruby and Python, and they've mostly never seen decorators.


> It would be un-Pythonic to write code that a less expert programmer couldn't understand.

I assume you have syntactical concerns and syntactical concerns only in mind, as domain knowledge and local style and creative decisions are far more important for maintainability. Even so, I don't believe you. I've seen far too much Python code which uses decorators and generators and list comprehensions to believe that it's un-Pythonic to "write code that a less expert programmer couldn't understand".


The point is that as a Python programmer, even a casual one, I know what decorators and generators are and can look up how they work. I can pretty confidently expect to figure out what they mean in any case I need to.

And yeah, the language has arguably become less Pythonic as it caters to more expert programmers at the expense of less expert ones. From the beginning, there have been people who claimed that primitive, clear, inelegant code is worse than elegant, concise code that depends on extra language features. Usually that claim has been rejected, but as sometimes happens in politics, the people who care enough to influence the process are not always the people for whom the process is supposed to work. I see decorators as something of a Trojan horse through which Python became more of a language for me (a software developer who copes with, and sometimes even likes, C++) and less of a language for my customers (scientists and engineers). Which is tragic because there are plenty of languages for software developers and not enough languages for people who just need something stupidly simple yet powerful enough for all practical purposes.

Still, despite the erosion of its simplicity, Python stands out for its philosophy of simplicity and its adherence to it. There remains a gulf between a language that sounded a clarion call for simplicity and has slipped a little from its principles and a language that chose the red pill and dove down the rabbit hole basically for the sheer beautiful hell of it.


> There remains a gulf between a language that sounded a clarion call for simplicity and has slipped a little from its principles and a language that chose the red pill and dove down the rabbit hole basically for the sheer beautiful hell of it.

I'm don't understand what the difference between Scheme circa 1975 and R6RS has to do with Python.

It's awfully circular to claim that Python is beautifully Pythonic despite that it's become less Pythonic even as it's adhered to its philosophy of simplicity. If anything, I'd think that a language that "reads like pseudocode!" to the uninitiated wouldn't require even casual programmers to look up syntactic elements in the documentation, the way some people talk about Python.


I agree with you, the argument is pretty stupid.

The reason it gets so heated is that the two languages, while similar from some perspectives, are _wildly_ divergent in philosophy. It really is a Catholic/Protestant battle, as someone pointed out earlier.


> It really is a Catholic/Protestant battle, as someone pointed out earlier.

And who's who? (Not meant as flamebait. I just want to see where the analogy leads to.)


As someone who's raised Catholic and prefers Ruby... I don't think that they map together well in any deeper way. Neither language started off as a fork of each other.

This particular analogy only runs skin-deep.


OK. Thanks!


My take away: As a Python developer, I should really check out Ruby. It's like Python in some ways, but in other ways it may help give me an additional perspective on programming.

Thanks for the article! Mark


More replies like this one, please!


"The Seattle Python community represented there was almost painfully polite. ... I later learned that this may be an attribute unique to Seattle Python developers."

When I lived in Seattle, I read that musicians, playing in PNW clubs and venues and noticing a lower audience energy level than they were used to, sometimes had to be reassured by club owners that yes, the audience really does like you, really, it's just that PNW audiences are more subdued, laid back and polite.


It's not self.call(:my_method) --- that's nuts. It's my_method[param1, param2] which is aliased to my_method.call(param1, param2). Ruby's syntax can be a crapfest (like Procs not being callable without [] instead of () for example), but this isn't an example.


proc[arg1,arg2] is terrible; strictly worse than proc.call arg1, arg2. When I see an id followed by brackets, I'm looking at a collection, not a callable. This is only exacerbated by Ruby's weird/useful [index,length] convention.


I think what we both want is proc(arg1, arg2).


In newer versions of Ruby you can do proc.(arg1, arg2), which I think is a decent compromise.


Wow, I actually never knew that it was [index, length]. I usually just pass a range as the key when I'm doing stuff like that, so you can do "hello"[2..3] (2 <= i <= 3) or "hello"[2...3] (2 <= i < 3).


I think this is a good explanation of some of the very real differences between Python and Ruby. The lambda issue is almost enough to get me back to Ruby after switching to Python. I stick with Python mostly because of syntax (especially significant whitespace) and the batteries-included philosophy. I'm also in love with a Python library called pyparsing, the equivalent of which I haven't seen in any other language.


As an aside, pyparsing is based strongly on the excellent "Parsec" library for Haskell. A number of other languages have similar parser combinator libraries.

If you're looking for Ruby libraries specifically, check out: http://treetop.rubyforge.org/ (Treetop uses PEGs rather than parser combinators, but like pyparsing it integrates very well with its host language.)


Good call on Parsec. Unfortunately, I haven't found Haskell nearly as practical as Python for day-to-day work.

Treetop I had not heard of. It looks interesting.


The only problem I had with Treetop when I tried to play around with it is the same problem that I tend to have with lots of Ruby libraries. No docs other than code. Treetop has docs, but they were kind of sparse last time I looked at them.


pyparsing, the equivalent of which I haven't seen in any other language

Well the "golden oldie" equivalent in the Perl world is Parse::RecDescent (http://search.cpan.org/dist/Parse-RecDescent/).

A new kid on the block is Regexp::Grammars (http://search.cpan.org/dist/Regexp-Grammars/), which is heavily based on Perl 6 rules/grammar (http://en.wikipedia.org/wiki/Perl_6_rules).


I'm not sure I get the lambda issue. If you want a > 1 line lambda why not just define a function?

    def a(x):
        def b():
           print x
        return b
Not sure what a prototypical ruby usecase would be.


The other side of the argument: why support anonymous functions, but restrict them to one line? That seems highly arbitrary.


Nope - not arbitrary, it is because of the indentation scoping rules. Try coming up with a syntax for statement based lambdas that isn't ugly as heck.


First, links for context.

Guido's take: http://www.artima.com/weblogs/viewpost.jsp?thread=147358

Arcieri's take: http://www.unlimitednovelty.com/2009/03/indentation-sensitiv...

It's not hard if we disallow statements, and make everything into an expression that returns a value -- something that Ruby does right. The value of a block of statements is just the value of the last statement in the block.

So, whether you call it a function, or a method, or a lambda, or a block, whitespace with multi-line expressions can be made to work.

The commonly-cited lambda-with-multiple-prints example, in CoffeeScript:

    count: ->
      print 'one'
      print 'two'
      print 'three'


Not one line, one statement.


The prototypical ruby case would be:

  def some_method(x, &block)
    yield x
  end

  then to call it:

  some_method "hey" { |v| print v }
That might not look like much, but it allows you to create methods that can extend the language expressively and then use them without extra crufty syntax or sigils obstructing their meaning.


> some_method "hey" { |v| print v }

I'm sure ruby is great once you're initiated, but despite >10 years of programming and having learned basic, c, pascal, lisp, java, c++, python, perl, bash, php and javascript, I have no idea what code does.

Don't mean to harsh, just an observation.


I made that method absurdly generic, how about:

  get "/hi" do |url|
    print url
  end

?


I don't understand the argument either.. I use multi-line lambdas with ifs and forloops all the time.

  f = lambda x:(
    x if (
      x**2 > 10 or x**2 < 5
    )
    else x**3
  )


I don't think you can assign variables in these blocks, nor do sequential statements. Imagine you wanted to reduce a list, and then do something on it. Print statements don't work either.


That's not a python, that's a milk snake. Feel free to downvote me for pointing that out.


"Without powerful blocks and lambdas, you can’t have Rake. You can’t have RSpec. You can’t have Sinatra’s clear REST syntax."

Can anyone explain why?


Disagree on "REST syntax". Python could do just as well:

Sinatra:

  get '/hi' do
    "Hello World!"
  end
Python 2:

  @get('/hi')
  def hello():
    return "Hello World"
Python 3:

  def hello() -> "/hi":
    return "Hello World"


A Rubyist would argue that that Python 2 syntax is anything but clear.

I have no idea what that Python 3 snippet is doing... care to share? That looks like something that's hard to Google...


As a Pythonista I have no idea what the Ruby snippet is doing. Readability depends entirely on context.

The Python 3 version is using a function annotation.

In Python 2 or 3 you could use a context manager (with statement) to similar effect.


As a Pythonista I have no idea what the Ruby snippet is doing. Readability depends entirely on context.

Oh, come on. You're just disagreeing for effect here.

I've never used Ruby but that snippet is clear as day.

The Python 3 snippet suggests to me that the output would be "/hi" though :)


  Oh, come on. You're just disagreeing for effect here.
  I've never used Ruby but that snippet is clear as day.
The hell it is. I find it quite confusing. I'll take the Python 2 solution anyday, which clearly seperates what is called from when it is called. One of the main problems with the 'my language is so flexible' approach is that inventing concise solutions becomes a goal in itself.


> which clearly seperates what is called from when it is called

You're passing some code as an argument to a function. Many other languages do this. Do you hate Lisp and Haskell, too? Do you not use continuations in Python? Or callback functions?


If you pass a function as an argument to a function, you're still separating what from when: the function declaration shows what; the invocation of the function shows when. It doesn't matter whether it's

  def foo(f):
    f()
or

  (define (foo f) (f))
That has nothing to do with annotating a function to show it binds to some URL and is invoked when an HTTP GET request is received with that URL. I don't like having to scroll through a source file to discover such bindings and I actually prefer them to be defined at a separate place. In that sense, the Python 2 solution isn't good either and suffers from the same problem I described earlier: people try to be so concise that they loose sight of other goals.


The Ruby code is not an annotation. It's very close to passing an anonymous function to a function. The definition of get is

    def get(path, opts={}, &block)
See that &block? Here's the actual source of get:

      # Defining a `GET` handler also automatically defines
      # a `HEAD` handler.
      def get(path, opts={}, &block)
        conditions = @conditions.dup
        route('GET', path, opts, &block)
 
        @conditions = conditions
        route('HEAD', path, opts, &block)
      end
Think of it as "I'm registering this block as a callback, to be called when this url is processed." I'm not sure how else you'd like to have a web DSL written; every web library I've used has worked this way.


The Ruby code is not an annotation.

Which is exactly the problem: it should be, because it is meta-information about when the function is supposed to be called. It's not a good idea to wrap that into a function, together with the code that is supposed to be executed, because you are mixing two completely different kinds of information into some new function. This code is being too clever for it's own good: it condenses information so far that you are forced to think harder about what each piece means. I consider this is one of the main dangers of languages like Ruby: it's proponents lose sight of the fact that they are coming full circle, back to writing code that's so clever that no one in the future will understand it.

every web library I've used has worked this way.

I doubt that we've used a disjoint set of web libraries, so my only answer can be: no, they haven't worked that way. Most libraries map paths to named functions separately from implementing the functions.

Conciseness is not an ultimate goal; in fact, it is rather the opposite, as those that suffered under the clever C hacks of others will tell you. To paraphrase Santanyana: people have forgotten the past and are repeating it.


I guess we'll just have to agree to disagree on this. By keeping the function definition near the route instead of just defining a name, I feel that it's much, much cleaner.

> I doubt that we've used a disjoint set of web libraries,

I guess I mis-spoke slightly. I meant assigning a function to a route, because I consider that (in this case) it's an anonymous function to be an irrelevant detail. Basically, to me

    get "/hello", hello
    def hello
        puts "hello"
     end
to be the as clear or less clear than the way Sinatra does it. Rails and Zend (the two frameworks I've used the most) put that 'def hello' in another file, elsewhere.

Anyway, thanks for the discussion. We've apparently boiled it down to taste, so it's a good thing there are multiple languages, I guess.


Thanks to you as well :). I even may come to see it your way in the near future, as it seems I'm going to be doing some Ruby coding for my new employer.


> Oh, come on. You're just disagreeing for effect here.

It's unclear what "get" is. Is it a function? What does it return? My guess would be that it returns a function bound to the handler of a "/hi" url, but that's a guess.


"get" is a function that takes a string and a block.

And the block is bound to the uri given in the string, so your guess is correct.


Ruby always confuses me with this flexible syntax...


It's possible that you just haven't read enough ruby, then. There are only two variations on the syntax of passing a block to a function, "do/end" and "{ }". By convention, multiline blocks use do/end, and single line blocks use {}.

It's also possible that one of the things in the article is the gotcha, flexible parenthesis. By convention, Rubyists tend to use parenthesis when defining functions, but not when calling them:

    def get(path, opts={}, &block)

    get "/hello" do
not

    get("hello") do
Which would still work, if you preferred. The exception to this is chaining method calls:

    Users.find_all_by_age(23).select {|user| user.first_name == "steve" }
... not that that's an awesome use of ActiveRecord, but whatever.


> As a Pythonista I have no idea what the Ruby snippet is doing.

Fair enough. Arguing over beauty is silly anyway, I just wanted to point out that the entire thing is entirely subjective.

> The Python 3 version is using a function annotation.

Thanks, checking out PEP 3107 now. I've always seen annotations done with the @annotation syntax like the Python 2 snippet has.


> Thanks, checking out PEP 3107 now. I've always seen annotations done with the @annotation syntax like the Python 2 snippet has.

The @ syntax is for decorators. Different beast altogether.


Ah. So, Python uses the Java annotation syntax for decorators? Hm. One more thing I'll have to look into when I get the time.


Actually, I think Java uses Python decoration syntax for annotations, but I have been wrong before.


I'm pretty sure Python picked it up after Java did. But, I don't think it's a case of imitation; it's just that the glyph '@' happened not to have syntactic meaning attached to it and it looks okay.


No, they're exactly the same beast!

I've used decorators to add attributes to function objects in several projects in the past -- you don't have to wrap the original.


It's using function annotations as a way to describe which URL to route to. Function annotations aren't used by anything in Python3 by default, so it's one possible way to do that.


I would prefer to use a decorator for that.


> A Rubyist would argue that that Python 2 syntax is anything but clear.

Why does that matter? The syntax should be clear to a capable Python developer, not someone who has never used Python.

I'm not suggesting that that particular syntax is or is not clear to said Python programmer, merely that the consideration for a Ruby programmer is useless.


Because "he's a Rubyist" is the reason he would say something like "you can't have Sinatra's clear syntax."


Just for kicks. In CoffeeScript:

    get '/hi', ->
      "Hello World"
You can have your cake and eat it too.


Decorators and annotations are very useful in Python, but I still like the terseness of Ruby--no need to define "hello()". Of course, Python wins on a different kind of terseness--no do/end--but that is mostly orthogonal.


And you could use {} instead of do/end, but a Pythonista wouldn't consider that any more terse.


Yep, my mention of do/end or squigglies was just a caveat on the Ruby-is-more-terse-in-this-example statement in the context of anonymous functions or blocks. I wish there was a language that won on both terseness metrics--i.e. a Ruby with indentation or a Python with anonymous functions.


I've never worried much about which language I use to GET hi. As long as the end result is same, everyone should be feeling good.


Python doesn't have multiline lambdas, so there is no way to create an api similar to rake's:

  task :name do |t|
   # do stuff
  end
I'm not sure what's the closest equivalent syntax you could create in python.


Python's answer to blocks tends to be the with statement, so your example would look like

  with task('name') as t:
    # do stuff with t
It's not really the same; the task object doesn't have control over whether the block is actually run, but sometimes it is sufficient.


You could almost certainly achieve that with the implementation of blocks provided by this package:

http://pypi.python.org/pypi/withhacks/


Wow, I've never seen that before. I'm also not sure I'd say a solution that uses bytecode rewriting is really working within the language, but that's a pretty interesting package anyhow.


Well, normally I would agree - but if its entirely abstracted away in a library (and the library is well written) then it might sort-of-kind-of-maybe be ok.

Python itself does varying degrees of bytecode optimisation depending on which version you're using.


that's cool, thanks ... I was wondering about that


Why do you need lambdas to do this? Why wouldn't an inline function work?


This is correct, it would work. People who harp on this probably don't actually use Python for anything.


Not sure what this snippet does, but if it creates a block that is registered as a task named "name", then you can do the same with decorators:

    def task(f):
       register_task(f.__name__, f)
       return f
    
    @task
    def name(t)
       .....
or similar.


Exactly. I fail to understand why people are so dismissive of languages/approaches that do things slightly differently and don't implement equivalent things in the exact same way. What's so special about the rake syntax?


Another CoffeeScript snippet, if you're working with Node.js or the like:

    task 'name', (t) ->
      # do multiline stuff


For something like RSpec, you can't monkey-patch in Object#should.


Are you saying this because you can't monkey-patch literals? Because you can very much monkey-patch everything else in Python.


As far as I know, Python doesn't have open classes, right?


  >>> def print_a(inst):
  ... 	print inst.a
  ... 	
  >>> class Foo(object):
  ... 	def __init__(self, a):
  ... 		self.a = a
  ... 		
  >>> Foo.print_my_a = print_a
  >>> f = Foo(5)
  >>> f.print_my_a()
  5
Not sure why my previous post was downvoted, unless maybe your definition of monkey-patching is different than mine.


Well, I didn't downvote it, but you can't do this with _everything_ in Python, like you can in Ruby.

    $ irb
    irb(main):001:0> class Numeric
    irb(main):002:1>   def wtf
    irb(main):003:2>     puts "hey"
    irb(main):004:2>   end
    irb(main):005:1> end
    => nil
    irb(main):006:0> 5.wtf
    hey
    => nil


A main take away point: Ruby is better for writing DSLs (which is what I am doing for one customer right now)


Scala is awesome for writing DSLs allowing things that I wouldn't even know how to start in Ruby. (granted, my Ruby-Fu is sub-par so the fault likely lies with me).

http://blog.fogus.me/2009/03/26/baysick-a-scala-dsl-implemen...


Smalltalk is even better. Advanced Smalltalk is morphing Smalltalk into a DSL. You can even write your own domain specific if-then-else analogues, and it looks 1st class like the Standard conditional logic. Yet the implementation is just a plain vanilla method.


You can't morph Smalltalk into a DSL as Smalltalk itself is nothing but a DSL; syntactically every single control structure is library.


I prefer to think of it this way: DSL are syntactic 1st class citizens in Smalltalk. (Not 1st class for optimizations, though)

To say Smalltalk IDS is a bit useless. Sure, if your "domain" is some Turing-complete language.


> Sure, if your "domain" is some Turing-complete language.

Which is exactly what Smalltalk is. Pick any other domain, and you can use the same syntactic elements used to build the base language to extend it into that particular domain.

Ruby DSL's control structures tend to look nothing like Ruby the language's control structures; Smalltalk DSL's control structures look exactly like Smalltalk the language's control structures.


Also try Haskell if you want to do DSLs.


    Python lambdas are limited to one line and can’t contain
    statements (for, if, def, etc.). Which leaves me
    wondering, what’s the point?
As much as I wish that the python lambda syntax was more powerful, they are ridiculously useful for one-liners where you can't use forms that require whitespace indentation. Everything must consist of set operations.

    cat file | python -c "import sys; lines=sys.stdin.readlines(); lines_i_care_about = [str(l.split(',')[2]) for l in lines if l.split(',')>=3]; print '\n'.join( lines_i_care_about )
(yes you could do this example in awk or sed, but that's not the point)


As others have pointed out, you could just use a non-anonymous function defined in the current scope in place of a lamba...


It's silly to use Python when sed or awk would yield better solutions.

It would be sillier to use Java. Or COBOL.


"Lisp chainsaw"?

Definition or reference, anyone? Although I can probably guess where this is leading....


It's a play on the old description of Perl as a swiss army chainsaw


I hate this stupids discussions and I have seen many pythonist criticizing ruby..why?...because think ruby is a rival?...I use java and ruby..one reason for never choose python is his fanboy community w close mind and always criticizing the other languages..like java..c# ruby...yes..your language is better and is perfect but not everybody prefer it...if you learned a language only for speak bad of it is better no learn it, when you has a few days using ruby is than understand all thing back it...star type code without parentesis and see it look better and is most readeable (I remember you I come from java), I use a bit python and his syntaxis is good but i don't like all...never I feel good using it (I feel more limited) but I don't writte a article criticizing python, ruby is the language for peoples without limits and free mind, RUBY IS THE MOST ELEGANT LANGUAGE I HAVE KNOW, and is very readeable (no exceeds python but is very readeable) for all other reasons I think python could win the discussion forget this discussions and allow ourselves know new ways to learn and write, this discussion are like the religions discussion, nobody win and only works for create bad ideas for the others...peace and sorry for my bad english, I'm germany


I believe Python has a yield statement, or am I missing something?

http://docs.python.org/whatsnew/2.5.html#pep-342-new-generat...


Indeed. Perhaps the Ruby one works different?


Yep. `yield` in Ruby is a normal anonymous method call. It pushes a new frame onto the stack. `yield` in Python works more like Ruby's [Generator](http://ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/Gen...). It freezes the current stack frame's state and resumes execution somewhere else, returning again to the same place on the next iteration. They're very different things really.

More about Python's generators here:

http://www.python.org/dev/peps/pep-0255/


So what would yield in Ruby be like in Python? Surely there must be some analogue?


You can pass an anonymous function or lambda:

    def foo(thing, block):
      thing = "cruel " + thing
      block(thing) # like `yield thing' or 'block.call' in ruby

    def bar(thing):
      return "hello " + thing

    foo('world', bar)

    # or:
    foo('world', lambda x: "hello " + x)
Ruby's blocks are really just sugar for passing an anonymous function in the last argument and yield is just sugar for calling that function. The example above in Ruby would be:

    def foo(thing)
      yield thing
    end

    foo('world') { |thing| "hello " + thing }


Ruby's yield is essentially just calling an anonymous function given to it in the form of a block. e.g., the following code snippets are equivalent

Ruby:

    def foo(bar)
      if block_given?
         yield bar
      end
    end

    foo 5 { |x| puts x } # prints 5
Python:

    def foo(bar,fcn):
        fcn(bar)


    foo(5, lambda x: sys.stdout.write("%d\n" % x))
The only real difference being that the ruby code is calling a block versus a "real" function.

edit Oops, had this page open for a while, didn't realize someone had replied in the interim, making my response somewhat redundant


Nice article. One correction: python does have 'yield'.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: