Programming BASIC was a lot like programming assembly language in terms of how the GOTO and GOSUB keywords worked. GOTO led to a lot of criticism over "spaghetti code", but the limitations of GOSUB were worse.
GOSUB would put the calling location on a stack so you could RETURN to it later but there was no stack for parameters, local variables or return values so you had to use global variables for all of those.
You could not write recursive functions in BASIC unless you implemented a stack yourself using arrays. It was easy to compute Fibonacci iteratively, but people had to sort in BASIC all the time and wrote bubble sort, shell sort and other algorithms that were slow but easy to code in BASIC as opposed to Quicksort.
If you have the kind of functions that exist in C, Pascal, LISP, ML, Python and many other languages then you can write a simple Quicksort in a few lines of clear code.
> Programming BASIC was a lot like programming assembly language in terms of how the GOTO and GOSUB keywords worked.
One of the things many people fail to understand when they criticize GOTO and GOSUB is that it is essentially an expression of what is happening at the hardware level. Modern languages didn't really do away with them. They simply added a layer of abstraction that made it easier to develop reliable software. Unfortunately that abstraction also has overhead, which as problematic when you had a few kilobytes of RAM to work on with early personal computers. I would imagine that it was also problematic on the early multi-user systems that BASIC originated on. It isn't that GOTO is evil. It simply became less necessary for developers to use it in high level languages as technology improved.
Of course, the other thing that made spaghetti code inevitable was the line number based syntax. Until development tools improved, people were basically plopping new statements in random locations because they needed more "space" between existing statements. Yet line numbers were used in early systems since the BASIC REPL also served as a line editor. (At least on personal computers. I'm not sure how it worked on mainframes.)
editing programs with a text editor, saving them on cassette tapes, assembling them, etc. In the same amount of RAM you could have fit a FORTH implementation and with a disk system you could have an experience similar to BASIC based around editing individual disk blocks. With 64k of RAM I would run a C compiler on that color computer and people did the same with CP/M.
So far as mainframes at first they didn't have text editors, instead you would put together a deck of punched cards and submit that to the FORTRAN compiler which would output the object code to another deck of punched cards.
It wasn't unusual for people in the 1980s to use BASIC preprocessors that would read a text file, append line numbers, and let you use structured loops, and GOTOs with named labels. I read about
MSX Basic had "RENUM" or some such, which would renumber all the lines to for instance 100, 110, 120 etc. It also automatically updated all GOTO and GOSUB. So if you ran that all the time, it was almost like line numbers in a text file, but with an extra manual "RENUM" chore thrown in.
Dijkstra doesn't describe the go-to feature as "evil" but as "harmful" and it is.
The problem, which you even mention, is that it's impractical to work with larger programs because their control flow becomes too hard to understand. Now, if you have (as many of the earlier BASIC systems did) only 4096 bytes of RAM you can't write such complex programs anyway, you don't have enough RAM. But even by the time these 4K home computers start to appear on the market the price of a modest business computer is tumbling, and such a computer might have dozens of kilobytes of RAM.
Once a flow diagram you can draw on a whiteboard isn't a correct description of your whole program, but merely a high level summary, go-to is just a foot gun.
GOSUB would put the calling location on a stack so you could RETURN to it later but there was no stack for parameters, local variables or return values so you had to use global variables for all of those.
You could not write recursive functions in BASIC unless you implemented a stack yourself using arrays. It was easy to compute Fibonacci iteratively, but people had to sort in BASIC all the time and wrote bubble sort, shell sort and other algorithms that were slow but easy to code in BASIC as opposed to Quicksort.
If you have the kind of functions that exist in C, Pascal, LISP, ML, Python and many other languages then you can write a simple Quicksort in a few lines of clear code.