6 ms·
I'm not sure I uderstand the point you are trying to make here: > To reuse addOne means to recreate the entire context of X. I want a banana but in order to ge
by tcgv 6y ago
I'm not sure I uderstand the point you are trying to make here:
> To reuse addOne means to recreate the entire context of X. I want a banana but in order to get the banana I must recreate the gorilla holding the banana and the entire jungle the banana is sitting in.
If 'banana' is dependent upon 'gorilla' then you're doing OOP wrong, or maybe you didn't need to reuse 'banana' in the first place and took some shortcuts while coding and now that you need you will have to refactor the code and extract that functionality into a new class.
Even in the case of inaccessible logic hidden into classes it's entirely possible to extract that code into, say, an utility class that can be reused across several classes. In this case the resulting code may resemble a combination of higher level OOP classes wich take advantage of lower level functional modules for implementing their behavior.
- dnautics 6y agoYes, that's all true, but after even two stages of this you're in the kingdom of the nouns. Note the argument is not structural, but philosophical. Yes, the two constructs are logically isomorphic, but to get composability with objects you must start twisting your brain in uncomfortable ways. I would concede there might be a minority of folks whose brain truly works like this. For the rest, it must be stockholm syndrome.
- Geminidog 6y agoIt's structural. class X: constructor(y=3,z=2) y; z; b = [......] F(x) = y + x F cannot be reused outside of the context of X and z y and b. This is not a philosophical issue but concrete. G(x, y) = y + x Here G has the same exact logic as F but can be reused and is more modular. No philosophy of fuzzy stuff here I am talking about a concrete problem. Philosophical arguments lead to unresolved controversies. I am not going in that direction. I am talking about a concrete issue that can be resolved.
- dnautics 6y agoI think parents posters idea about reuse is that if you need to reuse it, you make it into an abstraction and hoist (copy/paste) to a superclass and make where you took it from a child class. On the one hand, it does make the reuse explicit ("explicit is better than implicit"). Or you broaden the member elements to be able to take a broader interface. On the other hand, this is how you wind up with enterprise java.
- Geminidog 6y agoThe analogy I'm using is too big. It's actually a famous quotation but it kind of blinds you to the fundamental issue. Let me put it with a very primitive example. class Jungle: int bananas; int gorrilas; removeBananaFromJungle(): banana -= 1; Literally the example above is the most fundamental example of a class you can write. A class with a method that operates on a member variable. You can't get any simpler than this. There's no alterative pattern here; this isn't some overly complex example you can fix with a pattern. This is objects 101, one of the simplest entities in OOP you can ever define and the problem remains: I want a banana but I must initialize the jungle and the gorilla in order to remove a banana. It seems like a good organization scheme because the banana and gorilla live in the jungle. But this is the issue with OOP. We can't predict the future and we can't predict how requirements will change or the perfect design. So really the best way to program is to assume nothing. Don't assume either the gorilla or the banana are in the jungle: int gorrila = ... int banana = ... map<string, int&> jungleStuff = ... haveTheGorillaThrowABananaOutOfTheJungle(gorilla, banana, jungleStuff) What if one day I'm called as a programmer to write a program about Gorillas on the Space station? With the OOP version I have to create the jungle and the banana just to get the gorilla onto the space station. With the regular procedural version I do not. Basically 99% of accidental technical debt is the result of unintended groupings of logic and data promoted by the OOP pattern because people assume gorillas live in the jungle and they can never account for the fact that one day they will be on the space station. I'm sure you can come up with some crazy OOP pattern that can account for both the regular Jungle case and the SpaceStation... but what if I start throwing all kinds of crazy requirements at you? The spacestation now has to account for Ostritches, Gorillas can now live with ostriches in a house.... anything you can think of I will try to break your design with a new requirement (within reason) until you come up with a set of entities that can anticipate anything... You'll find more and more that your classes will become smaller and smaller until basically you have an OOP pattern that can anticipate any requirement I throw at you: class Gorrilla int gorrilas class Banana int Bananas class Jungle map<string, int> stuffInTheJungle class SpaceStation map<string, int> stuffInTheSpaceStation class House map<string, int> stuffInTheHouse class Ostrich: int ostriches Which is basically equivalent to this: int gorrilas int Bananas map<string, int> stuffInTheJungle map<string, int> stuffInTheSpaceStation map<string, int> stuffInTheHouse int ostriches In short, any grouping of logic and variables through the use of free variables or classes reduces the modularity and flexibility of your program pointlessly. There is no reason why you should group logic together and you can never anticipate the future where your grouping will be found to be incorrect. To counter this problem you need to make your groupings smaller and smaller until each class holds one thing. A class that holds one thing is pointless, it's the same as just that thing itself without a class wrapped around it.
- Orochikaku 6y agoIsn’t this just lazy evaluation? What prevents an OOL from also lazily evaluating?