10 December 2013

BCPL pointers were not zero indexed because of compile time issues.

Re: Citation Needed - blarg?

Mike has done a bit of research, but not enough. Reading and understanding the BCPL manual (let alone having any experience with '60s and '70s compiler technology) would have made this jump from Martin Richard's comment (which says nothing about the cost of optimizing the code) to "in that context none of the offset-calculations we’re supposedly economizing are calculated at execution time" obviously wrong.

First, the yacht thing is a complete red herring. You always had to limit your job run times because computers were just plain unreliable. They could easily go down several times a day, forcing the restart of a job. Higher priority jobs could always show up and bump you, and getting bumped was not all that big a deal... you'd just get run again once it was done, if by chance you happened to be late in the queue you'd run a day or so later at the most... and that could happen anyway if jobs before you ran into problems or there was too much maintenance downtime. A handicapping run a few times a year? that's nothing.

Second, you could have expressions on both sides of the dyadic "!" operator. "V!I" was exactly the same as "I!V" ... Richards spells that out explicitly in the text Mike quoted! There's no reason to treat it as a compile-time-only issue.

Third, of course BCPL had pointers. It was completely typeless, an address was just a number. When you wrote

LET V = VEC 5

You create both a pointer variable "V" and allocated a 5 element array to it. Yes, it really allocated a total of six cells. As far as I recall, "V" could be reassigned to point to another vector, or incremented within itself.

Fourth, local variables were dynamically created on the stack. So a local

LET V = VEC X

could be at any address in the stack, depending on the call history.

Fifth, and backing up my recollection in the third point, the BCPL manual has an example of pointers being initialized on page 27:

LET IOV = VEC 650
LET IOVP, IOVT = IOV, IOV + 650

Sixth, he's applying 21st century reasoning about compilers to the '60s. When you wrote:

V!1

it's virtually certain that the compiler would actually generate the code to fetch "V" and add one to it. I would be staggered to learn that the compiler optimized away this extra indirection, ever, because that would have required tracking the state of every variable used as an lvalue to know when that optimization was safe.

Finally, seventh, and most critically, using 1 index on the dyadic "!" operator would have caused extra complexity for *programmers*, because suddenly "!(V+I)" would mean something different from "V!I", and having "!(V+I)" mean "the memory at V + I + 1" would be just nutty.

BCPL arrays, like C arrays, were zero-origin because it fell naturally out of the unification of pointers and other values in a low level language.