Python vs Ruby, slightly more in-depth
rapd.wordpress.com
rapd.wordpress.com
Note that, if I correctly understood, python event engine Twisted uses a custom C-implemented event loop to avoid this.
[1] http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ru...
[2] http://groups.google.com/group/comp.lang.ruby/msg/e809a7a720...
Wow, seems like MacRuby uses OS threads and completely abolished the GIL [3].
[3] http://www.infoq.com/news/2009/06/macruby-drops-gil-threadin...
Having said that, I welcome Google's unladen swallow and hope they succeed in removing the GIL.
Here are some of the reasons Python uses a GIL: http://www.grouplens.org/node/244#comment-2493
Pasted for convenience:
""" Python has a GIL as opposed to fine-grained locking for several reasons:
--- It is faster in the single-threaded case.
--- It is faster in the multi-threaded case for i/o bound programs.
--- It is faster in the multi-threaded case for cpu bound programs that do their compute-intensive work in C libraries.
--- It makes C extensions easier to write: there will be no switch of Python threads except where you allow it to happen (i.e. between the Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros).
--- It makes wrapping C libraries easier. You don't have to worry about thread-safety. If the library is not thread-safe, you simply keep the GIL locked while you call it. """
Not really. Stackless Python still has a GIL, and if you want to make use of multiple threads, the GIL will still bite you.
Stackless allows you to write coroutines and has lots of cool abilities, but avoiding the GIL is simply not one of them as far as making use of multiple cores.
25 processors buys you a lot of programming time.
I don't think this is a good article nor a useful one.
I mean come on, just look at the 'conclusion': These languages are interchangeable, especially for building web application. Neither are more awesome. They get the job done and they make programmers happy.
As one wise man once said: Wether you prefer Python or Ruby depends mostly on which one you met first.
At this point in the Ruby VS Python conversation, my expectations for an evaluation are benchmarks of code that is algorithmically identical. If one language provides for a better algorithm than the other, I'd like to see those differences as well.
* Beautiful Soup vs Nokogiri/HPricot * Fabric vs Vlad * Paste vs Mongrel performance using proxy pass behind Nginx * (I am not going to write Rails vs Django)
I intentionally downplay what Python has to offer. It is true that Python has greater breath than Ruby in terms of communities, especially outside web world.
If I started to mention those, it will make Ruby looks less capable (or I would naturally skew the article biased towards Python).
"intentionally downplay" is a bad choice of words, sure, but I think he means "am only comparing web stuff". Most web developers do not care about SciPy. Most research scientists don't care about web frameworks.
(Edit: and this is downmodded too? Did Programming Reddit change their color scheme again?)
I also see that you were apparently unaware that lambda exists in Ruby until someone in the comments told you, which makes me seriously doubt that you've even used the language at all.
Googling around for info on a language with which you have limited or quite possibly no experience is not a basis for purporting to present an "in-depth" comparison, nor does it qualify you to make claims about capability of a language.
* (Django, Pylons vs Rails, Merb) * (web.py vs sinatra) * (Beautiful Soup vs HPricot) * (Paste vs Mongrel) * (Moneta vs Shove) * (Psyco vs RubyInline)
I would defend myself and say that all these modules are useful for web development. For example:
* You never had to scrape other site's HTML and parse the elements for useful information?
* You never curious about hot-and-shiny key value databases for work?
* You never felt like a certain function could have been optimized and make your web app faster?
Especially in these two paragraphs, I actually use all the ruby modules I mentioned in those paragraphs (minus merb & DataMapper), and I use all the Python modules mentioned as well.
For other non-web related or modules that I haven't use frequent enough, i set it aside and "downplay" it in the article.
Lastly, no amount of blog post could do justice on these two languages. The best way to know about these languages is to use it to hack on something.
It's very unusual for a web developer to work directly with RubyInline. It's quite a stretch to classify it as a "web development tool" or significantly related to "Web Apps."
"I made almost immediate comparison between the two"
It's not even close, though. The Ruby analogue to WSGI and Paste is Rack, not Mongrel. RubyInline and Psyco are very different things. HPricot is one of multiple options for HTML parsing in Ruby (nokogiri, scrapi, scrubyt). There are multiple JSON options for Ruby (including yajl bindings), and half the paragraph is about simplejson vs python-cjson, which has nothing to do with Ruby. There are also multiple Ruby templating systems available (erb, erubis, haml, markaby, liquid), but you only mention python templating enigines.
And all of these are just a small subset of libraries that you can have in a typical web app, such a small subset that they aren't really representative of anything.
"You never curious about hot-and-shiny key value databases for work?"
There are a whole slew of libraries for "hot-and-shiny" data stores (there are at least 5 Ruby libraries for couchdb alone) and it's not uncommon for people to roll their own. I don't think shove even supports anything "hot-and-shiny" like couchdb, tokyo, cassandra, etc.
"The best way to know about these languages is to use it to hack on something."
This is very true.
Python > http://pleac.sourceforge.net/pleac_python/index.html
Ruby > http://pleac.sourceforge.net/pleac_ruby/index.html
Coverage varies depending on the language.
Really? These are all the same thing? I think not.
"Python comes with webbrowser, urllib2, smtp, http, SocketServer, HttpServer, and more, while Ruby only has net/HTTP"
Untrue. Seems the author knows Python, and spent a little time with Ruby.
More useful points to make would have been how objects are implemented, how inheritance and mixins are handled, and the key paradigms in the language (e.g., in Python, foo.bar() means invoking the method bar; in Ruby, it means sending foo a bar message.)
Be it calling function, setting attributes, or adding extra functionality by including modules.
So here's my main complaint: If you know that these things are not really the same, why do you present them as if they were? You would have had a much more favorable reaction had you been more upfront on your biases, limited Ruby experience, and narrow focus for comparison.
Whichever technique I choose to use does not matter.
I am using my blog the way blog is intended to be used, as opinion piece, I had no attempt in hiding my biases, but there's no need to purposely be biased as well because I like both and make a living out of both.
OTOH, I'm a big fan of the What's New in Python X.X articles. Nice features like spawn() seem to sneak into the Ruby codebase unheralded and practically unnoticed.
Yes, testing in Ruby is absolutely wonderful. It makes writing tests an enjoyable experience compared to pretty much any other language I've used. Nowadays I strive for 100% C0 testing coverage and near-100% C1 testing coverage whenever I write software. This can be done very easily in Ruby but is hard to very hard in most other languages.
But anyway, "100% code coverage" is very misleading. Sure, every branch might have been executed once, but you don't ensure that every combination of branches executed once. If you have state that can be shared between code paths, then you are not doing an adequate job testing.
(This is why people like functional programming. One input always produces the same output, cutting the number of cases you have to test dramatically.)
The default configuration for RubyGems doesn't run unit tests. Therefore unit tests provide a sophisticated check for, "Works on my machine" but isn't so helpful for getting good bug reports about what doesn't work on other people's machines. By contrast the default configuration for Perl's CPAN runs unit tests before you install anything, and this has been the default for Perl modules since the last millennium. (Actually unit testing has been part of Perl culture since 1987! Yes, the "make, make test, make install" idiom was in the first release of the Perl core. This was over a decade before Kent Beck began popularizing the idea for a broader audience.)
And it doesn't end there. For instance the Ruby world has no real equivalent to CPAN Testers. That's a distributed group of people who run all of the unit tests on all of the CPAN modules on different platforms and make publicly available reports of success/fail. That project runs nearly a half-million test suites per month. Which makes it possible to do things like dependency analysis on CPAN modules to track down who is causing what other modules problems. See http://ali.as/top100/.
In short I'm glad that you're doing unit testing and like the tools that Ruby offers for it. However if you're open to cross-pollination, there ARE things you can learn about unit testing from other language communities. Some of them might be great additions to Ruby.
I stopped reading at this point. More complicated debugging is a reasonable tradeoff for intuitive APIs. To call them evil indicates the OP is quite inexperienced.
Not that big of a deal, but enough to annoy me.
huh?
Python decorator does not do that?
@decorator2
@decorator1
def foo(*args):
pass
is just a shorthand for def foo(*args):
pass
foo = decorator2(decorator1(foo))
I completely fail to see the visitor pattern here, even with stretching until breaking.@decorator1 can be a completely different class which manipulate foo.__class__
Certainly, you can use decorators as a tool to implement the visitor pattern by implementing some hairy, magical reflecting class-decorator which adds a method visit to an object, which then calls visit_{CLASSNAME} on the parameter, but this is just a way of implementing this and not the visitor pattern in itself.
Ruby's ActiveMerchant is a well-crafted bit of code. The handful of python contenders I've discovered are (1) immature and often poorly coded, and (2) unable to touch ActiveMerchant in terms of number of supported gateways and features supported per gateway.
But, honestly, I know how it would turn out: The technical considerations are not all that different. Most people who bitch about one of the two and praise the other seem to not understand the one they are bitching about, and the pattern is strong enough at this point that it should be considered the norm. I'm tired of Ruby advocates who seem unaware that yes, Python can pass functions as first class arguments and yes, that pretty much is a block, and tired of Python advocates who get shredded in the comments for obviously having only gone through a Rails tutorial.
In the end the big difference is community. I think there is a big difference there. I'll skip igniting a flamewar by trying to characterize the communities, since it is impossible to do that neutrally, but there's definitely a difference I can see.
Python Ruby
map collect,map
lambda block
filter select
? reject
reduce (functools) inject (native)
Guido van Rossum on inclusion of 'reduce' in Python 3.0, in 2005:"This is actually the one I've always hated most, because, apart from a few examples involving + or *, almost every time I see a reduce() call with a non-trivial function argument, I need to grab pen and paper to diagram what's actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability of reduce() is pretty much limited to associative operators, and in all other cases it's better to write out the accumulation loop explicitly" (http://www.artima.com/weblogs/viewpost.jsp?thread=98196)
Ruby lets you do it however you want to. I don't see myself learning Python any time soon.
I don't miss anonymous functions that much, yet, because I have inner function and list comprehension in Python.
Both still needs javascript to make awesome looking web applications.
Not so much "looking", as js would not help with that, but working, yeah.