8 ms·
curious what you prefer about Ruby. i'm very familiar with python, and have only looked at Ruby long enough to decide (mistakenly?) that it wouldn't do anything
by exit 16y ago
curious what you prefer about Ruby. i'm very familiar with python, and have only looked at Ruby long enough to decide (mistakenly?) that it wouldn't do anything for me which python doesn't already.
- cageface 16y agoPython and Ruby are very much alike but I find Ruby more ergonomic. It's more consistently object-oriented, which means I spend less time looking things up because the core is easier to remember. The syntax is more expressive, which makes my code shorter and easier to read. The consistent use of blocks everywhere is more intuitive and consistent than Python's mix of loops and comprehensions. I find I can take in a block of Ruby at a glance. Python requires closer inspection. Everything in Ruby is an expression that returns a value whereas Python has statements and expressions and it's up to you to remember which are which. Ruby feels to me like the product of an astute student of languages that borrowed the best ideas from Smalltalk, Lisp, Icon etc. The design mistakes in the first versions of Python, mostly now corrected, suggest to me that Guido didn't do his homework as dilligently. Perhaps I'm way off here but the languages seem to me to show some of their cultural heritage. Python has a blunt & minimalistic Dutchness about it while Ruby has a Japanese elegance and style.
- dedward 16y agoThat's about it - Python has a richer, more refined set of libraries to call on than Ruby. (Ruby also has a ton...) Ruby is more fun,but python is more mature. In the end - whatever gets the job done right?
- mkramlich 16y agoYou gave a great comment. I get almost completely the opposite take on Ruby versus Python though: There are a number of things that made me think Ruby was made by a less astute designer. The 'end' everywhere feels bad in a world where I know both "}" and a newline can accomplish the same thing but with less typing and screen clutter. Also do not like Ruby's dropping of ()'s from fn call statements, because it blurs the boundary with non-calls and non-expressions and control flow keywords. I also feel Ruby encourages a certain kind of DSL creation which makes the code harder to read and maintain. I also don't think every app or library needs to export a DSL into client space. It's better if the interface it publishes still looks and feels like the prog language used. That said, I acknowledge Ruby has good qualities. Python is not perfect, but to me it gives the better designed feeling. Actually the Lisps seem to be the most elegant and powerful. Love their regularity and power but not (yet) all the parentheth everywhereth.
- cageface 16y agoRuby certainly has some rough edges. I don't find the redundancy of end/} a big deal in practice but I do wonder what Matz was thinking when he put them both in the language. The omission of parentheses from function calls can occasionally add some confusion but it makes uniform access to properties transparent without the property hack that Python had to add to accomplish this. It seems like Python has had to add a lot of new, non-orthogonal stuff over the years to catch up to what was elegantly possible in Ruby from the beginning. People sometimes do go overboard with DSLs in Ruby too but the big problem I have with Python code is that it all looks the same. The shape of Ruby code is usually a good indicator of what it's doing, partly thanks to DSL. Python seems to have gone just far enough in making all code look the same to defeat quick visual intuition. Why not take it a step further and get a completely regular, homoiconic syntax and all the Lisp-y benefits it brings? To me Ruby hit the sweet spot exactly between Lisp and Perl. If I had to code in Python I wouldn't hate it though. There are far worse languages.
- steveklabnik 16y agoRuby is incredibly flexible, whereas Python is not. Often times my idea of the way things should be done is not Guido's idea, and so Python seems a bit lacking. I really enjoy the pretty simply object model, the message passing OO, and blocks. An interesting point that I read somewhere the other day, from someone who codes in a lot of both: Ruby (to him) is kind of ugly, and Python is very pretty. Yet, the exact parts that make Ruby ugly allow it to have _awesome_ libraries. Python, with its rigidity, means that the core language is great, but the libraries end up being worse because of it. He uses RSpec as an example, specifically. So for him, Ruby ends up being better to use, even though he likes the Python language better.
- eru 16y ago> Ruby is incredibly flexible, whereas Python is not. Often times my idea of the way things should be done is not Guido's idea, and so Python seems a bit lacking. Apropos: Does Ruby optimize tail calls?
- steveklabnik 16y agohttp://stackoverflow.com/questions/824562/does-ruby-perform-tail-call-optimization http://stackoverflow.com/questions/824562/does-ruby-perform-...
- eru 16y agoThanks, I did some searching and found this, too, after I wrote my comment.
- asher 16y agoAll the popular scripting languages "do" the same things. But I prefer Ruby to Python (while still liking Python) because it feels more programmer-friendly. Ruby: a = %w( apple pear orange ) Python: a = [ "apple", "pear", "orange" ] Ruby: a=%q/O'Malley says "Hello"/ Python: a = "O'Malley says \"Hello\"" Python lets you use "'" or '"' as the delimiter, which solves 80% of these cases - but why not generalize the concept, as Perl and Ruby did? In Ruby, the last expression in a function is the return value; in Python you must use the return keyword, even though there's no ambiguity.
- dlsspy 16y agoa = '''O'Malley says "Hello"'''
- kragen 16y agoMy usual approach to the first one in Python is: a = "apple pear orange".split()
- Goladus 16y agoWhile it's true that "last expression in a function" is not technically ambiguous, because of python's statement/expression distinction leaving off the return can lead to unclear code. For example, if there's a function composed entirely of print statements, the last expression evaluated will be the expression in the last print statement executed. But, that means you have to know that 'print' is a statement and not an expression, and that the right-hand side of the print statement is in fact an expression. In ruby, actions like prints and assignments are side-effects and always evaluated as expressions. So if puts is the last expression in a function you'll get the return value of puts (which is usually nil I believe). That's pretty simple.
- asher 16y agoGiven a = [1, 2, 3, 4, 5]: Ruby: a.map{|i| i+1}.reject{|i| i%3 == 0}.map{|i| i*i} Python: [i*i for i in filter(lambda i: i%3 != 0, [i+1 for i in a])] Please ignore the fact that the whole operation can be simplified mathematically - nontrivial map-grep-map operations do occur. I find the Ruby version clearer because it proceeds from left to right like a shell pipeline.
- samdk 16y agoI see your point, but I think your Python's not terribly idiomatic and that's a big part of the problem. This is easier to read and understand, only goes through the list twice, and loses nothing in terms of power: [j*j for j in [i+1 for i in a] if j%3 != 0] (And for any given operation, there's very possibly a cleaner way to abstract out the inner list comprehension, which would again make it a lot nicer.) In general, I don't see much of a reason to use filter/map/etc in Python: weak lambdas mean they're not terribly powerful. List/sequence comprehensions can do everything they can do with cleaner syntax and/or fewer operations. This, I think, is actually at the core of this whole discussion. The Ruby/bash approach makes sense if you're used to working with sequences like Ruby/bash do. The Python approach is more natural to me though, because I've written a lot of Python. (And having spent the last year writing a lot of Ruby, I still find the Python approach cleaner/easier to understand at a glance.)
- LordLandon_ 16y ago[(i+1)**2 for i in a if i%3!=2] Goes through the list once, and reads like set notation! (and does i+1 once, which is what I assume you were going for with the separate [i+1 for i in a])
- samdk 16y agoI kept the i+1 separate because the parent noted that this was a trivial example and wanted to make a point about the more general map-filter-map operation. I wanted to make the point that you can do the map-filter-map in Python more succinctly and more efficiently without sacrificing any power or flexibility. In this example, yes, it's easy to solve the problem with only one iteration through the list. In a more complicated example (especially when the first map step is expensive and you really only want to do it once) this kind of solution may not work.