The Broken BASIC Years

I polled Mastodon people a few weeks back:

mastodon poll:
If you had a home computer with BASIC, how many times did this programme print the text '3 TO 2' on your computer?

10 FOR X=3 TO 2
20 PRINT "3 TO 2"
30 NEXT X

Results:

28%: 0 / None
57%: 1 / Once
15%: Something else, or show me the results

Twice as many people said their home computer’s BASIC did something illogical as said it did the right thing. What gives?

The de facto problem

BASIC was refined over several years in the mid-1960s as part of the Dartmouth Time-Sharing System (DTSS) running on a GE mainframe. It was intended to be accessible to all students at Dartmouth. Responsiveness to user commands was valued over performance. The concept caught on, and by 1970 DEC, HP, IBM and GE all had time sharing BASIC systems in the market.

The language was simple enough that if you’d used it before on another system, you’d have a good idea how it should look. Implementations of BASIC sprung up on lots of computer systems based on whatever documentation was at hand: if you were lucky, maybe a photostat of a Dartmouth BASIC manual, or maybe one of the programming manuals that DEC sold for their PDP-8 systems.

The original BASIC ran on a mainframe computer with each line being compiled into separate jobs by a terminal server. Early microcomputer developers, however, saw BASIC as something they could fit into a few thousand bytes as an interpreter. With so little space to work in, and so few guidelines to work from, implementation rules became very blurred. Here’s what you might have expected to see if you fired up your 8K Altair 8800 some time in 1976 after buying a shiny new (and $$) copy of Altair BASIC:

MEMORY SIZE? 8192
TERMINAL WIDTH? 80
WANT SIN-COS-TAN-ATN? N

1862 BYTES FREE
ALTAIR BASIC REV. 4.0
[EIGHT-K VERSION]
COPYRIGHT 1976 BY MITS INC.
OK
10 FOR X=3 TO 2 STEP 1
20 PRINT X
30 NEXT X
40 PRINT X
RUN
 3 
 4 
OK

With so little memory to play with, the FOR X=3 TO … is effectively treated as LET X=3, and NEXT X becomes LET X=X+1 (with an optional GOTO 20 if X < 2, which it never is). The 1975 Altair BASIC Manual has a slightly more lucid description on page 32, but doesn’t explain why it does this. Maybe it was influenced by FORTRAN-66, which always executed a DO clause once.

The only guidance against this admittedly illogical behaviour is hidden away on page 37 of the Dartmouth BASIC 4th Edition manual from 1968:

text: If you write 50 FOR Z = 2 TO -2, without a negative step size, the body of the loop will not be performed and the computer will proceed to the statement immediately following the corresponding NEXT statement.
No, I can’t get past that the Os are slashed and the 0s are not, either

So in a feat of mass emulation (and sometimes using real vintage hardware), here are some BASIC systems that always execute a FOR loop at least once:

  • Altair BASIC 8K (version 4.0, 1976, Microsoft – 8080)
  • BASIC-E (version 2.0, 1976, Digital Research – 8080)
  • Tiny BASIC (version 3.1, 1976, Sherry Bros./Li Chen Wang – 8080)
  • BASIC-80 (version 4.51, 1977, Microsoft – 8080)
  • Commodore BASIC (1977, Microsoft – 6502)
  • Integer BASIC (1977, Apple – 6502)
  • TRS-80 Level I BASIC (1977, Radio Shack – Z80)
  • AppleSoft BASIC (version 2.0, 1978, Microsoft – 6502)
  • Atari BASIC (1979, Atari Inc. – 6502)
  • Atom BASIC (1980, Acorn – 6502)
  • Sinclair ZX80 BASIC (1980, Sinclair Research – Z80)
  • BASIC3 (version 1.1, 1981, RCA – 1802)
  • BBC BASIC (version 2, 1981, Acorn – 6502)
  • CBASIC (version 2.07, 1981, Digital Research – 8080)
  • Extended Color BASIC (version 1.1, 1982, Microsoft – 6809)
  • Lynx BASIC (1983, Camputers – Z80)
  • MSX BASIC (version 1.0, 1983, Microsoft – Z80)
  • MTX BASIC (1983, Memotech Ltd – Z80)
  • Oric Extended BASIC (version 1.1, 1983, Tangerine – 6502)

And these are the interpreters that handle FOR loop variables correctly:

  • PDP-8 BASIC (1970, DEC – PDP-8)
  • TOPS-10 BASIC (version 5.03, 1972, DEC – PDP-10 KA10)
  • 9830 BASIC (1973, Hewlett-Packard – HP9800)
  • 5100 BASIC (1975, IBM – PALM)
  • HP 2000/Access BASIC (version r.1534, 1975, Hewlett-Packard – HP2000)
  • BASIC-11/RT-11 (V02-03, 1978, DEC – PDP-11)
  • BASIC-80 (version 5.21, 1981, Microsoft – 8080)
  • IBM PC BASIC (version 1.10, 1981, Microsoft – 8088)
  • Sinclair ZX81 BASIC (1981, Sinclair Research – Z80)
  • Amstrad CPC464 BASIC (version 1.0, 1984, Locomotive Software – Z80)
  • BASIC for Macintosh (version 2.00, 1984, Microsoft – 68000)
  • Mallard-80 BASIC (version 1.29, 1984, Locomotive Software – Z80)
  • SuperBASIC (QL) (1984, Sinclair Research – 68000)
  • Extended BASIC (version 5.7, 1985, Data General – DG Nova)
  • Enterprise IS-BASIC (version 1.0, 1985, Elan/Intelligent Software – Z80)
  • Amiga BASIC (version 1.2, 1986, Microsoft – 68000)
  • Atari ST BASIC (1987, Metacomco – 68000)
  • GfA BASIC (version 3.51, 1988, GFA Software – 68000)
  • GW-BASIC (version 3.23, 1988, Microsoft – 8088)
  • QBasic (version 1.1, 1992, Microsoft – 8088)

It’s a little hard to see trends in a sea of bullet points, but:

  • Up until about 1975, BASIC systems from DEC, Hewlett-Packard and IBM did the right thing with FOR loop variables.
  • Small BASIC systems on the Intel 8080 appearing after 1975 introduced uncertainty in FOR loop behaviour.
  • Many of these iffy systems were written by Microsoft, though many other vendors copied that behaviour. (Whether they copied code too, I can’t tell).
  • The ANSI working group efforts to develop a standard for BASIC between 1974–77 were too late to have much influence. At best, they codified a standard almost identical to Dartmouth BASIC of 1964, thirteen years too late.

Changes … but why?

Microsoft did make a change in their FOR loop behaviour, though:

  • BASIC-80 (version 4.51, 1977) always went through the loop at least once;
  • BASIC-80 (version 5.21, 1981) did not.

What prompted that change is referenced in a tiny little note in the manual‘s introduction

In its fifth major release (Release 5.0), BASIC-80 meets the ANSI qualifications for BASIC, as set forth in document BSRX3.60-1978.

This still doesn’t explain why Microsoft changed their interpreter. But one document does, indirectly: Federal Information Processing Standards Publication 68: minimal BASIC from September 1980. It states that ANSI Standard X3.60-1978 is adopted as a FIPS norm, and therefore:

11.1 Acquisition of Minimal BASIC Processors.
The provisions of this publication are effective on September 4, 1980. All BASIC processors specified for Federal use after this date must implement Federal Standard Minimal BASIC.

In short, Microsoft wasn’t going to be able to sell BASIC to US Government agencies after September 1980 unless they fixed it. And selling software is what motivates Microsoft most. So they fixed it.

(Curiously, the actual text of ANSI X3.60-1978 is still paywalled, though the supposedly similar Standard ECMA-55: Minimal BASIC is available. I will never understand standards bodies and their eternal grabby hands.)

Sinclair, by complete coincidence, also changed how FOR loops work between the ZX80 and ZX81. I doubt that this was for FIPS compliance, but rather that ZX81 BASIC was in an 8K ROM instead of a 4K one, so there was more room to do the right thing.

It’s also interesting to note that Microsoft didn’t change all of their BASIC interpreters after 1980. Sure, the important (as in, $$$ for Microsoft) ones like IBM PC BASIC got it, but the later MSX BASIC didn’t. MSX wasn’t a low-effort port, though: it had a new graphics system and a completely different decimal floating point package.

And if only Acorn had read the BBC’s “Outline Specification for the BBC Microcomputer System” in detail, they might have caught the requirement that:

The general syntax of all commands should be identical to Microsoft BASIC 5.0 (repeat 5.0)

With better reading comprehension, Acorn would have had an almost perfect BASIC interpreter in the BBC Micro. Oh well.

What came next?

I’ve already shown that a standard, especially one that had commercial ramifications, changed the way BASIC behaved after 1981. But BASIC language development mostly ignored any formal standards.

Associated with the FIPS norm were the National Bureau of Standards’ Minimal BASIC Test Programs. The version 2 test set from 1980 is still available from NBS:

There are more than 200 test programs, which you can attempt to run, if you must. They’ve been collected in source form by John Gatewood Ham, Jorge Giner Cordero and others, with an archive available here: bas55/tests as part of the bas55 Minimal BASIC interpreter.

The ANSI full BASIC standard sneaked out in early 1987 to little fanfare. Most of the working group were from mainframe companies, though Thomas Kurtz (one of the originators of BASIC at Dartmouth, along with John Kemeny) was still part of the process. There are no names from micro companies: except for one “J. Raskin”, possibly Jef Raskin, ex Apple.

Kemeny & Kurtz couldn’t leave BASIC alone, and in 1985 had written “Back to BASIC : the history, corruption, and future of the language“. Reading it now, it seems to be a sour-grapes rant against “street BASIC” dialects taking over. But never fear, Messrs. K&K were releasing TrueBASIC that was sure to put those street ruffians to rights. While TrueBASIC soldiered on as a product until the 2020s, it never left a legacy. The two Dartmouth professors’ grip on the language had strangled BASIC and left it as a quaint but inert toy.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *