The quoted text above is referring to objects, not OOP -- which encompasses a number of concepts. You can refer to the the "Features" section in your link above for the complete list (notice one is missing). For further information about the relationship between OOP and mutability just google it.
It's a waste of time to argue about a topic that is orthogonal to your original claim (before the goalposts moved): that the "problem" with OOP is how you invoke a function -- `noun.verb` as opposed to `verb(noun)`; As if those two systems are subject to different constraints. They are not. It is just semantics.
The above isn't to say there doesn't exist consequential differences between OOP and FP, but I absolutely did _not_ engage in this discussion to argue about OOP vs FP in general. I think we actually both agree FP is a superior paradigm.
>The quoted text above is referring to objects, not OOP -- which encompasses a number of concepts. You can refer to the the "Features" section in your link above for the complete list (notice one is missing). For further information about the relationship between OOP and mutability just google it.
Makes sense. Object oriented programming isn't programming revolving around objects. You totally invalidated all my claims with this genius argument here. You also invalidated the entire definition of OOP and wikipedia too.
>It's a waste of time to argue about a topic that is orthogonal to your original claim (before the goalposts moved)
At first I was going to say that the goal posts have not moved but your brain was the thing that moved. Then I realized nothing has moved. Your brain is still in the same place: A place of ignorance.
>that the "problem" with OOP is how you invoke a function -- `noun.verb` as opposed to `verb(noun)`; As if those two systems are subject to different constraints. They are not. It is just semantics.
Let me spell it out for you where the goal posts were when the conversation started. The goal posts were in a place where 99.999% of all programmers operate: In a universe of mute-able variables, mute-able objects and immutable functions. Typically "goal posts" start here because that's how 99.99999% of all programmers operate.
So within the bounds of these "goal posts" you made a claim that OOP and Functions only have a semantic difference. Which is CATEGORICALLY wrong. So then I decided to let you know that your CLAIM is only TRUE if VARIABLES are immutable you acted AS IF we were ONLY talking about immutable variables ALL ALONG as if that's the primary assumption all programmers make when talking about programming. The goal post wasn't moved... get it? I only changed the context a little to show you WHEN your arguments would be true, BUT nowhere did I "change the goal posts."
What happened after that is that YOU changed your argument. You imply that you've been ONLY talking about immutable variables all along and that I changed the goal posts to suit my needs. I can tell you 100% that you are either a liar or deeply delusional. You literally refuted a sourced definition of OOP in your attempt to stay relevant. Give it up dude.
>The above isn't to say there doesn't exist consequential differences between OOP and FP, but I absolutely did _not_ engage in this discussion to argue about OOP vs FP in general. I think we actually both agree FP is a superior paradigm.
I agree that we aren't talking about FP vs. OOP. What we are talking about is, and I quote:
"that the "problem" with OOP is how you invoke a function -- `noun.verb` as opposed to `verb(noun)`; As if those two systems are subject to different constraints. They are not. It is just semantics."
Which you are completely and utterly wrong about. You cannot make this statement without saying that all variables are immutable which is not a property that can be ASSUMED OUT OF THIN AIR.
OOP is not "programming revolving around objects". Simply using objects in your code-base does not mean you are practicing OOP anymore than using functions means you are practicing FP. But I digress. Again, the definition of OOP is unrelated to the claim which prompted this discussion.
>The function would not be tied to state and that function can be executed in the context of anything
This is the (your) line of text at the top this thread (go look), and the point to which I wanted to offer some clarification. It has nothing to do with the definition of OOP or mutability vs immutability.
The point I have been trying to make is that `noun.verb` and `verb(noun)` are both tied to the same state; That the _caller_ of either of these functions needs to have a reference to `noun`. In this way, the "context" is also the same (both functions can only be executed in a context that has `noun`). There are problems with OOP! The above just isn't one of them.
>You cannot make this statement without saying that all variables are immutable
How do you know `noub.verb` mutates `noun`? Similarly, how do you know `verb(noun)` doesn't mutate `noun`? There is no way to make an assessment of the mutability of `noun` given those snippets. Which is kind of the point: they are equivalent.
Making an assertion about the behavior of either function (when that behavior is _clearly_ not shown) is building an argument against something else entirely. This is called a straw-man. Similarly, shifting the argument to be about the definition of OOP and/or mutability instead of the relationship between how a function is written and its dependencies/modularity is to argue about something else entirely. This is called moving the goalposts.
>How do you know `noub.verb` mutates `noun`? Similarly, how do you know `verb(noun)` doesn't mutate `noun`? There is no way to make an assessment of the mutability of `noun` given those snippets. Which is kind of the point: they are equivalent.
This is why you have to make every possible assertion. Muteable and immuteable. And in the muteable case your statement is wrong. Since we are talking about OOP (see first sentence of my first post) by definition only the muteable case is considered. There was no movement of goal posts, you simply failed to see where the goal posts were originally.
>Making an assertion about the behavior of either function (when that behavior is _clearly_ not shown) is building an argument against something else entirely. This is called a straw-man. Similarly, shifting the argument to be about the definition of OOP and/or mutability instead of the relationship between how a function is written and its dependencies/modularity is to argue about something else entirely. This is called moving the goalposts.
The topic at hand is on OOP. That's because that's the topic in my first post. Thus since OOP is mentioned in my first post THE DEFINITION of OOP is what I'm talking about. And since mute-ability is part of the DEFINITION of OOP this is the topic. What happened is you entered this conversation with the idea that the goal posts were somewhere else. They were not.
We are talking about noun.verb and verb(noun) in the context of OOP. That is the topic. And the statement of verb(noun) is the same as noun.verb is categorically wrong. You are wrong. This is concrete.
The only assertion I need to make (and have made repeatedly), is that `noun.verb` and `verb(noun)` are subject to the same constraints. In terms of mutability, we can say that both functions could mutate `noun` or both functions could not mutate `noun`. It is a straw-man to build an argument against a premise which arbitrarily asserts that `noun.verb` _behaves_ differently than `verb(noun)`. The behavior of the function(s) is not relevant to point you were trying to make or my point of clarification (of course two functions that behave differently are different!). Again:
>The function would not be tied to state and that function can be executed in the context of anything
The above is the claim which prompted this lengthy discussion. It has nothing to do with the definition of OOP or mutability. To rephrase your argument in my own words:
Separating data and behavior (state and functions resp.), in the form of `verb(noun)`, is superior to combining data and behavior, in the form of `noun.verb`, because it means `verb` is subject to fewer constraints and, as a result, is more portable.
The above is not accurate. There _are_ problems introduced by encapsulation. But one of them is not that functions are tied to state. This remains true for any function no matter how it is written (the semantics).
I'm not sure why you continue to insist on moving the goalposts here, especially to an argument for which you are so obviously wrong. The definition of OOP makes no claims about mutability. Furthermore, many of the most popular OOP languages provide built-in support for defining objects as immutable (while at the same time implementing immutable objects in their own standard libraries. e.g. `string` in many languages). Even a cursory google search on the subject unambiguously yields this information. I'm not going to waste my time debating this when you are fully capable of researching and revising your position. Especially because this has nothing to do with the claims that provoked this discussion in the first place.
My original comment was rather innocuous. It was intended as a point of clarification towards a claim you made as part of your broader opinions on the deficits that OOP impose on a system as it relates to functions, state, and modularity. You essentially say the same thing later in your post in your comparison between the OOP model and microservices:
>The difference here is rather then unionizing action and state with Code it unionizes state and action with real cold hard metal. The actual machine that holds state and "does stuff" is the object. So all the problems of realizing how to divide or unionize services and state in microservices are exact same problems that existed when trying to figure out what methods belong with what object in OOP...
Just replace "microservices" with "FP" in that last sentence and you will have basically synthesized my argument:
"all the problems of realizing how to divide or unionize services and state in FP are exact same problems that existed when trying to figure out what methods belong with what object in OOP"
For what it's worth, I agree with your ultimate conclusions.
>>The function would not be tied to state and that function can be executed in the context of anything
>The above is the claim which prompted this lengthy discussion. It has nothing to do with the definition of OOP or mutability. To rephrase your argument in my own words:
>Separating data and behavior (state and functions resp.), in the form of `verb(noun)`, is superior to combining data and behavior, in the form of `noun.verb`, because it means `verb` is subject to fewer constraints and, as a result, is more portable.
>The above is not accurate. There _are_ problems introduced by encapsulation. But one of them is not that functions are tied to state. This remains true for any function no matter how it is written (the semantics).
Have you ever thought about the difference between a list of "noun.methods" that encapsulate a "noun" vs. a list of "verb(noun)" that also encapsulate a noun? Under your semantic equivalence principle it's the same thing. IN your universe one can encapsulate a noun with procedural functions through type signatures AND it can be done with OOP as well. We are of course negating the usage of a noun as a global variable.
Also what is the "noun" in "noun.verb"? Can it be a namespace? Is "noun.verb" the same as "namespace.verb"? Namespaces hold variables and functions and so do Objects... Are these two concepts isomorphic? If regular programming already has namespaces what's so special about Object Oriented programming? What's the point of calling a namespace an object?
Well then you could say that OOP allows the user to "generate" or "instantiate" namespaces at runtime. That's neat except what is the point of generating a new namespace for what is essentially the same thing? Why do I need namespace1.verb and namespace2.verb when I can just have verb(namespace) or just get rid of OOP and have a single namespace.verb?
Well you could argue that namespace1 and namespace2 have different states. That's why you need the ability to instantiate them. But then what's the point of instantiating different namespaces at runtime when you can just have verb(namespace1) or verb(namespace2)? What's the point of OOP if it's the same thing as everything else in existence? Was OOP invented for semantic confusion only?
Well no, in OOP the namespace.verb() verb modifies the instantiated namespace. namespace1.verb is DIFFERENT from namespace2.verb because they are modifying different states. This is OOP. If VERB was stateless and did not touch the state of namespace2 or namespace1 then there would be no difference and you wouldn't be doing OOP.
It is mutation that ties a method to state. The goal posts were never moved. When you talk about OOP you have to talk about it in the context of mutation because that's what Wikipedia lists as part of the definition and that is the only unique and logical difference between OOP and other forms of programming. Thus you must be mutating or reading internal state to be doing OOP.
In the context of OOP and the sort example, noun.verb MUST modify noun otherwise we aren't talking about OOP. IN the context of procedural functions verb(noun), verb COULD modify noun OR it could NOT. In FP verb CANNOT modify noun ever.
FP: verb(noun), verb cannot modify noun
OOP: noun.verb, verb MUST modify noun
Procedural programming: verb(noun), verb can modify noun or it may not.
The implementation changes depending on the context and the context is 100% OOP. For any styles to be isomorphic (which is what you are implying) the properties must match exactly. I talked about OOP in my first comment, you were making a clarification about it in reference to another person who was also talking under the SAME oop context. The title of this entire thread has OOP in it. We are talking about OOP.
You can bend procedural programming to be isomorphic to OOP. But this isn't a two way equivalence, you cannot always bend OOP to fit a procedural function.
This statement from you (a perversion of a statement I made earlier) is ALSO categorically wrong:
>"all the problems of realizing how to divide or unionize services and state in FP are exact same problems that existed when trying to figure out what methods belong with what object in OOP"
In FP, everything has to be immutable. This the exact opposite of a required property for OOP. OOP uses mutability to tie methods with state.
Also you should note the definition of encapsulation is literally my argument of unionizing state with methods plus the added property of information hiding or aka private members and methods (https://www.wikiwand.com/en/Encapsulation_(computer_programm...). That's it. Since you're basically saying that the unionization of state and methods ISN'T the problem... you must be referring to information hiding. The private keyword, according to you is the problem with OOP. All of the problems with OOP (encapsulation) according to you could be fixed if people stopped using the private keyword. Amazing. Take a look at python... no private keyword... didn't fix anything.
>For what it's worth, I agree with your ultimate conclusions.
If you think encapsulation is the cause of the "ultimate conclusion" you need to realize, namespaces and modules and libraries also encapsulate things with no problems. The source of OOP's problems is not in encapsulation. You or whoever introduced that idea to you is completely wrong. Literally you can write a metaprogramming script that removes all the private keywords from objects and according to your logic will fix the problem.
In OOP, unlike FP, immutability is an implementation detail, not a requirement. I'm trying to be gentle about this, but your insistence is becoming tiresome. Again, just do a search and inform yourself. I'm not going to patronize you by listing the numerous links/resources that clarify the above distinction.
>The problem is associated with modularity problems grouping two primitives together into a single entity
>If that method was never unionized with state, if we used smaller subdivisions in our code where state and functions are separate entities then this would be much less of a problem
>all the problems of realizing how to divide or unionize services and state in microservices are exact same problems that existed when trying to figure out what methods belong with what object in OOP
Maybe I'm misunderstanding you argument, but I understand "the problem[s]" above (your words) to be a matter of organization not implementation -- I see no reference to mutability.
I don't have to be wrong about this. `noun.verb` doesn't have to be materially different than `verb(noun)` for the validity of your point to hold about the difficulties of designing and distributing systems being the major obstacle and that abstracting the server model into code being more pragmatic than abstracting the code into the server model.
I am simply clarifying that you can create the same problems with organization in FP as OOP. That is, you can write a function with the wrong signature just the same as you can put a method on the wrong object. Modelling a domain happens before any code is written (theoretically). There is nothing inherent in either paradigm that forces a developer to synthesize a useful abstraction of the functional requirements of their system any better than the other one.
>In OOP, unlike FP, immutability is an implementation detail, not a requirement. I'm trying to be gentle about this, but your insistence is becoming tiresome. Again, just do a search and inform yourself. I'm not going to patronize you by listing the numerous links/resources that clarify the above distinction.
I patronized you with wikipedia. Go ahead and send me some links to some blog posts. Just note that some medium blog posters "opinion" on OOP like your opinion doesn't mean anything without a proper logical reasoning. You will see tons of people who say garbage like "OOP" is "orthogonal" to "FP" which is equal to the amount of people who don't know what FP actually is.
>Maybe I'm misunderstanding you argument, but I understand "the problem[s]" above (your words) to be a matter of organization not implementation -- I see no reference to mutability.
I didn't mention it because it's a very subtle property that's very hard to see and very hard to explain. People understand how OOP is organized on the surface, they don't understand the subtleties of it. Only when we get into details does it come out: Mutability is the very property that dictates the organization of OOP. I get how it appears that I'm moving "goal posts" since I didn't bring it up explicitly in the beginning.
What happened was you noticed a subtle isomorphism between two paradigms but the details were even subtler then that. This is when I chose to bring up the topic of mutability because this is the core property that is intrinsically tied to the organization of OOP. In short, I dove into the details when you brought up a detail... Anyway, mutability It is the core property that breaks the isomorphism and dictates our vocabulary... it's why we have the term OOP, FP and Procedural Programming in the first place.
>I am simply clarifying that you can create the same problems with organization in FP as OOP. That is, you can write a function with the wrong signature just the same as you can put a method on the wrong object. Modelling a domain happens before any code is written (theoretically). There is nothing inherent in either paradigm that forces a developer to synthesize a useful abstraction of the functional requirements of their system any better than the other one.
You're talking about the application of programming styles to the real world which is amenable to opinion.
One paradigm is more flexible to change.
Much easier to change a function operating on the wrong type than it is to change a method intrinsically tied to scoped variables that change state.
The biggest key difference is that FP gives you flexibility to change the model once the inevitable design flaws become apparent.
You will note that in OOP there are no functions or data. Only data bundled with methods called Objects can exist. It's easy to see how these arbitrary walls cause numerous design issues. Also, again, it is the mutability of each object that is the actual instigator of this organizational scheme, I am not talking about the "semantic difference" you pointed out earlier.
>If anything I am _strengthening_ your argument.
I disagree. I believe OOP is actually worse than most other styles of programming for most cases. You are saying OOP is the same as all other forms.
The Wikipedia page to which you keep referring does not support the argument that mutability is "core property" of OOP. The quote you've cited (far above at this point) is referring to a feature of objects, not OOP. OOP encompasses range of features. You can explore them on that very same page under the "Features" section. You will certainly notice that "Mutability" is not listed as a feature. OOP is an _approach_. Simply using objects does not mean you are practicing OOP any more than using functions means you are practicing FP.
I urge to to a ctrl+F on "mutable" and read the top 2 (of 3) passages where it is referenced (the third is not relevant):
> ... in most OOP languages, in particular in all those that allow mutable objects.
> ... in OOP languages (with mutable objects) ...
The clarifications in the above passages are unnecessary if mutability is considered a necessary feature for OOP. If that's not enough, how about you read the first sentence of https://en.wikipedia.org/wiki/Immutable_object:
> In object-oriented and functional programming, an immutable object (unchangeable[1] object) is an object whose state cannot be modified after it is created.
If immutable objects are incompatible with OOP, why is it included in the above?
Are you suggesting that if I write a Java program and I use all of the features of OOP (inheritance, polymorphism, encapsulation, etc.) but don't use mutability, that my system is better understood as functional? Come on. What about an OOP system that doesn't mutate by design? Not every program requires changes of state. We need to put this to rest. I can pretend "this never happened". After all, this entire argument is not relevant to the point I was trying to make (the whole goalpost thing).
> Much easier to change a function operating on the wrong type than it is to change a method intrinsically tied to scoped variables
_This_ is to the point I was trying to make. The above is simply untrue. If I have a function referenced all over my code base, `validate(giraffe)`, and we change the signature to `validate(gorilla)`, it isn't any easier to refactor the system than if it were modeled in OOP. In both cases, the _caller_ needs to have a reference to a different piece of data in order to call our `validate` function. Which means the caller of the caller needs to have a different piece of data (so now the caller needs to change), etc. up the stack. In the end, the most flexible solution in either paradigm is to "inject" the appropriate data (`giraffe`/`gorilla`) via the "DI" mechanism that the paradigm supports. In OOP this is in the constructor. In FP we can use partial application. These two concepts _are_ isomorphic.
I am _not_ saying that OOP is "the same as" all other forms. I am saying, in terms of the pitfalls regarding modelling a domain, all forms are the same. As I understand it, this is the argument your OP was making (you just left FP out of it).
I agree that OOP is worse than FP. There are a few features of FP that make it superior in many respects (notably required immutability and an algebraic type system).
>The Wikipedia page to which you keep referring does not support the argument that mutability is "core property" of OOP. The quote you've cited (far above at this point) is referring to a feature of objects, not OOP. OOP encompasses range of features. You can explore them on that very same page under the "Features" section. You will certainly notice that "Mutability" is not listed as a feature. OOP is an _approach_. Simply using objects does not mean you are practicing OOP any more than using functions means you are practicing FP.
Dude. OOP is programming oriented around objects. The core feature of OOP is objects. Any feature that an object possesses is a "core property." Also it's a pretty safe bet that anything mentioned in the first paragraph of the Definition of OOP is likely a core property.
>If immutable objects are incompatible with OOP, why is it included in the above?
>Are you suggesting that if I write a Java program and I use all of the features of OOP (inheritance, polymorphism, encapsulation, etc.) but don't use mutability, that my system is better understood as functional?
Yes I am. 100% if you use immutability your program is isomorphic to functional programming. It's included because you CAN do this. Just like how you can do functional programming in a procedural language. If you want to compare OOP to other styles you compare the features that are variant not the features that are identical.
>_This_ is to the point I was trying to make. The above is simply untrue. If I have a function referenced all over my code base, `validate(giraffe)`, and we change the signature to `validate(gorilla)`, it isn't any easier to refactor the system than if it were modeled in OOP.
it is easier. We've talked about the deeper difference. validate in OOP is attached to a concrete instance, it cannot be moved up to a more abstract type without affecting everything it's attached to.
>What about an OOP system that doesn't mutate by design?
You may lack the insight to realize it, but if you are doing this your program is basically a functional one. Your loops become recursion, you become unable to write procedural steps and your methods become isomorphic to stateless functions. You are no longer in OOP land.
>I agree that OOP is worse than FP. There are a few features of FP that make it superior in many respects (notably required immutability and an algebraic type system).
An algebraic type system is not exclusive to FP. It's included in Rust which is not an FP language. It has nothing to do with OOP or FP.
>OOP is programming oriented around objects. The core feature of OOP is objects
Objects DO NOT HAVE to be mutable. As I have _repeatedly_ stated, you are building a straw-man. That is, you are creating your _own_ definition of OOP (objects and to some degree FP) and using it to support your argument about modularity. Refer to the "Specialized Objects" section of: https://en.wikipedia.org/wiki/Object_(computer_science)
>Immutable object: an object set up with a fixed state at creation time and which does not change afterward.
Crystal clear. Even the single sentence in which you are basing this entire waste-of-time argument on:
>A feature of objects is an object's procedures that can access and often modify the data fields of the object with which they are associated
in no way supports your conclusion with any rational reading. A "feature" of objects is procedures that can "often" modify fields. It takes some serious gymnastics to read that as "mutability is a required property of OOP". I have yet to find a resource that supports your definition of OOP (and I'm looking!).
>if you use immutability your program is isomorphic to functional programming
Being isomorphic to a functional program doesn't mean the program isn't OOP. From the same page above:
>Object-oriented programming is an approach to designing modular reusable software systems
OOP is an approach. It is the _approach_ one takes when designing a system that determines whether or not that system should be understood as OOP. If the approach uses the "Features" of OOP (listed on the wiki), then the system is OOP.
Your entrenchment on this topic is astounding. Again, I don't have to be wrong about `noun.verb` vs `verb(noun)` for your conclusions about how we abstract software to stand. My intention wasn't to disagree with you, it was simply to point out that all paradigms suffer from modularity problems as they relate to functions acting on state.
>it is easier. We've talked about the deeper difference
No, but we have. And I've clearly demonstrated that same problem presents itself. That's how we got here. You needed to change the constraints of the problem (that objects _must_ mutate) in order to make a coherent argument (the straw-man). That got us to this separate argument about the definition of OOP (moved goal posts). Here is the moment above when you played your hand (and lost the argument):
>A stateless function versus a function that carries it's own mute-able state. There is MORE than a semantic difference. The semantic difference you're referring to is when the SELF value is immuteable. In that case the two ways of calling the function become more similar, but THAT is NOT OOP
Instead of doubling down and starting this dumper-fire of a discussion, you could have simply responded with something like:
"That's correct. Which makes it even more pragmatic that we strive to abstract the server model into code, because the problems with modularity/distribution cannot be avoided in _any_ programming paradigm. That is, the level of abstraction where we WRITE code is not the same, or appropriate level of abstraction used to modularize/distribute code. If, instead of explicitly hard-coding the boundaries of communication into a system, we could abstract the boundaries into compilation as a matter of configuration, it would allow for any arbitrary level of modularization/distrubution without the need to change the source code itself".
The above makes a great point (your point), and has actually served as inspiration for my latest side-project. So kudos to you for that.
>Objects DO NOT HAVE to be mutable. As I have _repeatedly_ stated, you are building a straw-man. That is, you are creating your _own_ definition of OOP (objects and to some degree FP) and using it to support your argument about modularity. Refer to the "Specialized Objects" section of: https://en.wikipedia.org/wiki/Object_(computer_science)
I don't know how to get it through to you what I'm talking about. You fail to understand repeatedly.
In procedural programming YOU CAN MAKE values immutable. Mutability is not a requirement. You don't even have to have procedures in procedural programming. Your functions can be singular expressions of one procedure, equivalent to a functional function. Additionally you can attach all your first class functions in lists, dictionaries or namespaces which makes it equivalent to an OBJECT.
So why even have the words "procedural program" when it has utterly no requirement and can mutate to fit any form of programming? Above I describe using procedural programming to fit OOP and to fit functional programming. It's THE SAME STORY for OOP.
OOP can be used to imitate what we traditionally call functional programming and even procedural programming. Thus everything has an isomorphism.
THEREFORE: When you compare procedural programming and functional programming you HAVE to COMPARE the variant features. PROCEDURAL PROGRAMMING has procedures, while functional programs have expressions.
What does this mean with OOP and all other forms of PROGRAMMING? Mutability. Technically YOU DON'T HAVE TO use mutability, but it's pretty pointless if you DON'T and you can pretty much call your programming style functional if you don't. Mutability is one of THE CORE FEATURES that separates it from other forms of programming. The reason why is because having every single method in an OOP program be a method that mutates its own state leads to horrible design so people usually use it with a combination of both stateless functions and mutating methods. The issue is Almost NOBODY realizes this.
The logic is inescapable: THE CORE DIFFERENTIATOR IS MUTABILITY.
>Crystal clear. Even the single sentence in which you are basing this entire waste-of-time argument on:
No man. It's my time that you are wasting here.
>in no way supports your conclusion with any rational reading. A "feature" of objects is procedures that can "often" modify fields. It takes some serious gymnastics to read that as "mutability is a required property of OOP". I have yet to find a resource that supports your definition of OOP (and I'm looking!).
Read my explanation above. Procedural programming, for loops and while loops DO NOT REQUIRE Muteable values. Yet try to write a for loop without a mutable value see how far you can go in writing a closed function like that without IO.
You won't find anything on the topic JUST LIKE you won't find anything talking about methods and functions being ONLY semantically equivalent. If you do find some idiot blogger who actually supports this claim without mentioning immutability then he likely doesn't know what he's talking about.
>Being isomorphic to a functional program doesn't mean the program isn't OOP. From the same page above:
It's LITERALLY equivalent ACCORDING TO YOU. You called it only a SEMANTIC DIFFERENCE. And I said the SEMANTIC DIFFERENCE ONLY EXISTS if the values are immutable but to you they ARE ALL THE SAME.
>OOP is an approach. It is the _approach_ one takes when designing a system that determines whether or not that system should be understood as OOP. If the approach uses the "Features" of OOP (listed on the wiki), then the system is OOP.
The approach according to you is basically the SAME THING as everything else. I mean verb1(noun1) verb2(noun2) is the same damn thing as noun2.verb2() and noun1.verb1(). There is literally NO DIFFERENCE from this APPROACH to any other APPROACH according to your misguided logic.
>Your entrenchment on this topic is astounding. Again, I don't have to be wrong about `noun.verb` vs `verb(noun)` for your conclusions about how we abstract software to stand. My intention wasn't to disagree with you, it was simply to point out that all paradigms suffer from modularity problems as they relate to functions acting on state.
What's astounding is your lack of understanding. You're intentions don't matter, the topic that I am pointing out is that you are completely and utterly WRONG. You being RIGHT has incredibly absurd consequences.
>No, but we have. And I've clearly demonstrated that same problem presents itself. That's how we got here. You needed to change the constraints of the problem (that objects _must_ mutate) in order to make a coherent argument (the straw-man). That got us to this separate argument about the definition of OOP (moved goal posts). Here is the moment above when you played your hand (and lost the argument):
You've clearly demonstrated a LACK of understanding. AGAIN, what you see as an unnecessary constraint is NECESSARY.
Let me use a more clear analogy. How do you compare the difference between a MAN and a WOMAN? Why you compare the color of their hair, eyes and the amount of fingers they have. Do you really? Or is it a complete act of stupidity to compare the properties THAT ARE NOT EXCLUSIVE TO EITHER?
Let me use a more clear analogy. How do you compare the difference between OOP and FP_______? Why you compare how OOP can be immuteable and how FP can be immutable, you compare how methods and functions can return values... Do you really? Or is it a complete act of stupidity to compare the properties THAT ARE NOT EXCLUSIVE TO EITHER?
Read the above to paragraphs. This is what your entire illogical argument looks like. The only person who lost is you.
>Instead of doubling down and starting this dumper-fire of a discussion, you could have simply responded with something like:
>"That's correct. Which makes it even more pragmatic that we strive to abstract the server model into code, because the problems with modularity/distribution cannot be avoided in _any_ programming paradigm. That is, the level of abstraction where we WRITE code is not the same, or appropriate level of abstraction used to modularize/distribute code. If, instead of explicitly hard-coding the boundaries of communication into a system, we could abstract the boundaries into compilation as a matter of configuration, it would allow for any arbitrary level of modularization/distrubution without the need to change the source code itself".
The above is completely wrong. The problems with modularity AND distribution CAN be avoided but it comes at a cost. You're just too blind to see it. Modularity is actually a very clear concept that is quantifiable.
If every single possible primitive in your program was a immutable module THAT is the MAXIMUM modularity your program can afford. If your program has 5 primitives then 5 is the maximum amount of modules you can have. At a modularity of 5 modules can be composed into higher level modules of your choosing building a pyramid of modules where each level has less modularity then the level below it.
IF your entire program was one single MODULE that could not be reused that is the LOWEST possible level of modularity your program can achieve. In short 1 is the lowest number of modules a program can have.
The only thing we are doing with modularity is picking arbitrary walls and grouping arbitrary amounts of primitives. It's a multidimensional gradient. In a program with ABC primitives you have this many possible groupings (A)(B)(C), (AB)(C), (AC)(B), (BC)(A), (ABC). So 5 possible ways with 3-1 groupings.
What FP does is eliminate arbitrary walls by eliminating mutations.
F(x) = (x + 1 + 2) is easily factored into
F(x) = G(H(X))
Where G(X) = x + 1 and H(X) = x + 2
whereas
Object F {
int val
H(){val += 1}
G(){val += 2}
}
cannot be decomposed.
Both programs have two primitive concepts: the addition of 1 and the addition of 2. That means it has a maximum modularity of 2 modules. However only function F can be decomposed into two modules without changing the nature/signature/interface of F itself. Object F cannot be decomposed without changing what F is.
So in short if your FP program was modularized via (HG) it can easily be broken down to (H)(G) in which case modules can be recomposed however you like... The OOP version cannot be decomposed it is (HG) forever because mutability ties both methods to state.
The problem that exists at the infrastructure level is that MUTABILITY must exist. It's called databases. No server is an F(X) but rather it is a method H or G that is coupled with val (the database).
>The above makes a great point (your point), and has actually served as inspiration for my latest side-project. So kudos to you for that.
You mean taking my idea of writing code or a framework that compiles into servers? Having decorators on functions that specify what part of the infrastructure a function is located in? Composing two functions in code and having that compile into two servers communicating?
It's sort of been done. See RPC frameworks like thrift and gRPC. If you use the same language for all your servers with something like thrift as the connector between all the servers then you achieve roughly the same effect as a language that compiles into servers. The only difference is that your code won't influence the infrastructure, RPC only removes the walls between servers.
I urge you to attempt to condense your replies into more coherent prose. I'm not entirely sure what my takeaways from the above should be.
You seem to have moved the goalposts again from "OOP requires mutability" (which I think you have given up) to "OOP is different from FP":
>THE CORE DIFFERENTIATOR IS MUTABILITY
Aside from the fact that the above is not true (the core differnetiator is all of those "features" listed in the OOP wiki), I have explained a couple of times now that I did engage in this to argue about the differences between OOP and FP. There are numerous differences, and they have very little to do with my (or your) original claims -- other than the fact that you keep trying to move the goalposts to this topic as a means to say that because OOP is different than FP, `noun.verb` must also be different than `verb(noun)` in terms of modularity/dependencies. You are broadening my claim substantially (straw-man).
Again, this is the claim you made:
>If that method was never unionized with state, if we used smaller subdivisions in our code where state and functions are separate entities then this would be much less of a problem. The function would not be tied to state and that function can be executed in the context of anything.
to which myself and two other commentors sought to clarify. The `function` above cannot be executed in the context of anything. It _must_ be executed from a context that has a reference to `state` (because `state` is an argument to `function`). Notably, this is the _same_ context required to invoke the `method`. Similarly, the context of the `function` and the context of the `method` are the same -- they both have access to the same variables (dependencies). So yes, `noun.verb` vs `verb(noun)` is just semantics; both the surrounding and internal contexts are the same. Choosing one approach to express the behavior over the other makes no difference in terms of modularity/dependencies.
>I urge you to attempt to condense your replies into more coherent prose
My prose is coherent. I urge you to gain the intelligence to comprehend it. The only real option is to take english classes. This is not an insult, I see no alternative to help you comprehend english better other than taking a class. Seriously. It's not me, it's you.
> I'm not entirely sure what my takeaways from the above should be.
It's your comprehension that needs work. Re-read it if you can't understand or ask for clarification before you respond. If you have good english then honestly the only other logical explanation is your intelligence. Again not an insult, just observations.
>"OOP requires mutability"
It does THIS NEVER CHANGED. But many methods can be stateless. For your Program to be OOP there must exist methods that mutate state. It IS REQUIRED. If not then you're not doing OOP. Get it?
>Aside from the fact that the above is not true (the core differnetiator is all of those "features" listed in the OOP wiki), I have explained a couple of times now that I did engage in this to argue about the differences between OOP and FP. There are numerous differences, and they have very little to do with my (or your) original claims -- other than the fact that you keep trying to move the goalposts to this topic as a means to say that because OOP is different than FP, `noun.verb` must also be different than `verb(noun)` in terms of modularity/dependencies. You are broadening my claim substantially (straw-man).
Why don't you read my entire claim and respond to each snippet as I have done for you. Rather than take one of my claims ignore all the evidence I provided and go off on your own wild tangent and calling it a straw man. If you want to make my claim a strawman you need to respond to EACH of my points of evidence. I honestly don't even think you read my post. You just did a quick scan and used coherency as an excuse to avoid reading. I responded to your "kudos" as well, which was completely ignored.
>to which myself and two other commentors sought to clarify. The `function` above cannot be executed in the context of anything. It _must_ be executed from a context that has a reference to `state` (because `state` is an argument to `function`). Notably, this is the _same_ context required to invoke the `method`. Similarly, the context of the `function` and the context of the `method` are the same -- they both have access to the same variables (dependencies). So yes, `noun.verb` vs `verb(noun)` is just semantics; both the surrounding and internal contexts are the same. Choosing one approach to express the behavior over the other makes no difference in terms of modularity/dependencies.
Man, we're going in circles. This is crystal clear and you are WRONG. Read all previous post CAREFULLY. Respond to each point if you disagree. The logic is inescapable if you have the ability to follow it. If not this conversation is over.
It never ceases to amaze me how transparently people project their insecurities. I read your post. It was far too long, and all over the place. My response was focused only on the aspects I find relevant to the discussion at hand. I do not need (nor have any desire) to pick apart every point you attempt to make, however inaccurate or imprecise I find them to be, in order to compose my argument.
>For your Program to be OOP there must exist methods that mutate state
Provide me with a single resource that supports this claim (emphasis on "must"). I have found exactly zero corroborating sources that affirm the above, but many that (coincidentally enough all agree) mutability is an implementation detail in OOP. As far I have seen your logic is:
1. Objects _can_ mutate state
2. OOP uses objects
3. OOP _must_ mutate state
Something is amiss... But digress.
I have quoted, a number of times now, the single excerpt from your OP to which I sought to add some clarity. I suppose I can do it again:
>If that method was never unionized with state, if we used smaller subdivisions in our code where state and functions are separate entities then this would be much less of a problem. The function would not be tied to state and that function can be executed in the context of anything.
It's rather narrow in focus, and suggests that separating functions and state leads to more modularized/portable behavior. My response is rather simple in substance: Simply reorganizing `noun.verb` to `verb(noun)` doesn't make any difference in terms of modularization. In other words, the `verb` is tied to `noun` in either case.
That is _not_ to say there is no difference at all. In terms of extension (the expression problem) it is well-known that basic OOP and basic FP are complimentary in this regard. Where OOP allows for open extension of data, FP allows for open extension of operation.
>It never ceases to amaze me how transparently people project their insecurities. I read your post. It was far too long, and all over the place.
It wasn't. Likely you just scanned it without any real analysis. The post is long because of charity to you. It was done with examples to help YOU understand. I have obviously failed to anticipate the complete nature of your mental aptitude. The logical conclusion is that you likely aren't intelligent enough to comprehend any of this, this is not my insecurity rather more you reassuring yourself that it isn't reflection of your intellectual abilities. Unfortunately, It is.
Also, Nothing was off topic, each part of my response was a reply to each point in your response.
>Provide me with a single resource that supports this claim (emphasis on "must"). I have found exactly zero corroborating sources that affirm the above, but many that (coincidentally enough all agree) mutability is an implementation detail in OOP. As far I have seen your logic is:
>1. Objects _can_ mutate state
>2. OOP uses objects
>3. OOP _must_ mutate state
>Something is amiss... But digress.
I have stated this point a dozen times.
Because we are COMPARING OOP with other forms. The attribute of MUTABILITY must be compared. Because THAT is the form that breaks the isomorphism between OOP and FP. Otherwise we are comparing the Exact Same thing. There's no point. That is the property that breaks the "semantic equivalence" So when comparing definitions you MUST incorporate the property of mutability. It MUST be part of the DEFINITION we compare For this reason otherwise we are comparing nothing.
I used procedural programming as an isomorphic example of this above and the comparison of Human Males and Females. Read it again, it may kick some of those brain cells into gear. You believe that you are putting more "focus" but rather your incapability of understanding things is making you perceive things as off topic.
This conversation won't go anywhere unless you address those topics because what you are doing right now is restating your opinion when I have already addressed why your opinions are wrong. So to move forward you must address why I am wrong about you being wrong. This is how discussions/debates go. That's an extra IQ point given to you for free.
Also big thank you for stealing my idea. You're a real stand up guy.
I cannot stress this enough: I am _NOT_ comparing OOP with other forms (in a general sense). I have corrected you repeatedly on this (and pointed out how it is straw-man). My claim that `noun.verb` does not differ from `verb(noun)` in terms of modularity is _not_ that same as the (much broader) claim that OOP is isomorphic to FP. I have never made the latter claim, nor do I believe it to be true [1].
I understand that it does not behoove you to address my argument in good faith, but at some point we have to stop running in circles. Maybe you just misunderstood what I was attempting to say? (this is me giving you a chance to save face)
[1] If I were pressed to describe the relationship between OOP and FP, I would say they are complimentary approaches to designing software (in reference to the expression problem). I _wouldn't_ go so far as to say they are incompatible with one another: https://stackoverflow.com/questions/3949618/are-fp-and-oo-or... (as a matter of sheer coincidence many of the answers also discuss OOP and mutability)
>My claim that `noun.verb` does not differ from `verb(noun)` in terms of modularity is _not_ that same as the (much broader) claim that OOP is isomorphic to FP. I have never made the latter claim, nor do I believe it to be true [1].
Yes but the context of the entire thread is OOP. The semantic claim is made in that context. Also intuitively everyone who reads that will think noun.verb is OOP and verb(noun) is not. It's more like you moved the goal posts.
This also contradicts your claim of FP being different from OOP despite semantic equivalence. If there was only a semantic equivalence between noun.verb and verb(noun) then this implies OOP and FP are isomorphic. There is no other way to call functions or methods in either case and therefore they are the same under this misguided logic.
>Maybe you just misunderstood what I was attempting to say? (this is me giving you a chance to save face)
Save face from what? The thousands of people watching this conversation? I don't even care... this is the internet. Nothing was misunderstood by me. You're the one that's misunderstanding.
>If I were pressed to describe the relationship between OOP and FP, I would say they are complimentary approaches to designing software (in reference to the expression problem). I _wouldn't_ go so far as to say they are incompatible with one another: https://stackoverflow.com/questions/3949618/are-fp-and-oo-or.... (as a matter of sheer coincidence many of the answers also discuss OOP and mutability)
The expression problem is the same problem in FP and OOP according to your semantic equivalence logic. Simply rewriting noun.verb into verb(noun)and vice versa makes both data and operation problems exist in all forms of programming ONLY when values are immutable.
Another way to put it is that FP/immutability solves the expression problem by allowing you to change between the two styles of organization.
When OOP is immutable the two approaches are not orthogonal, they become parallel or identical. It is only when mutability is forced by only allowing member functions that mutate values rather then return results does the expression problem begin to change. This is when both design paradigms actually change and the dichotomy of the expression problem becomes apparent in the context of OOP and FP.
Stack overflow is even less credible than a medium blog post. There's no reason to resort to what you perceive to be authority to dictate what OOP and FP is. I don't even believe there's an officially sourced definition. All you need to do is take what humans as a majority intuitively understand as OOP and translate that into english. Likely when you ask a typical layman to translate his own intuition he'll get it wrong like the teeming millions on the internet. Just use logic to translate the ludicrous consequences of various "proposed" definitions to see which are valid.
It's a waste of time to argue about a topic that is orthogonal to your original claim (before the goalposts moved): that the "problem" with OOP is how you invoke a function -- `noun.verb` as opposed to `verb(noun)`; As if those two systems are subject to different constraints. They are not. It is just semantics.
The above isn't to say there doesn't exist consequential differences between OOP and FP, but I absolutely did _not_ engage in this discussion to argue about OOP vs FP in general. I think we actually both agree FP is a superior paradigm.