Exactly. A MOV is reduced to a register rename. An intelligent compiler can rewrite multiply/divide by 2 as shifts if it makes sense, etc.
"Assembly is not a low level language" is my favorite take, and with microcode and all the magic inside the CPU, it becomes higher level at every iteration.
> It is possible to write complex and performant programs without allocating memory.
I assume you mean by only allocating on the stack? Those are still allocations. It's just someone else doing it for you.
> And in some languages, where you only operate on values, and never worry about where something is stored, allocation is just an implementation detail.
Again, that's someone else deciding what to allocate where and how to handle the pointers etc. Don't get me wrong, I very much appreciate FP, as long as I do information processing, but alot of programming doesn't deal in abstract values but in actual memory, for example functional programming language compilers.
in some form or another is the key to their point.
Here's something to try at home .. exactly your code save for this change:
i[a] = 1;
... guess what, still compiles, still works !!
WTF ??? you ask, well, you see, X[Y] is just syntactic sugar for X+Y - it's a pointer operation disguised to look like a rose (but it smells just the same).
> It's impossible to write complex and performant programs without null.
Well, clearly there is a need for a special value that is not part of the set of legal values. Things like std::optional etc. are of course less performant.
If I can dream, all of this would be solved by 72-bit CPUs, which would be the same as 64-bit CPUs, but the upper 8 bits can be used for garbage collection tags, sentinel values, option types etc.
> Well, clearly there is a need for a special value that is not part of the set of legal values.
There's a neat trick available here: If you make zero an illegal value for the pointer itself, you can use zero as your "special value" for the std::optional wrapper, and the performance overhead goes away.
> If I can dream, all of this would be solved by 72-bit CPUs, which would be the same as 64-bit CPUs, but the upper 8 bits can be used for garbage collection tags, sentinel values, option types etc.
Address space is 64bit, pointers are 128bit, and encode the region the pointer is allowed to dereference. And there's a secret 129th bit that doesn't live in the address space that gets flipped if the pointer is overwritten (unless it's an explicit instruction for changing a pointer)
All reference types should be able to take a null value.
It's impossible to write complex and performant programs without null.
It's impossible to write complex and performant programs without pointers.
References always hold a memory address in a linear address space. (Not even true in C!)
Every type is comparable.
Every type is printable.
Every type should derive from the same common type.
All primitive types should support all kind of arithmetic the language has operators for.
The only way to extend an existing type is to inherit from it.
What else?