From: Michael Neumann Date: 2007-09-25T16:44:29+09:00 Subject: Re: Question about 2005 Ruby critique... barcaroller schrieb: > I come from a C/C++/Perl background and I have been reading up on Ruby for a > while (no hands-on experience yet, except for a few tutorials). Most of the > stuff sounds/looks very positive but I recently found this critique of the > Ruby language on the web and I was wondering whether these statements have > any validity at all. Uh, who wrote that? Hopefully not Bruce himself ;) In short, they are not valid at all (they never were), except the one with threading (but Ruby is getting native threads soon). > ======================================== > Ruby: better than Perl - but what isn't? > ---------------------------------------- > > Ruby is the second-most vulgar programming language in wide usage. It > succeeds at its intended goal of being better than Perl, but its design > manifests a total ignorance of basic programming language theory. > > Updated 9 January, 2005: Bruce Eckel apparently isn't bowled over, either. > > Ruby's creator, Yukihiro "matz" Matsumoto, crossed the Perl language with > Smalltalk-inspired OO features including a fully-unified type system and > closures, then added exception handling and simulated multi-threading. The > result is certainly an improvement over Perl, but it is terribly > disappointing as a language. This explains the unqualified rest of the text :) > The main philosophy of Ruby seems to be, "Side-effects rock!" We can "Side-effects rock" => complete nonsense. A lot of String operations are side-effect free, and destructive versions are available, denoted with a "!" at the end! > probably blame the C language for blurring the distinction between > imperative and applicative code. Maybe that blurring makes some amount of > sense for C, which is essentially a high-level assembly language. However, > languages such as C++, Java, and Perl have carried that foul practice > forward. And now Ruby takes it to new heights: every statement is an > expression, and every expression is a statement. Uh, and statements can't have side-effects? A method/function call is an almost any language an expression, and has possible side-effects in almost any imperative language. I don't see any reason to have statements in a language, when everything can be an expression. That's a servere limitation of the language if not "everything is an expression". For example in C/C++/whatever, you have to write: i = 1 > 2 ? true : false; because "if" is a statement. In Ruby: i = i > 2 ? true : false or: i = if i > 2 then true else false end > Every method is a > procedure, and every method also is a function. Hum, a method is a method. It's not a procedure, and not a function. Point. Don't understand his reasoning here. > Functions and expressions > with side-effects abound in Ruby. > > Worse, Ruby exalts global side-effects. In a nominally multi-threaded > language, this is unseemly to say the least. As an everyday example, the > statement > > x = gets > > reads a line and sticks it into x just like you'd probably expect, but it > also has the side effect of sticking the line into the global variable $_. > WTF??? Is it really global? Or did he meant thread-local? :) The question is, how often do you see code accessing $_ in Ruby. How many global variable accesses can you find in Ruby's standard library. Not many. The good thing, they are quite easy to locate in Ruby, using grep. Not so in C, C++. > Ruby seems to love the magical global variables carried over from Perl. > There are dozens of them, all with nonintuitive names like $_, $!, $*, and > $~. Yuck. These things get set as side effects, and often are used > implicitly. Again, most of them are thread-local. > Ruby's exception mechanism combines the above failures into an astounding > disaster. When an exception occurs, an exception object is created and > stored into $! which is a global variable. Complete nonsense. It's thread-local. > Apparently you aren't supposed > to get exceptions in more than one thread at a time. Updated 9 January 2005: > It turns out that this isn't actually an issue; read the comments for > details. > > Ruby also blurs the line between names of variables and methods. The > Uniform Access Principle is an excellent idea. at least in a language where > both variables and methods have to be declared and cannot overlap. But Ruby > allows a symbol to identify both a variable and a method, and the > disambiguation process is best described as eccentric. Has he ever written C++ code? class Datastructure { private: int _size; public: int size() { return _size; } }; It's so annoying to rename the instance variable to "_size" if you add an accessor method of the same name to it. God thank, Ruby doesn't has this. > Ruby delights in the bizarre usage of operator overloading. "<<" normally > means "left shift", but it also means "here document follows," "append to > string," and "extend array." He chooses "extend array" instead of "append to array" by purpose, I guess :) > Other operators have similar illogical > overloadings; for example, the "<" operator not only means "less than" but > also "is a subclass of." > > Ruby throws a basic OO principle to the wind by allowing anyone to add > members and methods to an existing class, even outside of the original class > definition. The methods thus added have full access to all other members and > methods, including private ones. The usual term for this is "breaking > encapsulation," although I dislike that term because it misuses the word > encapsulation. A better term is "violation of the Open/Closed Principle," in > that the original class is not kept closed against modifications. class A def a end end A.freeze class A def b end end # => TypeError: can't modify frozen class Where's the problem? > Ruby's multi-threading seems to be a misfeature from tip to toe. Ruby's > multi-threading is simulated: it only runs on a single CPU and is > fundamentally incapable of taking advantage of multiple CPUs or multiple > cores within a CPU. Which is just as well, because Ruby doesn't define a > memory model for coordinating data between CPUs or cores. Then there is the > problem of global variables being changed as side effects and accessed > implicitly. Writing multi-threaded code in Ruby looks like a good way to > cause yourself immense non-deterministic grief. Seems like his favorite language is Java. Ruby is getting native-threads in 1.9. > Ruby code can be written to be very clean and readable-something that cannot > really be said about Perl-but Ruby can also be written just as poorly as > Perl is. Unfortunately, most of the Ruby code that I've seen, including > various introductory guides to the language, seems to prefer the slutty side > of Ruby: procedural code using global variables and magical side effects. > I'm > not sure that I see how Ruby is better than Perl in those cases. > > I've written some Perl over the years, and I probably will be transitioning > to Ruby for those tasks. Ruby certainly is better than Perl, especially if > you choose the high road and write clean code that eschews the side effects > and global variables. But I'm not at all happy with Ruby, because it easily > could have been so much better than it is. > > Friday, 7 January, 2005 He should have informed himself better before writing this. But I think this blog entry was never intended to appear on ruby-talk. :) Regards, Michael