5 ms·
I think Java-style OO was successful because it made code organization obvious, more so than any other programming language I've seen. The key insight is that s
by cousin_it 12y ago
I think Java-style OO was successful because it made code organization obvious, more so than any other programming language I've seen. The key insight is that source files are the natural unit of writing code. Each source file has an explicit public API and private internal state, and a dedicated namespace that always reflects the file's name and location in the source tree. That makes it easy to see the big picture by just looking at the directory structure and the imports.
- AlexanderDhoore 12y agoBut what you describe are basically namespaces. All the rest of OO is overkill. Recipe for success: take a simple language with only functions (like Lisp or C) and add namespaces. Result: this language can do 90 % of what OO languages are useful for, with only 10 % of the features.
- hrjet 12y agoIMO apart from namespaces, the other biggest convenience provided by OO is inheritance. In some problem domains, there are naturally emerging inheritance hierarchies. And when you need it, manually coding virtual dispatch in non-OO languages is going to be hairy.
- andrewstuart2 12y agoOO is simply a layer of human-readability on top of functions and data. As far as the CPU is concerned, both object and method arguments are just data to operate on. So `steve.drink(water)` in another context is just `drink(steve, water)`, which is a little more difficult (at least in English) to reason about. OO principles are for the limitations of people, not computers.
- chongli 12y agoI should hope it'd be obvious to most people that you don't actually need all of OO just to get that little bit of syntactic sugar. I'd also like to point out another obvious fact: this idiom completely breaks down when the subject happens to be more than one person, i.e: steve_and_irene.drink(water) whereas it works fine in the procedural case (thanks to varargs): drink(water,steve,irene,...).
- seanmcdirmid 12y agoAnd you don't need syntactic sugar to do OOP, as you have just demonstrated with your examples. And also, multi methods exist, but you probably want one subject/dispatch variation per sentence anyways for complexity reasons.
- deleted 12y ago[deleted]
- deleted 12y ago[deleted]
- PJDK 12y agoOnly if your model is terrible. It's perfectly possible to have thirsty_people.drink(water).
- snlacks 12y agoI think the more realistic code would be. people.find('thirsty').drink('water') Not about plain language reading, but instead writing code the way people think about actions and things. Procedural is just as valid, but you use the right tool for the right job.
- deleted 12y ago[deleted]
- adunn 12y agoThis is correct. OO codifies the pattern of having a struct and a set of functions that operate on it. The syntax does help humans reason about that pattern. But my understanding is that the goal is more about the human limitations of managing large code bases than the human limitations of language. OO is all about encapsulation. We tend to decompose a program into chunks for different teams and individuals to work on. Software development is a distributed task. Encapsulation means when you code against components written by other people, you only have to understand the public API that they provided. You are supposed to be guaranteed that that API will continue to work even as the code behind it is updated. As component users we can focus on our own task and not worry so much about the details of the component. As the author of a component, we can hide state from the users. That can't be done with structs. we can make updates and switch out implementations without (as much) fear of breaking the code that depends on it. It's really all about being able to modify code more safely on bigger teams. In my mind the issues that OO introduces are: * Encapsulation results in more verbosity for the same functionality. * Inheritance takes more thought. * OO as a whole is more complicated and has a bigger learning curve. * OO used incorrectly will magnify the first two points greatly. Given the learning curve I imagine a lot of people don't use it fully correctly.
- colanderman 12y agoWhich is great until you have to OO-ify `playWith(steve, bob, ball)`. OO dictates that one of steve, bob, or the ball, knows how these three interact, and that it not vary with respect to the other two. Or `steve' is given to you from a 3rd-party library, and you want to imbue him with the ability also to eat. Well, you can't define `steve.eat(salad)', unless you subclass his class and make a proxy of the object from the library. To properly solve either of these, you are forced to resort to the second-class citizen of a static class, which is exactly just functions in a namespace. The one actual "benefit" OO gives you is run-time dispatch; the ability for the program to defer until run-time the decision which implementation of `steve' actually handles `.drink()'. Outside of OO's poster child of GUIs, I have rarely seen a need for this capability in 20+ years of programming. (Mere compile-time dispatch, as captured precisely by OCaml's module functors, is much more common.) Centering a paradigm around this rarity is quite bizarre.
- oblio 12y agoIsn't also limiting the potentially boundless array of (mostly irrelevant) functions to relevant data types also relevant? I'd venture to say it is. Ooooh... that's a Point object - no way the AddAccount function does anything relevant with it! In OO you don't even actually need to think that since Point has a limited set of methods.
- deleted 12y ago[deleted]
- sbov 12y agoI'd be willing to bet that the Point object in any given language is going to have more methods that take it as an argument than methods the class itself has.
- oblio 12y agoTrue. But I still go looking for the "Point" class first. Then I start looking for things which accept "Point" parameters. Big difference from procedural programming languages.
- colanderman 12y agoIn C, I look in "point.h" first, then start looking for other things. Not really different.
- hrjet 12y agoA natural way to separate those two types of methods is: * methods that do something *to* a Point object * methods that do something *with* a Point object The former are better to be declared inside the Point object so that they have access to internal state. The latter shouldn't typically access internal state of the Point object. This separation can help immensely while analyzing a code base.
- colanderman 12y agoThis applies to any language with static types. Or that allows code to be separated in multiple files, for that matter. In Haskell, I can literally ask the editor to list me all functions that operate on type X. Even in C written with a modicum of coding discipline, 90% of the functions relevant to type X will be defined in X.h, wherein 100% of the functions in X.h are relevant to type X. (And the 10% of functions relevant to type X that aren't in X.h? Well, in Java, they also wouldn't be part of class X anyway.)
- exDM69 12y ago> I think Java-style OO was successful because it made code organization obvious I can't agree with this opinion. I often find it an annoying restriction that I must put all my functions in a class. Let's look at a trivial example of multiplying a matrix by a vector. You can write matrix.multiplyBy(vector); // OR vector.multiplyBy(matrix); It is possible to multiply from the left or from the right (as long as the matrix and vector dimensions match). This makes it even more annoying. What I'd really like to do is: multiply(matrix, vector); // vector is a column // OR multiply(vector, matrix); // vector is a row Perhaps it's the kind of problems I work with (and the non-OO languages I am used to), but I am regularly faced with this problem if I have to use a language like Java where you have to put all your functions inside classes. To further elaborate why I don't really like OOP (except in a minority of cases where inheritance, etc makes intuitive sense), I think the biggest issue is that classes/objects are the method to do almost everything. Namespaces, visibility, inheritance, dynamic dispatch, etc are all somewhat orthogonal features. Having a "class" to be the unit that uses all of these features is, in my opinion, a restriction. Lists (or arrays), tuples (or structs) and Maps (or dicts) are what I want 99% of the time. When programming with Java or similar languages, I feel like the primary means of abstraction and composition in the language is catering to a 1% problem. I learned programming in the late 90s, early 2000s, during the height of the craziest OOP craze (when "object oriented" was synonymous with "good"), so it took me a while to un-learn all of the OOP methods but I feel like I did turn into a better programmer when I stopped thinking in terms of objects. OOP is a neat paradigm for some cases, but I find those cases very rare.
- adunn 12y agoGood points, I think it's not really the right tool for what you are doing. It's more for large teams and big code bases.
- wtetzner 12y agoHonestly, I think something like Ocaml's module system would be better for large teams than objects, and I think it's also just a better way to organize code.
- 12y ago