>This is where you lose me. The above is simply untrue.

No. My statements are true. But you are right about you being completely lost.

>There is absolutely no reason one cannot employ `SortingAlogrithm.sort` within the body of `people.sort()`

Let's talk about objectives and what you're implying with this suggestion. The objective is to sort a bunch of people within the the people class.

What is SortingAlogrithm.sort? Is it an object that sorts its own state or is it a stateless class with a stateless function? If it's an object that sorts its own state then it CAN'T do what I want. I want it to sort peoples' state NOT it's own state. If it's a stateless class with a stateless method then you are no longer doing OOP you have created a function that is not tied to state thereby proving my point that stateless functions are more modular.

>Are you suggesting every utility class (and by extension the entire standard lib) needs to be injected into an object before it can be used?

Yes this is the model in pure OOP languages. Otherwise you are using a hybrid of OOP and functions thereby providing evidence that OOP alone is broken. Things like JAVA, C++ do all kinds of BS like this further ingratiating my point.

>Again, you are creating a false-equivalence.

No. You are failing to understand. 'Lost' was the term you, yourself used.

>A "fair" example would require our generic `sort(comparable)` be passed into the original as a dependency like so: `sort(people, csort)`.

This is not fair at all. in fact it's ugly. I pass a generic sort as a parameter into a specific sort? If you think that's fair and you code this way then you're in for a surprise when building a complex system.

>It's _possible_ that the two functions could be composed, but that is completely dependent on the semantics of each function (we cannot just assume composition is possible for every use-case).

I'm thinking you got confused by what I mean by composition. There are two compositions I am referring to in my statements. Function Composition and Object Composition. Object Composition is exactly the previous example you gave sort(people, csort) or inserting something via the constructor People(csort), there's a number of ways to do it.

Function composition of A(x) and B(x) is F(x) = A(B(x)). Function composition is at the heart of functional programming.

>It's _possible_ that the two functions could be composed, but that is completely dependent on the semantics of each function (we cannot just assume composition is possible for every use-case).

If you're not changing state and something has properties of being sortable it can be done.

you have x = sortableListOfPeople

composedFunctions = f(sortableListOfPeople) {return doPeopleSpecificStuff(sortGeneric(sortableListOfPeople))}

you can go the other direction if you want. The implementation is situation specific but if something is sortable this can be done always but only if all functions are stateless and don't modify values. Note composedFunctions should have the exact function signature of the original function thereby negating the need to change other things dependent on it.

>The difference between a first-class function and an object is purely semantics.

No. A first-class function cannot change. It is immuteable and when called with the same input Always has the same output. An object with a method when called at different times can have different output based off of internal state. Your statement is categorically wrong.

>Yes, you have to `new` an object before you can call a method, but there is no requirement any "implicit context" has to be provided at the time of instantiation.

Then you are basically declaring a stateless function. The admission that you have to do this is an intrinsic flaw. Yes nothing prevents you from going outside of the OOP paradigm when programming in an OOP language. You likely have no choice due to inherit flaws in OOP. Try doing OOP without this ability... You'll see how broken the whole model is.

>Conceptually, all OOP does is take 10 functions that all have the same parameter and "partially apply" each of them over that parameter into new functions that don't have a parameter (i.e. they get that "implicit context"). That is, OOP saves you a step. It is common practice in FP to start with "pure" functions then, higher up in the application, partially apply those functions into new, domain-specific functions with your data (a.k.a. dependency injection) that are strung together to carryout a use case. OOP allows you to _define_ partially applied functions instead of the need to compose them (of course this also makes the DI mechanism a bit different as well).

Let me tell you definitively. I completely understand what you're talking about, I understand it now and I understood it before. No need to reiterate. What you're not understanding is that despite my 100% comprehension of your statements I am telling you, that you are failing to understand ME.

Let me try to put it as simply as possible. If there is an Object called Number and a method called addOneAndReturn... if I call that method on a Zero Twice? what happens? I get One and then I get a two. The method is returning two different values despite being called in the same way TWICE. This sort of thing is NOT POSSIBLE in a stateless function. It Cannot Happen period. THIS is the fundamental difference. THIS is MORE than semantics.

Yes I understand that currying and first class functions have parallels to Dependency Injection BUT there is still MORE then a semantic difference between OOP and functions.

>your general critique reads more of one leveled at programmers not understanding the basic principals of software design

Design is the domain of things we don't understand. There is no design in type theory or number theory because we understand all the implications of the axioms and theorems. We go to design when there is no formal theory that can say why one design is better than others.

I am not coming from the design perspective. I am coming from the theory perspective. When you tie functions with state the state must move along with the function. If you keep state and functions separate then they can move separately. This is logic. No design principles needed.

Any language with too many design patterns is a language that is very much lacking in a formal description (think: JAVA)

>I could just as easily create a mess in FP as in OOP.

You can. But there are more ways to do it in OOP then in FP.
In fact there are more ways to shoot yourself in the foot in OOP than in procedural programming in general. I'm not even referring soley to FP. Even C is better than C++.

>I urge you to sit down and write out the pseudo-code. It will be plainly obvious that there is no meaningful difference between each approach.

You don't need to write psuedo code. Use your brain dude. 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.

There is one rule that needs to be followed to make ANY program FP. Just one rule, that's it. Make all things immutable. OOP is fundamentally different from this because it involves the mutation of Object state.