Hacker News new | comments | show | ask | jobs | submit login
Ruby is beautiful (but I'm moving to Python) (wit.io)
122 points by ColinWright 1726 days ago | hide | past | web | 64 comments | favorite

I wrote this article almost a year ago as a tribute to my favorite language at the time. (That title now belongs to Clojure.) It feels like if you want to do scientific computing in Ruby, you're met with obstacles at every turn, but with Python, you're greeted with open arms and tested libraries. That could change (and I'm beginning work on a stats library for Ruby), but it will take time. This was partially a call to action to the Ruby community to start thinking about more than Web protocols and NoSQL databases.

For a more thoughtful comparison, feel free to check out my followup posts.

I had a similiar experience myself actually. You should actually check out the R language if youre interested in scientific computing. Speaking of the python communittee i watched many videos from djangocon this year and was really impressed by the openness of the leaders of the project. Also django i think is rally starting to gain more momentum. Alot of very cool things going on with the framework and communitee..

From the article:

"I’ve already used Ruby at work to dramatically speed up some of our vaccine screens—for processing and summarizing data—but I’ve always had to pipe my numbers into R for statistics and graphing. Because unfortunately, despite all the hubbub around Ruby, no one is crunching numbers with it! I’m sick of R, though, and I want a complete solution for my numbers needs."

have you tried Mathematica? in terms of abstractive power, i haven't found a more powerful language (it's 1 notch more abstract than Lisp) and it comes with a ton of statistics/science stuff and can import infinity different formats



What is the state of Incantr (or something like that was the name)? A Scientific Computing framework for Clojure.

Pardon, here's a link that works: http://clojuratica.weebly.com/

For Clojure, there's also Clojuratica: <http://clojuratica.weebly.com/>, which lets you trade data between Clojure and Mathematica seamlessly.

I never really understood the drama around switching tools. Picking the right one for the job is the first thing you should do.

I'm fine with being fairly passionate with your "default" language you turn to more often than not. Personally, I really love Ruby, and I'm happy with that.

The problem is the whole attacking thing. If you really love another language, that's cool. I definitely sided more towards the camp of "fuck you, my way is better" in my younger days... I think it's just something most people grow out of, in time. Either in maturity, or in sheer terms of being exposed to different ways of thinking.

Now I just find people's taste in other languages fascinating. Always more to learn, even if it's not directly relevant to your situation.

From "Don't Call Yourself A Programmer..."[0] recently seen on the front page:

Many asked how to know what programming language or stack to study. It doesn’t matter. There you go.

That's how I feel about this post -- it doesn't matter. The points he raises -- either as complaint or as praise -- seem shallow. It's not a very sophisticated critique of anything.

[0]: http://www.kalzumeus.com/2011/10/28/dont-call-yourself-a-pro...

I did something recently I wish I did years ago, I picked up a second language for personal projects. Which just so happened to be python, but I agree it probably doesn't matter, but from my experience don't use the same language you use at work everyday.

I'm not sure if I'm alone but I spend WAY to much time in front of my computer. 8-10 hours a day working, and then I often use my laptop casually to write stuff at night in front of the TV.

There came a point several years ago where I became disgusted with Windows. Not so much Microsoft, more enterprise infrastructure teams. But the negativity flowed over to personal use. So I brought a mac for personal use, I wanted the disconnect between work and fun. Windows for me is over, I'll never have another Windows machine in my house... in fact it will mainly be appliances for me... and by that I mean Apple products.

For a long time I plugged on using mono, but I lost the drive to program it just wasn't fun anymore. I'd get 80-90% of the way through a project and just hate finishing it. As soon as the fun exploration bit was over and I had to spend time aligning pixels or whatever it just felt like work. I hated it.

By pure chance I started using python to show my unskilled friend some ideas. He could follow python without much guidance, C# confused him. Since then I've grown to enjoy programming in the evensong again. I'm not sure if its the same disconnect I needed between work/fun or what... but its working.

Especially the ability to sit with my macbook, feet up on lazy chair, half watching TV, terminal open testing bits and pieces, IDE doing the thinking for me (PyCharm gets a thumbs up from me), and a nice hassle free (and inspectable) stack. The casual nature of python just seems to click perfectly with my mood in the evenings.

So theres my advice for languages, separate work and fun. Don't use the same stack for enjoyment as you do for stress endeavors.

> Many asked how to know what programming language or stack to study. It doesn’t matter. There you go.

That relativist thinking is not appropriate. If everything is a matter of personal taste, then constructive discussions are not possible anymore, and become as interesting as small-talks about the weather. It is the end of thinking.

except that you have to invest a lot in a tool and switching has significant costs.

What he says about higher order functions rings very true for me. I learned Python before Ruby, and while I love using both languages, in Ruby I really learned for the first time the power of higher order functions because they are thrown in your face when using it. They are everywhere in the standard library and the syntax makes them very convenient to read and write. They are idiomatic Ruby.

Once I learned Ruby, I started using higher order functions in other languages. Learning Ruby changed the way I wrote Python. Learning Ruby even changed the way I wrote Java! While I code mostly in Python, C#, and a little Racket these days, I'll always remember Ruby fondly for changing the way I thought about coding.

As a side note, The other thing Ruby opened my eyes to was metaprogramming. Ruby's metaprogramming facilities are dead simple compared to Python's, which I feel changed practically every release from 2.2 onward. Of course the Lisps take the cake when it comes to code generation, but Ruby's ability to easily manipulate symbol tables is a nice easy way to start wrapping your head around the idea of code that generates code if your brain has already gotten used to C-style syntax and finds homoiconic s-expression-based languages a little strange.

> Ruby's metaprogramming facilities are dead simple compared to Python's

I actually have the opposite experience, Ruby's eigenclasses and the self way to handle them to create class methods feels convoluted and shoehorning whereas __metaclass__ and the way you inherit of Class feels straightforward to me. The same goes for modules extending/including behaviors versus sane multiple inheritance combined with metaclasses and the way you manipulate methods and functions just assigning them as attributes, without any need for three handfuls of helper methods. Ruby's approach of development is so pervasive that I (and not only me) always have to check if I won't be tripping on someone else's wires. When I tell that, the Ruby crowd shouts at me that Ruby monkey-patching is safe! So let's make it safer[1]! It honestly feels like needless complexity, over-engineering, or jumping through more hoops.

I know both approaches quite well but I can't help but think that the Python approach just fits in, like a self-solving Tetris, whereas Ruby feels like I constantly need to solve puzzles. Granted it's fun when you learn the language, drawing a picture of where classes, instances and eigenclasses of each fit, but when you want to be productive you just want it to flow, not solve another damn puzzle of how I can do this smartly so that things don't end up making galaxies collide.

PS: don't get me wrong, I actually love both languages, but while it's love-love with Python, it's actually love-hate with Ruby.

[1] http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-pra...

The follow up http://wit.io/posts/the-ugliness-of-python is in my opinion, more interesting. I always find it funny how different people think different languages are ugly.

Yeah, I have the opposite reaction. I think python is very elegant, and I really appreciate it's "one and only one way" philosophy, as opposed to ruby's "you are a special snowflake" approach.

It really can be just a matter of preference, though. Python and Ruby are so, so, so similar, that ultimately I find flamewars between them to be tiring at best.

Characterizing the Ruby philosophy as "you are a special snowflake" is, well, starting a flamewar

Honest question, how would you characterize it?


Ruby, for all the problems it can cause, gives you. More than one way to solve a problem. Yes, it sometimes makes it harder to dive into other's code but I happen to enjoy the expressiveness.

Mind you I love some of the things about python too. Namespacing being one of the primary ones. Another is that, short of advances pythonfu (like django does), I can usually pick up someone else's code and dive right in.

Python has amazing access to mathematical and scientific libraries as mentioned. However with ruby, I would punt to the Java ecosystem via JRuby if I needed that.

It's a lot like design patterns. Some patterns don't fit in all languagea but that's usually a case of the language itself giving you another way. Mixins in ruby are a good example.

With Ruby, the flexibility of being able to do things in more than one way makes it necessary to learn conventions rather than just the language spec. Sometimes breaking those conventions can have a tremendous upside. Some people find that upside worthwhile and others don't.

My general feeling coincides with yours, I can't see how someone can look at Ruby and say it's consistent, although it's not the up to the insanity of C++ or Perl (people only make it that way with a combination of poor judgement and dynamic metaprogramming). It does have some quirks that are at times convenient, but this whole notion of "consistency" in Ruby makes me suspect whether I can really understand where the author is coming from.

I think if you read the followup article, you'll see it's not flame bait. I'm legitimately trying to foster a discussion here.

Oh yeah, that was more of a general comment on python vs. ruby discussions, not a specific reference to your article.

Although the point stands that I don't see the purpose in passionately arguing one or the other, since they are so similar.

In Ruby, everything is an object and responds to messages. And it turns out that we can ask a number if it’s even or odd. In other words, numbers have our criterion function built in, and we don’t have to define it at all.

I absolutely hate this. In fact, I'm not a huge believer in object-oriented programming in general.


Is not an operation that integers perform. Integers do not contain methods -- they are data. even? is function that operates on integers. Integer is a type. Objects are object types. An object which contains an integer is an object-integer type. An object-integer type is not the same as the integer type. Why do we constantly feel the need to wedge objects into everything in existence when often what we really need are algebraic data types, functions, and namespacing/modules?


As you can tell, I like the ML family.

Your rant isn't an argument, it's an opinion. I can just as well say integers are objects like any other and even? makes perfect sense as a method on them because that's the entire point of objects in the first place, binding state and behavior together into a single smarter package because it's a convent method of organizing code.

I agree 100% that it is my opinion. I would wager that most rants are opinions.

As far as this being the point of objects -- I see no state. I see no behavior. All I see is a function which maps the set of integers to booleans. That's it. It's just a function. The only reason we need packaging or modules at all is to prevent name collisions and importing the world.

The integer is state, deciding if it's odd or even is behavior. Yes, it's a query method, but it's a good one. The only reason we need objects is to make programming convenient. I don't want my namespace polluted by a free floating function named even?/odd? when it can be restricted to the only type it cares about by being bound to it.

In some strictly ease of use sense, object.function() is better than function(object) because it better helps me organize and scope my code; I don't have to worry about function name clashes because every instance is essentially a module for those functions.

My tools also work better when they can see I'm asking what methods are on integer rather than just show me all functions visible to me right now. It's easier to say hey Integer, what can you do rather than hey world, what works with integers.

If you can only see functions, integers, and booleans and you can't realize those are all themselves perfectly good objects, then that's a failure of your imagination. Me, I like my functions, methods, booleans, integers, and all other types being objects because it's damn useful and damn convenient in making my day to day life easier.

I completely agree. I like how most responses to your rant hone in on the fact that it's a simple syntactic change, but utterly fail to get the point that composition of stateless functions a la Joy is totally magical, and opens up a whole world of possibilities that mutating, unchainable, uncomposable methods cannot.

For starters, and given that this is a thread about scientific computing, having stateless functions that mirror mathematical ones gives you robust, efficient approaches for parallelism and optimization that are completely lost (or horribly intractable) once you start boxing numeric types just so some OOPhead can put a dot after them.

>Why do we constantly feel the need to wedge objects into everything in existence

Because... it's convenient?

Do we need a reason?

I fail to see how

is any more convenient than

    even? i
except that even? has now somehow entered into the set of functions worthy to be part of the integer-fake-object while others have not.

It's more consistent (no wondering what's a method and what's not for most common situations) and it stops the global namespace getting littered up with functions that are only relevant to certain types.

To a Rubyist, knowing that Ruby is an object oriented language, it is clear one is sending a message to i. With the latter example, it is not clear what even? belongs to and what it expects to receive.

Then namespace it. As I said, there's nothing stopping you from having namespaces and modules.

    import Arithmetic (even)

    even :: Integer -> Bool
    even i
Also, you can call function calls messages or object operations or dictionary lookups, but I don't see the benefit in 99% of cases. I guess the dynamism may be useful in GUI code where it's not that hard to see if you're wrong and if you are wrong, nobody's world really ends. In most other cases functions are best described as having a formal mathematical definition so you can reason about them with some accuracy.

Because the former reads more like english.

I would ask "is 2 even?" but I would never ask "does the quality of evenness apply to 2?"

One of the things I dislike about python is the word order you end up with. My eyes have to jump about to work out whats going on. Its like german ;)

Your order is like English, but your semantics are the exact opposite. My code asks "is 2 even?" -- it calls the even? function to check to see if it's a boolean. If you notice, the even? object function is referentially transparant and implicitly contains its own argument. It's not really a function. It's a field. What Ruby has done is define a field of every Integer instance which returns True or False based on a separate function call that determines whether or not the object is even. It's irrelevant how the function is implemented because those are the semantics -- you have defined a method that answers if the quality of evenness applies to 2. Your own example is exactly why I dislike the semantics of this object method.

Yes, but I like it like that you see.

I don't get your argument. What's the difference between

    module Numeric
      def even?
        # ...

    even? :: (Numeric t) -> a
Both declare functions that consume something implementing the Numeric type/protocol, and return something else. I don't see the practical difference between them, other than the calling syntax of the result.

First, the even function is only defined for integers, not general numeric types. Second, type classes are not objects. Ad hoc polymorphism is used to denote different actions for different types but it doesn't break typing. The type integer is not the type object-integer:

    even? :: Integer -> Bool
I am actually thoroughly confused where you got your type specification. Were you trying to say:

    class Integral a where
      even? :: a -> Bool

    even? :: (Integral a) => a -> Bool
The reason why this disturbs me is because I find it difficult to draw the line at why even? should be even? :: (Integral a) => a -> Bool instead of even? :: Integer -> Bool. This doesn't make sense -- it's not a good use for typeclasses. There aren't many different categories of types which have a semantic notion of being even but a different implementation or type restriction. Even is just... even. It's just an operation on the integers. There's no need to bring ad hoc polymorphism in here.

I'm increasingly not a fan of OOP. If I wrote this article again, one of the things that would change is this sentence.

I expected a nice article going back and forth debating pros and cons. Really you argued here that Ruby is better than Java, and then at the end say -- oh and Python has more Science packages so I'm switching.

You let me down buddy. I was expecting more thought, less fluff.

This is an older post, not sure the OP is the author. I agree the title is a big overstatement. Basically boils down to "I'm going to learn a new tool that I think does X better".

I did like the post though, the follow is good too.

TL;DR: Ruby has no equivalent to SciPy, hence the need to switch. Probably a fair point :-(

You are right, Python package management is terrible. Even using an OS package manager (on Mac) like Ports or Brew it's still a nightmare.

The other problem is fragmentation. This package requires python 2.5, that one wants python 2.6, and that one wants python 3.1 but might me ok for python 3.2.

It's just a mess. And confusing.

Not to mention, even installing python on Mac can be a nightmare. One piece of advice, if you are going to use python on a mac get py-virtualenv (http://pypi.python.org/pypi/virtualenv). It's as good as rvm (in ruby) and will save your life.

I miss GEM terribly.

But despite the shortcomings (maddness) I still LOVE python. :)

Previous discussion: http://news.ycombinator.com/item?id=1947723

OP appears to have changed domains.

I did, sorry that messed up the HN dupe filter. I git three-letter domains much more than ones inspired by sentences :)


Who is the article (at least the first half of it) aimed at?

Are there any Java developers who still haven't dabbled with dynamic languages but could still be convinced to?

I imagine that those who will already have done, and the rest will never touch any language not in the "enterprise" class (Java, C#, C++, COBOL etc.)

I don't see anything suddenly more compelling about Python (which I've always liked, at least among imperative languages) but I for one was pretty startled to learn that V8 was already within 2-3x the cost of JVM bytecode. That can make server-side Javascript feasible for work where Python or Ruby would need an order of magnitude more rack units today.

Congratulations! The most silly article a read today. Comparing languages by the length of code is something an amateur would do, but not a professional.

Want to filter list with an "ad-hoc" function in Java? Use

Collections2.filter(list, new Predicate<Integer>() { public boolean apply(Integer i) { return i % 2 == 0; } })

from the Guava library. To read a file I use


from my library.

You would say, that the Java verbosity is outsourced to external libraries — but so it is in Ruby as well. The only difference is that Ruby contains more libraries than Java. But does it count in a development of a huge professional project? NO. (You write the libraries once and use the package everywhere.) Does it count in script writing? Yes. But Java wasn't designed for script writing, so please please don't compare a fork and a spoon.

Seems like it would be a huge opportunity for people to start creating these science Ruby gems.

Not my field, personally...

It's been tried before. mum, Numerical Ruby and SciRuby were all attempts.

The fundamental issue I believe they all had is lack of community. There is a quite large community of folks using Python for scientific computing. Many are not professional developers but rather scientists / engineers who aren't as open to jumping around to different languages as a developer would be.

These issues combined with the fact that Ruby is mostly pigeon-holed as a web only language would make replicating the community that the NumPy/SciPy/matplotlib stack enjoys almost impossible.

It also doesn't help that such capability have to be implemented as C extensions due to performance requirements. This greatly limits the number of developers that would/could work on such a project.

SciRuby "were?" We rebooted the project a few months ago. Making some progress. sciruby-dev at googlegroups dot com, and #sciruby on IRC.

These kinds of projects can take years to take hold; you can't expect people to just all switch right away. Blog posts like this just need to be commented on with a link to those libraries. Eventually some big lecture, class or project will use one of those libraries and a whole new group of people will supplement the community. This doesn't just go for Ruby, it applies to any language

Ruby performance in general is getting much better and when C extensions are necessary (as they often are in any high level language) libraries like ruby-ffi have taken a lot of the pain out of that process.

There's more inertia here than you may be thinking. See this recent HN headliner about the difficulty of getting the NumPy/SciPy community to merely move from CPython to PyPy: http://technicaldiscovery.blogspot.com/2011/10/thoughts-on-p...

If that's a challenge, good luck getting a lot of NotProgrammers to move to a completely different language.

Besides, if I may be blunt, who in Rubyland cares if these guys are on Python? By and large, these people are on an island. They are optimizing for things you pretty much don't care about, for programming styles you're not using, for libraries you've barely heard of. Trying to entice them off of Python onto Ruby is a waste of time for everybody. The Ruby community would at best get nothing, at worst net pain of supporting a lot of newbies, and the scientists would incur the horrifying overhead of a language shift for the closest thing to a sidegrade available in the set of the top 20-ish language. If they were going to do that they probably shouldn't be going for Ruby, they should probably be going for Haskell or OCaml, both languages for which I could outline actual advantages to the scientists for the pain of the switch (though probably not enough to justify the switch).

You make good points, they're not blunt. I've just read the same basic blog post many times complaining that there's no SciPy in Ruby. Again, I'm not in the sciences so I'm out of my element talking about it. I'm just trying to make the simple point that there does seem to be people out there wanting science libraries for Ruby

>It also doesn't help that such capability have to be implemented as C extensions due to performance requirements.

If you think the NumPy and SciPy stacks are pure python, you'll probably be surprised to find a lot of C and fortran sitting under the hood.

I know they are not written in Python, that comment wasn't meant to be a knock on Ruby's performance in any way. Its simply the case that writing a highly performant vectorized computation library in a language that doesn't allow direct memory manipulation is a non-starter.

In my experience, Ruby and number crunching just don't match. Python's not especially fast to begin with, but I've definitely found it to be faster than Ruby. Though I probably wouldn't choose Python for number crunching either. If I were extracting some time-sensitive algorithm, I'd most likely go straight to something like Clojure.

And I must stress how much I love Ruby. It's my go-to language for the web/small scripts.

sciruby is once again in active development


If interested, you can check out BioRuby - bioinformatics package for ruby @ BioRuby.com

can't you just use jruby? i would think java libraries are at least as good as the python ones.

http://sciruby.com :D

I don't know whether that qualifies as number crunching, but I am using Ruby for computer vision.


tldr: He wants a couple science python library and 'doesn't feel like porting them in ruby' (to take his wording).

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