> Part of me suspects this was also because it was seen as "clever" at the time. Look ma, we let arrays turn into pointers! Isn't that clever?
It was intentional and functional. The idea was basically a primitive kind of polymorphism, which allowed for functions intended to act on arrays to accept any size of an array to be passed in. It was redundant with pointer arithmetic, but allowed for communication of intent without accidentally incurring a semantic unit of meaning. There's an interview where Ritchie talked about this.
Pascal's biggest misgiving was that it went the complete opposite route, where pointer arithmetic was disallowed and arrays did not decay. It also lacked any kind of polymorphism, and one of the biggest ergonomic painpoints ends up being that if your problem domain has non-uniform array sizes, you're in for a lot of annoying re-writing.
> When you look at pre-ANSI C function prototypes you wonder "where are the parameter types?" because there are none.
Actually pre-ANSI C technically didn't have function prototypes, ANSI C introduced them and it got them from C-with-classes. It did have function declarations though (which aren't the same thing)
Pedantics aside,
f(a, b) { return a + b; }
This is fully typed, the parameters and return type default to int.Fun fact:
int f();
Does not declare a function with no parameters, but it does declare a function with an unknown number of parameters of unknown types. An empty parameter list in C is: int f(void);