>Well guess what? That's what's necessary to compose things. That's what your compiler or interpreter is doing behind the scenes. You cannot escape this.

How MANY times have I said that there is a definition of compose that is universal and not arbitrary and not specific to certain contexts. You can escape this.

> It might surprise you to learn that "functions" and "procedures" are literally the same thing as far as the computer's concerned (at most, a "function" might be a procedure plus type information, or it might be a procedure that does its own type checking, but it's ultimately a procedure nonetheless).

Except that I have told you repeatedly that not only am I aware of this. EVERYONE is aware of this. Why are you repeating this same concept over and over again. It feels as if this concept is blowing your mind and that you have to share it repeatedly. I hate to break it to you. It's obvious to everyone.

That being said procedures and functions share a equivalence relation. They are not completely the same. If they were then I could call a procedure just like I can call a function, except I can't. Similar to how all programming languages are turing complete but not exactly the same. They are isomorphic but there are differences that can be identified and talked about. Following your logic there would be nothing to compare among any computer language because according to you everything is exactly the same.

>Composing functions is - when all is said and done - literally what my pseudo-Forth example demonstrated, because functions are ultimately just procedures. Forth literally has no type system (at least not by modern standards), and yet it fulfills the literal actual definition of function composition. But no, for some reason that ain't good enough, probably because you seem to believe that there's no middle ground between clean composition (what a type system actually provides) and no composition at all.

I know what you're doing. Get it through your head. I understand it 100%. No need to elaborate. You are bending the system to imitate functions. You can bend functions to imitate procedures as well. I have said again and again I GET IT. Heck you can bend python to be just like forth and write an entire forth compiler in python. Boom now there's no difference between python and forth and therefore nothing to talk about.

Composition is a property of functions through and through. It is not a property of procedures. You can bend procedures to imitate functions but as I have said again and again and again we're not here to talk about the isomorphism between all programming languages and styles of programming. We are here to talk about differences. Functions Compose. Procedures Do not. Stop telling me they are the same, it's like saying that You can drive a car just like you can drive a hunk of metal. How? by making a car out of the metal... just like how you made forth imitate function composition.

>Nothing composes unless you make up some definition on the spot. Composition is meaningless unless you define what "composed" means in a given context. For functions, they're "composed" by calling one with the other's output. For procedures, they're "composed" by calling them one after the other. For objects, they're "composed" typically by either aggregation or inheritance/delegation.

You still don't get it. What do I mean by making up some definition on the spot? It means that given two primitives that I've never seen before I have to make up a new compose function. So for objects A and B I have to redefine a new compose function composeAandB. For objects C and D I have to make a composeCandD. What about procedures? How do I compose steps 1 and steps 6? well the composeStep1AndStep6 Probably needs to insert steps 2 through 5 in between to get a composition. Or if they shouldn't compose period how will a type system or how will a computer know that these two things can't be composed? It can't be done, you must manually prevent this. Arbitrary definitions of composition the spot, that's what I mean. Custom logic literally all over your code to glue things together creating more complexity on every "composition"

When I say a compose function that has a universal definition I mean One where given primitive A and given primitive B, two primitive in which I have NEVER seen before I can compose the two AND the composition preserves context.

I have two functions one function takes sunlight as brightness levels and outputs energy.
Another takes energy and outputs locomotion or distance travelled.

A :: SUNLIGHT -> ENERGY

B :: ENERGY -> DISTANCE

COMPOSE(g, f) = lambda x: f(g(x))

COMPOSE(A, B) :: SUNLIGHT -> DISTANCE

There it is, a single universal definition. New context is created without the need of redefining anything new. True composition. I observed from your post (unlike you) that you already know the definition of function composition. What you didn't know is how it creates new context from old context.

>Not even the purest of functional languages can truly do that. Ultimately, they rely on actual primitives for data; it ain't functions all the way down. Even purely-mathematical functions need numbers to, um, func.

This is how I know you don't know what ur talking about. Do you know lambda calculus? Where are the numbers in that? There are no numbers. How are numbers represented in lambda calculus? Look it up. You can take a look at the Nat type in haskell or idris. The fact that Int exists is abstraction leakage from the lower levels of the computer. Literally Any data structure can be represented by only functions including Numbers.

>The closest you can get to that is... (drumroll...) Forth, which treats any word it doesn't recognize as a call to an imaginary procedure that pushes the value of that word onto the stack, thus trying its darndest to make everything pretend to be a procedure (and thus composable as such). Unsurprisingly - because functions are just fancy procedures - this concept has worked its way into the functional programming realm through concatenative programming.

Guess what. Procedures are just fancy functions. Your mind should be blown right now. When you do forth programming you're actually programming in Haskell. Understand? The two are one in the same. You really need to understand this that underneath the computer doesn't know about context..... All right I'll stop being sarcastic. Imperative procedures do not compose unless you bend them to compose. That's all.

>Put differently: the "power" you feel when clicking together functions like Lego bricks is possible specifically because of procedural composition; the former is just syntax sugar around the latter.

There's no such thing as procedural composition unless you make it up on the spot for every two procedures you want to compose. Again context is required here. A type checker can't check how to compose two procedures.

You literally just called functional programming syntactic sugar. Literally as if nobody knows that assembly language is imperative. Who on the face of the universe doesn't know this? Everybody knows assembly language is imperative, yet no one is uses the term "syntactic sugar" to describe every language built on top of it, only you. You need to stop and open your eyes and stop advertising the fact that procedures and functions are isomorphic as if it's the greatest discovery known to mankind. It's not, it's universally well known. https://www.wikiwand.com/en/Curry%E2%80%93Howard_corresponde...

Everybody knows about the call stack and everybody knows about the heap, so stop with your "revelations"

The "power" you feel when using Forth comes from the fact that you are using forth to imitate the power of functions and your brain is amazed that it can be done with stacks and a pointer (revelation: everyone knows how it works). You need to realize that the functions hold the power and forth is bending over backwards to become a function. Assembly instructions are bad primitives as well, literally we bend an instruction set over backwards so it can imitate functions because that's where the power is.