What was included and what wasn’t in the very first version of BASIC might surprise you. First of all, Dartmouth was waiting for the time-sharing system equipment from GE to arrive, but in the meantime Kemeny and Kurtz decided to write a compiler for BASIC, to have it ready once when implementation of the time-sharing system began.
While the two had designed BASIC to be an interactive language, with the goal of removing students from the tyranny of interacting with computers through batch processing of punch cards, the two still envisioned computing through a punch-card paradigm.
Before the time-sharing environment was ready, the card-operated version of the BASIC language went live, CARDBASIC, permitting one line per card. Because of differences between the teletype and the keypunch, PRINT used a single quote ‘ instead of a double quote “, and the relational operators were EQU, LSS, GRT, LQU, GQU, and NQU instead of =, <, >, <=, >=, and <> respectively. The soon-to-be-removed PAGE instruction started a new printed page. And the famous MAT instructions offered students using the language access to matrix math: MAT READ A(M,N) instead of a FOR-loop, MAT PRINT A, MAT C=A+B and so on, including matrix functions CON, IDN, INV, TRN, and ZER. (MAT functions weren’t available in the timeshared BASIC.)
While later iterations of BASIC would include file input and output, the first Dartmouth BASIC instead had READ and DATA commands, even with the interactive version. Like a program typed on punch cards, the data would be included with the program stored in the time-sharing system. Here’s the very first example program from the BASIC manual for the second version of BASIC (October, 1964; page 3):
10 READ A1, A2, A3, A$
15 LET D = A1 * A4 – A3 * A2
20 IF D = 0 THEN 65
30 READ B1, B2
37 LET X1 = (B1*A4 – B2*A2) / D
42 LET X2 = (A1*B2 – A3*B1) / D
55 PRINT X1, X2
60 GO TO 30
65 PRINT “NO UNIQUE SOLUTION”
70 DATA 1, 2, 4
80 DATA 2, -7, 5
85 DATA 1, 3, 4, -7
In fact, as its card-based pilot implementation did, the first interactive version of BASIC lacked an INPUT command. The only way to tailor data was either to hardcode it in variable LET assignments or to use the READ/DATA capability. While BASIC was meant to let you run commands and see the results immediately, there was no way to write a program that would accept input from the user. (There was no INKEY$ command either, as there were no string variables.) Kemeny and Kurtz thought it was too difficult to implement an input statement in a time-sharing system and instead wanted to provide quick execution of small programs. (Within two years, BASIC would have an INPUT command.) [See Back to BASIC, page 25.]
Here’s the first version of the language, from Appendix C:
LET <variable> = <expression>
READ <variable>, <variable>, …, <variable>
DATA <number>, <number>, …, <number>
PRINT <label>, | <label><expression>, | <expression>
GOTO <line number>
IF <expression> <relational> <expression> THEN <line number>
FOR <unsubscripted variable> = <expression> TO <expression> [STEP <expression>]
NEXT <unsubscripted variable>
DEF FN <letter>(<unsubscripted variable>) = <expression>
GOSUB <line number>
DIM <letter>(<integer>), | <letter>(<integer>,<integer>),
REM <any string of characters whatsoever>
Note that only a line number could follow a THEN in an IF statement (not other statements, like later IF … THEN PRINT X: GOTO 10). Also, only IF statements could have expressions with relational operators: LET F = A<10 wasn’t allowed. Variable names could be a letter or a letter followed by a digit, mainly to make it simpler to develop the compiler. (Array names, for the same reason, were a single letter.) Note that PRINT didn’t require a delimiter between a literal string (called a “label”) and a following expression: e.g. PRINT “SINE ” SIN(X). PRINT did allow the suppression of the carriage return by using a trailing comma (PRINT I,) though it instead advanced the cursor to the next print zone.
Arithmetic used nine digits of precision for integers and supported floating-point operations: the operators were + – * / ^. Moreover, the first BASIC had a rich library of functions: ABS, ATN, COS, EXP, INT, LOG, RND, SIN, SQR, and TAN. RND ignored its argument and generated a reproducible sequence of random numbers one at a time from 0 to 1 (the same numbers would occur in every program run). Programmers could even define their own single-line functions, FNA through FNZ, but the parameter passed in overrode it’s corresponding variable; e.g., DEF FNL(X) = LOG(X)/LOG(10) would assign the passed-in parameter to X! In other words, all variables were global, and functions had the side effect of changing the value of a global variable.
Once the time-sharing system went live, command-line instructions were added. Though often considered part of BASIC, these were part of the system in general and included HELLO (to start the user-login procedure), NEW (to create a new program and name it), OLD (to load an old program), SCRATCH (to erase the program but keep the name), RENAME, CATALOG, SAVE, UNSAVE, and LIST (including LIST–70 to list from line 70 on, for example).
The implementation also had two pages of verbose (by later microcomputer standards) error messages, from “ILLEGAL FORMULA” to “END IS NOT LAST”, but strangely no divide-by-zero message. (Microcomputer BASICs would have two-letter error codes or error numbers or, in the case of Palo Alto Tiny BASIC, just three messages: “How?”, “What?”, and “Sorry.”)
The first version of BASIC was intended as an alternative to FORTAN and ALGOL for students, and it was larger and more powerful than the first generation of Tiny BASICs for microcomputers, which would follow 12 years later.