This makes a lot of sense. It makes me think of Go's approach to blur the distinction of heap/stack by just treating it as an escape analysis problem leading to an allocation choice. If it provably doesn't escape => optimize it by using the stack, otherwise fallback to the heap.
The distinction of stack vs heap objects is an old distinction that is deeply encoded in the semantics of C. It's not obvious that's the right choice.
It's worth pointing out however that you do want to have control sometimes. When you're coding for performance, etc it can be very important to control exactly where objects live (e.g. this must be on the stack with a certain layout). I feel like sometimes it's underappreciated in modern PL design that low-level coding needs this kind of control sometimes.
I think there exists a happy medium solution ultimately though.
> The distinction of stack vs heap objects is an old distinction that is deeply encoded in the semantics of C. It's not obvious that's the right choice.
Nothing about C requires a contiguous stack, and there are perfectly standard C environments where the stack isn't contiguous, where call frames are allocated dynamically and managed (singularly or in groups) as a linked-list, e.g. some mainframe environments, gcc's segmented stacks, etc. C's automatic ("stack") variables are defined in terms of their lifetime, which is basically lexical.
> The distinction of stack vs heap objects is an old distinction that is deeply encoded in the semantics of C.
It's the most flexible way to implement recursive functions, and it's encoded on the semantics of the opcodes of every modern processor. They are way more deeply entrenched in our tech than just in C.
But it may make sense to mix them in some ways. None of that detracts from the point.
That's a good point. It is pretty intertwined with ISAs. But, I think you could successfully argue it's just C semantics leaking into the ISA. C was so incredibly successful that it's hard to appreciate sometimes that all the systems (abstractions above and below) that touch it came to embrace and conform to it's semantics.
In a lot of cases, we could argue that ISAs have been shackled by catering to the specific details of C. But if we're just referring to the CALL instruction (and its equivalents), that's not a reaction to C, it's a reaction to structured programming, which was a good thing.
A linear stack, distinct from a heap, is not required for recursion. It's also not required for most of the local state: the minimal requirement is to keep track of the minimal context information in order to resume the suspended caller when the callee terminates.