Sure. Before the Altair/MITS/SWTPC/Kim/Sinclair/Pet/RadioScrap/OSI/Apple things happened, there was a delightful little machine known as the IBM 5100. It had BASIC in ROM, a big cassette tape drive (or two), 8 KB of memory. a 24 line screen, and a printer, all for a measly USD 10,000 -- an order of magnitude cheaper than your typical mini. Originally built for scientists (APL in ROM was also an option), but then a few accounting types discovered it, and started a craze: every small business wanted one. With custom software, of course. The 5110 followed that, with the tape drives replaced by 8" floppies.

Any commercial software? Galoons.

Can you say general ledger, payroll, accounts payable, accounts receivable, inventory control, and invoicing? I have been there, done that -- in BASIC. Utility bills, new and used car inventory, garbage truck pickup and beverage delivery scheduling? Yup -- BASIC. Want to track iron ore from mines onto trains onto ships... BASIC. Everything that wasn't raised floor was likely getting done in BASIC. Commercially, I mean. (Because RPG II doesn't count ;-).

How did one work around the limitations?

Well, the first thing you did was send the customer back to IBM for more memory, Because who could write anything serious in 8 KB? You simply had to have 16. And two tape drives, if possible, because automata theory aside, merge sorting on a single tape is, well, a tad slow.

Oh, sorry - you meant the limitations of BASIC.

Well, you had to manage your resources pretty carefully -- things like line numbers -- because you didn't want to run out of those; real pain in the behind to have to renumber a whole section, and type it all back in, without accidentally losing a line or two of code.

Nah - just kidding. We didn't actually have that problem until micro---er, home computers showed up, with a BASIC interpreter that couldn't do renumbering by itself.

We also used modularity - where you called a new program, ran it till it quit and returned back to the calling program. A gosub on steroids (because you got more memory to use), but way slower (because it took a while for the machine to find the program on the tape, and load it in, and then rewind and find the original program and load that back...). A lot like a fork and exec, but without the fork, only better because the whole memory space was shared.

Rigorous use of conventions also helped -- you know, like "you MUST always target a GOSUB at a comment line that says what this routine does, and you SHOULD do the same for a GOTO when possible. Stuff like that. Oh, and structured programming, a little later -- "by convention" again.

Some even went a little to the extreme: OAOO, YAGNI, TSTTCPW, pairing, refactor mercilessly, that sort of stuff. Not by those names, of course. (See also: Ecclesiastes ;-)

The glory days.