3 ms·
16 years ago, but just 6 years after the language was released, and 4 years before Rails came on the scene. In retrospect, I'm not sure how successful Matz has
by norswap 9y ago
16 years ago, but just 6 years after the language was released, and 4 years before Rails came on the scene.
In retrospect, I'm not sure how successful Matz has been in upholding the principle of least surprise. In many ways, Ruby is one of the worst offenders.
- flavio81 9y ago>In many ways, Ruby is one of the worst offenders. Can you explain why? I'm curious.
- weaksauce 9y agoThe powerful metaprogramming features get used to make dsls and also make it harder to know what methods are available or built in or what gem added them in. I love the language and it's a joy to program in but it's not without fault. Also, there are many ways to do something so you need to know multiple ways. I don't find it particularly hard to program in once you get used to a few paradigms though.
- norswap 9y agoI actually have a whole series of posts up: http://norswap.com/ruby-dark-corners/ http://norswap.com/ruby-dark-corners/ The three topics (module linearization, scope lookups and method parameters) are constant source of wtfs as soon as you go beyond something basic.
- jhbadger 9y agoCompared to what, though? I really like how everything is a method in Ruby as compared to, say, Python where it seems completely random if something is or isn't -- for example, I have to constantly remember that to get a length of an array in Python I have to do len(x) rather than x.len(). Although I like what Rust and Nim are doing with making the method/function distinction irrelevant -- there, x.f() is just syntactic sugar for f(x) -- so you can use whichever you prefer.
- flavio81 9y ago>I have to constantly remember that to get a length of an array in Python I have to do len(x) rather than x.len() On the other hand, in Python lists, tuples and arrays are fundamental data types and thus len() is defined as a fundamental built-in function. I think it makes sense. What i didn't like was when map() and reduce() were moved away from the basic functions.
- bhaak 9y ago> On the other hand, in Python lists, tuples and arrays are fundamental data types and thus len() is defined as a fundamental built-in function. I think it makes sense. But len() is only a fundamental built-in function for fundamental data types and you can implement it on any class by implementing the method __len__(self). For those it doesn't make sense any longer to be able to do len(x).
- flavio81 9y agoI'm afraid you're right...
- steveklabnik 9y agoSmall note about Rust; you're not 100% right. For example, method syntax will do auto ref/deref on the reciever, for most methods, it'd be f(&x), not f(x), though if f took self by value, it would be! It is true that you can invoke it either way if it's a method, but you cannot if it's a function, as well.
- norswap 9y agoCompared to most everything (PHP is probably worse, and there might some that I don't know). I'm not saying it's surprising because it's different, rather it's surprising because it doesn't seem to be very internally consistent. Lots of complicated rules instead of a few simple ones. As I pointed out in another comment, the way lookup is handled for instance is really a clusterfuck (http://norswap.com/ruby-lookups-scopes/ http://norswap.com/ruby-lookups-scopes/) Other OO languages like Java or Smalltalk (the more direct Ruby inspiration) do much better in this regard of having simple rules for lookup (and other things).
- steveklabnik 9y agoMatz has also maintained that it's the principle of his least surprise. You can't be not-surprising to every single possible person.
- ksec 9y agoMatz also mentioned Ruby is no longer his project.
- griffinmb 9y agoIn general, I think Ruby does a good job of being unsurprising. I like that most things work as I'd expect, with the syntax I'd expect. But then you've got weird things like `File.read("|ls")` that are entirely surprising.
- goatlover 9y agoI don't see why it's one of the worst offenders. I always found that it made more sense that PHP and Javascript, and was a bit more consistent than Python and Java. What is your standard for non-offender? Certainly not C++ or Common Lisp. Scheme, Smalltalk, Go?
- norswap 9y agoPHP worse from what I've seen. JS I would say better. Most of what people complain about are wonky implicit conversions -- easily avoided. The retro-fitting of classes onto the prototype is not super elegant (the "Javascript: The Good Parts" approach is better), but can be readily understand with a good explanation and a schematic (1). C++ is probably an offender but for other reasons. My experience is limited, but from I've seen it's mostly vast But when you look at each feature they're not incredibly unintuitive. A huge problem in C++ is that there many ways to do everything (the old way and the new way and the new better way, all which have slightly different semantics). Common Lisp is also vast but seems really solid on its foundations. Scheme, Smalltalk and Go, definitely better. Lua. Java as well excepted maybe the really fine points of generics (captures) -- but in practice understanding that is almost never needed. C, unless you count undefined behavior as against least surprise, then it fails. Python I'm really not practiced enough to tell. All in all, we're probably not using the same criteria for least surprise. I'm not even considering libraries, just baked in language features, and being able to predict what they do. In that sense, Ruby is really much worse than Java. It's really bizarre (see my blog posts in the other comments). And the problem is made worse by the fact that all that weird behavior is not documented anywhere. (1) e.g. https://drive.google.com/file/d/0B0O9lcl5dMLQbDFkYk1kX28xM1U/view?usp=sharing https://drive.google.com/file/d/0B0O9lcl5dMLQbDFkYk1kX28xM1U...