>You can compose things without a type system

Compose an array of strings with an integer. What do you get? Run time error OR type error. Please don't make up an arbitrary definition of composition as a counter example. These things generally don't compose unless you make up some definition on the spot.

>You just have to take care to make sure the result makes sense in your domain (which a type system helps automate for you).

Thanks for retelling me what I've been telling you since the beginning.

> That's exactly what the previous OO example did, but you complained that being able to compose anything somehow doesn't count as composition because it's not restrictive enough. Now you're complaining that not being able to compose anything somehow doesn't count as composition.

You don't get it. It should compose anything under a single rule of composition WITH CONTEXT. You are defining an arbitrary compose for a specific pair of types that keeps context but this definition of composition will fail with every other instance of any primitive outside of the Foo and Bar type.

>Let's dig into what you might mean by that, though - specifically with your "arbitrary composition rule for addition". How would you go about implementing add(Store, Chicken) (or Store + Chicken)? What would that mean? What would your THREE actually be after adding your ONE and TWO?

You're asking me? LOL. I'm actually the one asking YOU. I'm telling you that it's NOT POSSIBLE to compose things this way for objects and procedures. you're claiming it is.

Let me state this as specifically as possible. Compose two THINGS under a universal DEFINITION with correct CONTEXT is what I'm talking about. Meaning a function that can compose cooking and ingredients into food can also compose eggs and sugar into a cookie while maintaining knowledge about what a cookie is, and what food is.

Additionally, I am SAYING such a compose function for objects or procedures as parameters with OR without a type system CANNOT BE done.

>but it seems like you ain't exactly satisfied by that answer. Unfortunately, the type system alone doesn't really help you much here; just because the computer knows what a Chicken and a Store and a Popeyes is doesn't mean it knows how to add a Chicken and a Store to get a Popeyes.

Yeah I'm not satisfied with your answers. I'm satisfied with A answer that you don't currently know about. It is definitely possible to compose two primitives with context and with no mortar or rebar under a universal compose function. Just not with objects or procedures as primitives.

>If you object to the "nonsensical" results of trying to add a Store to a Chicken, then you can't get around having to define specific implementations of that composition between a Store and a Chicken. Maybe you can cheat through it a bit by subclassing them from a common ancestor or having them both implement an interface and then add against that ancestor/interface, but that just punts the problem

The problem isn't adding these things together. It's impossible to add these things together. It's getting your computer to know what can be composed and what can't. Your computer should know that composing a chicken with a store doesn't make sense. Either way you're starting to see the full picture because it doesn't even make sense to compose two chickens without you making up an arbitrary definition.

There is ONE primitive where you can do this type of composition. It also relies on parametric polymorphism so in general you can't compose all these primitives together, only primitives of relevant context. Primitives of relevant contexts will compose to form higher order abstractions with contexts that make sense under a SINGLE definition.

If you build your entire program using nothing but composing this primitive then every atom of your program is legos. Modular, reusable, refactorable, scalable. Powerful.