Cargo culting OO helps no one, but neither does dismissing it out of hand.
Here are some other things that Adder AA; A=AA.Add(B,C) has over A=add(B,C) that you are glossing over
1) You move the adding logic to it's own file, with other adding-only responsibilities
2) You allow injecting different implementations of Adder - maybe introducing a more efficient one in some cases but not others
3) You enable mocking Adder so that your logic that verifies that B and C are added can be tested without having to re-add B and C all the time.
Not sure how much of a concern this was at the time when OO paradigms were first being created, but in today's world where .Add might be a call to different cloud services, and where unit tests with good mocking are essential for any serious application, these concepts are essential.
> 1) You move the adding logic to it's own file, with other adding-only responsibilities
The code snippet above says nothing about where the adding logic is, other than that one places it in a method while another uses a straight function. Said method/function can live anywhere, unless you have a specific language in mind that prevents you from moving functions to a file?
> 2) You allow injecting different implementations of Adder - maybe introducing a more efficient one in some cases but not others
The thing the code wants to do is add something, so if that can be made more efficient, it can be made more efficient by implementing a more efficient add function. Why is it that you need to introduce something that is not an add function, in order to inject a more efficient add function? Why can you inject an Adder but not add()? What language is that again?
> 3) You enable mocking Adder so that your logic that verifies that B and C are added can be tested without having to re-add B and C all the time.
This makes no sense to me. If you add B and C, you test it once, so what's the deal with this re-adding? And why can't you mock add()?
I hope you are kidding. But yes let’s worry about injection for even the simplest things. Maybe we should start with language injection where you write code and later on you inject a different language. That would be the ultimate maintainable system.
> language injection where you write code and later on you inject a different language.
I (still) work with a Classic ASP code base.
I kid you not, that there are VBScript functions, which call JScript (not JavaScript) functions, which in turn call VBScript functions.
It is a terrifying and glorious mess.
edit:
I also worked with a system at one time that used node.js to create C# files on the file system, then use the C# compiler to create an executable and then run it. It was... not great.
The funny thing is that these things may still have been the best solution for the problem within the available time. I have created some things that in hindsight were horrific but at the time they were the best that could be done.
Here are some other things that Adder AA; A=AA.Add(B,C) has over A=add(B,C) that you are glossing over
1) You move the adding logic to it's own file, with other adding-only responsibilities
2) You allow injecting different implementations of Adder - maybe introducing a more efficient one in some cases but not others
3) You enable mocking Adder so that your logic that verifies that B and C are added can be tested without having to re-add B and C all the time.
Not sure how much of a concern this was at the time when OO paradigms were first being created, but in today's world where .Add might be a call to different cloud services, and where unit tests with good mocking are essential for any serious application, these concepts are essential.