16 ms·
What Pythonistas Think of Ruby
- DanielStraight 17y agoI 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.
- mbrubeck 17y agoAs 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/ http://treetop.rubyforge.org/ (Treetop uses PEGs rather than parser combinators, but like pyparsing it integrates very well with its host language.)
- DanielStraight 17y agoGood 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.
- steveklabnik 17y agoThe 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.
- draegtun 17y agopyparsing, 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/ http://search.cpan.org/dist/Parse-RecDescent/). A new kid on the block is Regexp::Grammars (http://search.cpan.org/dist/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 http://en.wikipedia.org/wiki/Perl_6_rules).
- mclin 17y agoI'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.
- gcampbell 17y agoThe other side of the argument: why support anonymous functions, but restrict them to one line? That seems highly arbitrary.
- kevingadd 17y agoNot one line, one statement.
- fuzzyman 17y agoNope - 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.
- jashkenas 17y agoFirst, links for context. Guido's take: http://www.artima.com/weblogs/viewpost.jsp?thread=147358 http://www.artima.com/weblogs/viewpost.jsp?thread=147358 Arcieri's take: http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html 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'
- brutimus 17y agoI 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 )
- lsb 17y agoIt'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.
- tptacek 17y agoproc[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.
- lsb 17y agoI think what we both want is proc(arg1, arg2).
- duairc 17y agoIn newer versions of Ruby you can do proc.(arg1, arg2), which I think is a decent compromise.
- duairc 17y agoWow, 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).
- gsiener 17y agoNot related to the article, but I really like the setting and layout of the top section. Felt like I was reading a magazine!
- chasingsparks 17y agoFYI: http://news.ycombinator.com/item?id=950321 http://news.ycombinator.com/item?id=950321
- sant0sk1 17y agoThese 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.
- r11t 17y agoRaganworld's markdown rendered blog @ github http://github.com/raganwald/homoiconic 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.
- Silhouette 17y agoIronically, 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.
- ericb 17y agoI like the choice of image--a king snake. Looks venomous, but is harmless.
- three14 17y agoThe caption says San Pueblan Milksnake, but still.
- deleted 17y ago[deleted]
- rbanffy 17y ago"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?
- arockwell 17y agoPython 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.
- tsuraan 17y agoPython'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.
- fuzzyman 17y agoYou could almost certainly achieve that with the implementation of blocks provided by this package: http://pypi.python.org/pypi/withhacks/ http://pypi.python.org/pypi/withhacks/
- mark_l_watson 17y agoA main take away point: Ruby is better for writing DSLs (which is what I am doing for one customer right now)
- kashif 17y agoAlso try Haskell if you want to do DSLs.
- stcredzero 17y agoSmalltalk 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.
- gnaritas 17y agoYou can't morph Smalltalk into a DSL as Smalltalk itself is nothing but a DSL; syntactically every single control structure is library.
- stcredzero 17y agoI 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.
- gnaritas 17y ago> 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.
- 17y ago
- pavelludiq 17y agoI 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.
- steveklabnik 17y ago>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-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 http://news.ycombinator.com/item?id=416589
- pavelludiq 17y agoYes, 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.
- steveklabnik 17y agoI 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.
- raganwald 17y ago
- joblessjunkie 17y ago"Lisp chainsaw"? Definition or reference, anyone? Although I can probably guess where this is leading....
- madair 17y agoIt's a play on the old description of Perl as a swiss army chainsaw
- deleted 17y ago[deleted]
- deleted 17y ago[deleted]
- old-gregg 17y agoAs 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.
- sreque 17y agoDo 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.
- patio11 17y agoThe fights are so vicious because the stakes are so small. (Originally said about academics, but works for programmers, too.)
- berntb 17y agoI 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? :-)
- tghw 17y agoI'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?)
- KirinDave 17y ago> 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".
- showell 17y agoYou 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.
- deleted 17y ago[deleted]
- KirinDave 17y agoI 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.
- chromatic 17y ago> 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.)
- 17y ago
- junklight 17y agoPython 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...
- dschobel 17y agoI 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.
- pmiller2 17y agoThis 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.
- silentbicycle 17y agoI 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.
- megamark16 17y agoMy 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
- kemiller 17y agoMore replies like this one, please!
- cturner 17y agoPython 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)
- nfnaaron 17y ago"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.
- deleted 17y ago[deleted]
- jamesbritt 17y agoWow. 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.
- AdamN 17y agoI believe Python has a yield statement, or am I missing something? http://docs.python.org/whatsnew/2.5.html#pep-342-new-generator-features http://docs.python.org/whatsnew/2.5.html#pep-342-new-generat...
- eru 17y agoIndeed. Perhaps the Ruby one works different?
- rtomayko 17y agoYep. `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/Generator.html 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/ http://www.python.org/dev/peps/pep-0255/
- AdamN 17y agoSo what would yield in Ruby be like in Python? Surely there must be some analogue?
- rtomayko 17y agoYou 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 }
- 17y ago
- PostOnce 17y agoThat's not a python, that's a milk snake. Feel free to downvote me for pointing that out.
- pheinberg 17y agoNice article. One correction: python does have 'yield'.
- angelOS 17y agoI 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