K&R C being superseded and C++ being a development upon C
C++ is not a development of K&R C, it"s a wholly new language implemented on top of C. C99 is a development of K&R. C++ is merely a hopelessly complex abomination
I don"t think anyone"s saying Basic isn"t good enough per se
I am. In my opinion, BASIC is useless as a teaching language, as it lacks the means to adequately express anything beyond the most "basic" of concepts. There are no concepts expressible by BASIC which cannot be equally easily expressed in other, more capable, languages. And that goes for the more "modern" BASICs as well as the horrible 8-bit ones.
Indeed, I"d go further. Extending BASIC is a pointless exercise unless, like C++, you go way beyond what BASIC is, at which point you have another language that has some BASIC-like syntax. Syntax, of course, being irrelevant, except where you"re talking about beginners, where "as little pointless syntax as possible" is king. Arguing about whether brackets should be square instead of round or vice versa when the language is fundamentally incapable of passing arguments to a function is like arguing about how many angels can dance on the head of a pin – you can do it, heatedly, for as long as you like, but it won"t solve any of the fundamental problems.
In short, use another language. BASIC is rubbish.
John Beetem said:
GOSUB relies on global variables, because it does not take parameters or return results. That"s *really* bad – even assembly does not really work that way.
Actually, I would say that assembler / machine languages for most popular architectures do exactly that. ARM"s Branch and Link instruction just jumps to the subroutine while setting the Link Register (R14) to the return address. Arguments and results are passed via global resources like general-purpose registers and the stack.
Registers and stack are inherently transient, inherently "local". Take the following examples (we'll stick with the ARM calling convention, but I could use pretty much any other one, I think):
I have a function that takes 3 32-bit arguments, and returns one. The calling convention states that I pass the first argument in r0, the second in r1, the third in r2, and that I must retain the values of r4-r12. r0-r3 are considered "throwaway", and r0 is used to return a value.
As I am passing 32-bit values *by value*, the values my function receives in r0-r2 are inherently local – on return, r0 is guaranteed to be blown away by the return value and r1-3 aren"t guaranteed to be anything at all.
Next – I have a function that takes a structure or other >32-bit value as an argument (again, passed by value). This is passed on the stack frame. Again, on function exit, this is not guaranteed to be in place, as unwinding the stack on function exit automatically places the frame out of scope.
The only way to get around the implicit locality of passed-in variables is to pass by reference, where, instead of passing the value, I pass a pointer to the value (which can then be a value which is global, local to the calling function / one of its callers, or a mutable copy of some other variable). The pointer itself, of course, is local to the called function, and if we want to change a pointer then we have to pass a pointer to a pointer, and so on.