>Objects allow you to describe user-defined data by composing objects

No you got it wrong. :) Re-read what I wrote about dependency injection. You are surgically grafting an address into Person. You must change the nature of person (The type signature) in order to graft in an address, this is not Composition. This is the creation of a dependency. The fact that people call it composition over inheritance is entirely the wrong word. A more accurate term but not fully correct is "Explicit Dependencies over Inheritance."

Meanwhile examine my function composition. In the composition of two functions into a new function... the nature of either function remained EXACTLY the same. The type signature does not change.

When I talk about COMPOSITION, I am referring to a different sort of composition. My entire piece on the nature of design, works on THIS type of composition which is entirely different from what people talk about when they talk about Object Composition.

Also, your example was not an Object defined by OOP. Your example is just data. It's more akin to a dictionary/hashmap/Record than it is an "Object" as defined by OOP. An Object has methods that operate on itself which your example failed to show. Think about how a method on one object would compose with the methods of another object... it becomes a mess. Just letting you know the difference.

:)

>Nope, everything is an object, numbers, array, function, etc, are objects.

This is an arbitrary definition that probably comes from smalltalk. In foundational mathematics category theory or the theory of sets; functions and data are different primitives. This makes more sense from a primitive standpoint.

Traditionally, in OOP as popularized by JAVA and C++, an object is defined by a class syntax definition. On the class you can put in methods and data. This Class is entirely different from another separate primitive in C++ called an Int, where on the Int methods don't exist and data/functions are different. The popular definition of OOP is the one I refer too.

>Methods are functions biased toward an object, which allows polymorphism, so you can abstract over data

The type signature of a function biases a function towards that type. You don't need to "attach" it to the "type." That being said a method has the ability to mutate data while a function does not. This is the true difference between method and function.

:)

>That said, OOP has several flaws: - at some point someone decides that OOP was about inheritance or prototype chains but those mechanisms are more bad than good. - existing mainstream languages tend to favor mutable objects by default which leads to bugfests.

When you create an "object" that is immutable it is no longer object oriented programming. It becomes functional programming. When objects become immutable, then all functions "attached" to the object are simply scoped functions. Whether you define that function in one scope or another scope is not the point as the type signature will control the overall bias of the function, not the scope.

The type of programming described by the definition of OOP as popularized by JAVA and C++ tends to use mutators like getters and setters to change state. With this last paragraph you wrote, you're essentially changing the topic, you're talking about non-traditional OOP. It's a loaded word, you might as well call it what it is: Functional programming. Still under this methodology your scoped methods are scoped in a way where they can never compose with functions outside of the object. It's an arbitrary cut and bad design for primitives. It forces you to compose data along with methods at the same time.

I'm sorry but you entirely missed the point.

:)