4 ms·
I believe you’re confusing Ruby with Rails. While these can eventually come in handy sometimes, they are by and large seldom used, but Rails heavily leverages
by lloeki 6y ago
I believe you’re confusing Ruby with Rails.
While these can eventually come in handy sometimes, they are by and large seldom used, but Rails heavily leverages such patterns for flashy yet ultimately questionable magic.
As a long time Rubyist, I believe Rails, for all its innovation, has been warping the view of what Ruby is, and when and how to use its features responsibly.
- abernard1 6y agoI concur. The dynamic inheritance part of Ruby is still core even in a non-Rails ecosystem. That does make optimizing performance more difficult. But on a much simpler level, a lot of Pythonic data code is just functions + values, without them being complected in an object. That makes a lot of stuff like wrapping numerical libraries in C very easy in Python. I think you'd still have a bit of a culture shock writing procedural, return-by-value code in Ruby. That's pretty normal in Python and I think one of the (many) reasons it got picked up by STEM disciplines in academia. Looks over shoulder at awful code in Numerical Recipes in Fortran book. Different strokes for different folks and all that, I just think there are probably constraints (and cultural values) that Python has that make it more suited to data problems than Ruby.
- mumblemumble 6y agoI'm inclined to agree. One of Python's strengths in this space is that it's a procedural language with just enough in the way of object-oriented facilities. That makes it possible to write reasonably object-oriented libraries with easy-to-learn interfaces, while still sticking to procedural idioms for the actual data hacking. Which, in turn, means makes it a comfortable environment and interfacing mechanism for both engineers and analysts. That said, sometimes I look at tools like https://moosetechnology.org https://moosetechnology.org and desperately wish I could be using something like that at work.
- abernard1 6y agoTotally. Another thing is that outside of scientific data applications, ordinary data processing apps at scale have been map-reduce for a long time. That's an inherently functional paradigm that's closer to Python. Having parallelized heavily OO Ruby code across machines by unrolling it into functions that could be sent data payloads... that's not a fun thing to sell in an OO culture. In Python you're kind of already writing code that way, so increasing performance by splitting the data onto different machines is simple.
- mumblemumble 6y agoI don't think that would really be too bad, TBH. Don't forget that the first project to popularize distributed map-reduce, Hadoop, was a Java project. All you really have to do to translate map and reduce into an OO paradigm is have the map and reduce operations take objects that implement specific interfaces instead of functions that have a certain signature.
- abernard1 6y ago> Don't forget that the first project to popularize distributed map-reduce, Hadoop, was a Java project. Yeah, but that required everybody learning a different style of programming that wasn't OO ;-). The problem is for "map", you have to get rid of shared state and the interleaving of state and time. Interleaving state and time is basically the only thing objects do beyond providing a namespace and polymorphism. There's also an inherent 1-ary behavior in most OO code. If you've got a complicated object graph, making something a bulk N-ary operation is non-trivial. A lot of ORMs have this problem when trying to optimize queries. When you're passing a vector of "state" to a function, it's much easier to make things bulk. (Anyone who's had to make legacy code provide a bulk API with an efficient DB insert operation knows what I'm talking about). What you usually get in Ruby is a bunch of code that's like Duck.quack() and a complex set of things below that interface. What you need for data processing is something like quack(ducks[]). The way of parallelizing real-deal objects keeping them objects is with actors, and then you need to worry about distributed state a lot more. Anyhoo, that's a long way of saying that the much-derided procedural or functional style of Python avoids this problem from the get-go. You can just slap the "map" step onto a stream processing system without cutting your graph into pieces that don't share state.
- pjmlp 6y agoJust enough? Python has the full program with multiple inheritance, metaclasses, abstract classes, slots, attributes, properties and decorators. One can go wizard level with Python's OOP facilities.
- cutler 6y agoI don't think that's been true for quite a while. Even a function like len('abc') is implemented as 'abc'.__len()__ under the hood so no different from Ruby really.
- lukeschlather 6y agoWell, the problem is that Rails (and ActiveSupport) is borderline idiomatic Ruby. I imagine the vast majority of Ruby codebases use them. And honestly I don't even know how vanilla Ruby stacks up to Python, it's almost an inconceivable idea (though I left Ruby behind some years ago.)
- vinceguidry 6y agoRails is dominating Ruby less and less every year. There are plenty of alternative web frameworks to use, and Rails is a really heavy-weight thing to include if you're not building a website. I'll pull in an ActiveSupport module every once in awhile but so few of the things I write are websites that need Rails.
- cutler 6y agoThere's no evidence for this in the job market. Most Ruby jobs are Rails jobs.
- chrisseaton 6y ago> While these can eventually come in handy sometimes, they are by and large seldom used I don't think they are seldom used in practice - I think large parts of the Ruby ecosystem use them pervasively, even if you disregard Rails. But even if we don't agree on that - it's missing the point. The point is you pay for much of Ruby's metaprogramming, even if you aren't using it. So not using it doesn't help you. A concrete example is that you pay for `Kernel#binding` every single time you finish using a local variable but Ruby retains it for the binding, even if you never ever call `Kernel#binding`. Even JITs cannot remove this cost.
- pizza234 6y ago> The point is you pay for much of Ruby's metaprogramming, even if you aren't using it. I don't think there has been any meaningful attempt at assessing the performance of Python vs Ruby. If we consider the benchmarks game, their performance is comparable. I assume that PyPy is faster, but whether to consider it representative of Python's general performance is arguable.
- jashmatthews 6y agoWhich cost do you mean? Needing to keep the value alive for deoptimization if Kernel#binding is actually called or?