mixer_set_volume(m, 0.8);
What is m, if not an object? mixer_set_volume(m, 0.8);
What is m, if not an object?The issue with m->set_volume(.08) is it becomes difficult to tell what happens inside set_volume() because in the method scope you have access to the internals of the "m" object, not just the interface.
With mixer_set_volume(m, .08) you have ".08" and "m" but only the interface "m" exposes anywhere else. Thus it becomes easier to reason about effects.
>> The issue with m->set_volume(.08) is it becomes difficult to tell what happens inside set_volume()
Isn't that the point? That you shouldn't have to care what happens inside set_volume? If mixer was designed and implemented well, then set_volume (along with the rest of its interface methods) should consistently and correctly handle its internal state.
Thus m->set_volume(.08) and set_volume(m, .08) should not require you to understand what happens internally as the user of either.
More generally in programming that is the point.
My only point is that of scope and essentially search space -- set_volume(m, .08) can only access the public interface of "m". While, m->set_volume(.08) could do almost anything to m. In a perfect world, with perfect programmers thinking the same way about what "set_volume" means or should do the separation of state and action would be less valuable.
This not to say OOP is > Functional or vice-versa. I think there is a place for both but that is a MUCH larger and more nuanced conversation :)
But the truth is that one can write many different stories on this line. One can tell the OO story in which m is an object, one can tell the FP story in which m is an IOMonad, one can tell the procedural story in which m is a record.
All of these stories are more or less equally good if it's a single line of code. But on a whole program, some of them can be more or less believable at certain points. For instance, when the OOP story tells us that integers are objects and that "+" is a message to which integers answer by given the result of an addition, this part of the story can seem a little far-fetched for some people.
Is there such a thing as the "best story in the world"? Definitely not. There's not even a "my favourite story" for most people, but instead a "my favourite love story" and a "my favourite horror story", and so on. How does one come up with a favourite story? By reading stories.
(Yes, you cannot inherit all kinds of objects – but you definitely can inherit any kind of struct, POD or not.)
Usually when people are talking about OO objects they mean data+behaviour.
The distinction between behavior being "a set of methods defined inside a class", and "a set of methods whose first param is a particular type of struct" is not that important.