FOCAL (programming language)
FOCAL (acronym for Formulating On-line Calculations in Algebraic Language,[1] or FOrmula CALculator[2]) is an interactive interpreted programming language based on JOSS and mostly used on Digital Equipment Corporation (DEC) PDP series machines. JOSS was designed to be a simple language to allow programs to be easily written by non-programmers. FOCAL is very similar to JOSS in the commands it supports and the general syntax of the language. It differs in that many of JOSS' advanced features like ranges and user-defined functions were removed to simplify the parser. Some of the reserved words (keywords) were renamed so that they all start with a unique first letter. This allows users to type in programs using one-character statements, further reducing memory needs. This was an important consideration on the PDP-8, which was often limited to a few kilobytes (KB). Like JOSS, and later BASICs, FOCAL on the PDP-8 was a complete environment that included a line editor, an interpreter, and input/output routines. The package as a whole was named FOCAL-8, which also ran on the PDP-5 and PDP-12. When ported to the PDP-11, the resulting FOCAL-11 relied on the underlying operating system, RT-11, to provide file support and editing. The language definition was updated twice, to FOCAL-69 and a very slightly modified FOCAL-71. A port to the Intel 8080 was also available. FOCAL is notable as the language in which the original versions of the early video games Hamurabi and Lunar Lander were written. Both were later ported to BASIC, where they became much better known.[3] FOCAL was not popular outside the PDP platform and largely disappeared during the move to the VAX-11. It had a strong revival in the Soviet Union where PDP-11 clones were used as educational and home computers (BK series). HistoryJOSSJOSS was released in May 1963 on the one-off JOHNNIAC computer at RAND Corporation. In RAND, use grew rapidly, and the machine, originally built in 1953, quickly ran out of capability. JOHNNIAC was decommissioned in 1966 and JOSS was reimplemented on a newly purchased PDP-6, Digital Equipment Corporation's (DEC) first "big" machine. Use continued to grow and by 1970, the system was being used by 500 to 600 users across the country and had spawned several innovations such as mobile computer terminals that could be wheeled from room to room and plugged in for quick access.[4] JOSS was highly influential. It emerged just as time-sharing was being introduced. There was significant interest in man-machine interaction and computers were seeing wider use. Whereas most time-sharing operating systems of the era concentrated on user account and file management, leaving the users to do their own programming, JOSS provided file editing and a programming language in one package. RAND showed the system to a parade of people in the industry.[4] FOCALThe PDP-6 was DEC's first mainframe, and JOSS took full advantage of its power and memory capacity. DEC programmers were interested in JOSS, but most of their machines had nowhere near the power needed to run it. Written by Richard Merrill, FOCAL removed features from JOSS as required in order to be able to run in the much more limited memory space of the PDP-8 and other 12-bit machines in the DEC lineup. To achieve this, a major change was made to reduce the amount of temporary data, or state, needed to parse the statements. One noticeable effect of this decision was that conditionals could only be used for branches, in contrast to JOSS, where conditionals can be applied to any statement. The other noticeable change was to rearrange the keywords so each started with a unique letter. This simplified the parser, which needed to read only the first letter of the command on a line of code, and could then skip forward to the next whitespace character. It would then compare that against an internal list of possible keywords, which was one character per entry. In contrast, JOSS had to continue reading until it had read the entire command word and then compared that against a list containing complete words. Not only did this change save memory in the parser, users could also save memory by typing in only that letter, reducing the size of the source code. The first version of FOCAL was released in 1968 for the PDP-8. An updated version followed the next year, which was later known as FOCAL-69. The system as a whole, regardless of version, was known as FOCAL-8 when it was ported to other machines in the 12-bit series, including the PDP-5 and PDP-12. It was popular as it was highly efficient in memory use, which was often severely limited on these machines to a few kilobytes (KB). The similar FOCAL-11 ran on the PDP-11 under RT-11. Processor Technology also offered a version of 8k FOCAL, complete with Lunar Lander, for the Intel 8080-based Altair 8800 system. This was provided for the copying charge of the tape, while the source code was provided for free with other purchases.[5] BASICWhile FOCAL was becoming popular on DEC machines, BASIC was becoming a more popular alternative on other platforms. By the late 1960s, several companies were making inroads in DEC's minicomputer stronghold, selling similar machines running time-sharing versions of BASIC. Notable among these was the HP 2100 series, running HP Time-Shared BASIC.[6] David H. Ahl had recently joined DEC's PDP-8 Group, just as the company became interested in selling the machine into educational settings. Due to the popularity of BASIC in the education market, especially with the growing library of BASIC programs from the Minnesota Educational Computing Consortium, Ahl found selling the machine with FOCAL was difficult despite its advantages.[6] As he later noted:
Ahl took it upon himself to produce a BASIC system for the platform, hiring a company he later learned was a single programmer in Brooklyn to produce a version for the 4 kWord PDP-8. DEC began selling packaged versions of the PDP-8 with terminals and the BASIC as the "EduSystem" lineup, with larger systems in the series having expanded versions of BASIC, and in some cases, also FOCAL and FORTRAN. Some PDP-11 based EduSystems were also created.[7] Ahl then began porting programs from FOCAL to BASIC, notably The Sumer Game (which he renamed Hamurabi), a version of Lunar Lander, and many smaller FOCAL demos. Combining his ports with submissions from outside programmers, he managed to collect enough material to have DEC publish 101 BASIC Computer Games in 1973. The book was an immediate success and ultimately ran through three printings to 1975.[8][6] By the mid-1970s BASIC was a standard feature of all DEC machines and FOCAL use evaporated.[8] Rebirth in the Soviet UnionThe PDP-11 had been cloned in the Soviet Union in the 1970s for military purposes. In the 1980s, single-chip variations similar to the LSI-11 were produced that gave rise to a series of PDP-11 compatible home computers. Most notable among several models were the Electronika BK series, released in 1985. These were initially supplied with FOCAL on a ROM cartridge,[9] while a BASIC cartridge was an optional add-on. Later models supplied BASIC by default.[10] LanguageThe following description is based on FOCAL-69 as seen in the FOCAL-8 language reference manual.[11] Direct and indirect modesFOCAL followed the JOSS model for interaction via a command line interface. This allowed users to type in commands in "direct mode", which were performed immediately, or to prefix them with a line number, in which case they were added to the program if they were unique, or overrode existing code if the same number had previously been used.[12] The method of operation is similar to BASIC's "immediate mode" vs. "program mode". It contrasts with JOSS, in which all commands, both program and direct, were saved and loaded as part of the user's workspace. This allowed JOSS to have commands without line numbers, which they used for Program statementsEvery line in a FOCAL program must start with a line number. As with JOSS, line numbers are fixed-point numbers consisting of two two-digit integers separated by a period. In FOCAL-8, valid line numbers range from 1.01 through 31.99. When printed out, using The number on the left of the period is known as the "group number". Groups provide some level of code organization that is lacking in languages like Fortran or BASIC. The primary use of these was to use a group as a subroutine which can be called with Every line must start with a command keyword following the line number.[13] There is no concept of a "default command" as is the case in BASIC with its optional CommandsASKThe 01.01 ASK "NAME", NAME 01.02 ASK "COORDINATES", X, Y 01.03 ASK "A1",A1,"OMEGA",W,"T0",T0,"DAMPING FACTOR",DAMPINGFACTOR If the user doesn't enter a number but enters text, the system will convert the initial character to a number with "A"=1, "B"=2, etc. COMMENTThe 01.01 COMMENT: THE SUMER GAME, BY RICHARD MERRILL DOThe 01.15 DO 7.24 01.16 DO 8 FORThe In contrast to other parts of the language where multiple statements on a line are independent, the 01.01 FOR X=1,10; TYPE X,! 01.02 FOR X=0,10,100; DO 2 A sample FOR loop: 01.10 ASK "HOW MUCH MONEY DO YOU WANT TO BORROW ?",PRINCIPAL 01.20 ASK "FOR HOW MANY YEARS ?",TERM 01.30 FOR RATE=4.0,.5,10;DO 2.0 01.40 QUIT 02.10 SET INTEREST=PRINCIPAL*(RATE/100)*TERM 02.20 TYPE "RATE",RATE," ","INTEREST",INTEREST,! GOTOThe 01.05 GOTO 1.01 02.90 TYPE !!,"TRY AGAIN.",!!!!!;GOTO 1.1 IFThe 02.20 IF (25-25) 2.4,2.3,2.4 03.01 IF (X) 3.1,3.02,3.1 IF could be short-formed by placing a semicolon (or end of line) beyond the first line number. For example: 02.20 IF (X)1.8; TYPE "Q" 02.30 IF (X)1.8,2.50 02.40 TYPE "P" In this case the test at 2.20 will cause the program to jump to line 1.8 if the test is negative, otherwise it will continue and type "Q" to the console. Line 2.30 will jump to 1.8 or 2.5 if the value is negative or zero, and otherwise continue to type "P" to the console.[19] QUITThe 01.10 FOR X=-10,1,10;TYPE X 01.20 QUIT RETURNThe 22.78 COMMENT: 'YES OR NO' SUBROUTINE 22.80 ASK "ANSWER YES OR NO ? ",AN 22.82 IF (AN-0YES)22.84,22.86 22.84 IF (AN-0NO)22.8,22.88,22.8 22.86 SET X=2;RETURN 22.88 SET X=1;RETURN SETThe 01.30 SET PI=3.14156 01.60 SET INTEREST=PRINCIPAL*(RATE/100)*TERM TYPEThe Items can be variables, literal strings surrounded by double-quotes, or a variety of control characters. The control characters include the TYPE [NUMBERS, E1, "TEXT", !, #, :, $ OR %] ...OUTPUT 01.10 TYPE "HI THERE, GOOD LOOKING. HOW MUCH MONEY DO YOU WANT TO BORROW?",! 01.50 TYPE "INTEREST",INTEREST,! 01.80 TYPE "THE INTEREST FOR",TERM," YEARS",!,"IS",INTEREST, " DOLLARS.",!! 01.90 TYPE "NEW YORK",!,"WASHINGTON",!,"ATLANTA",!,"DALLAS",! 02.10 TYPE "X",X," ","X^2",X^2," ","SQRT",FSQT(X) 03.20 TYPE ".",# 02.20 TYPE !!!!!
SET A=67823 TYPE %6.01,A = 67823.0 TYPE %5,A = 67823 TYPE %8.03,A = 67823.000 TYPE %,A = 6.7823E4 Note the extra leading spaces in some examples, padding out the full defined width. Using % alone caused the output to be printed in "floating point format" using the E.[23] A special control character was TYPE $ A0(00)=67823 VariablesVariable names may start with any letter except F (F is reserved for functions) and may contain any sequence of letters and numbers. However, only the first two characters are significant. For example, the following code sample from FOCAL: A New Conversational Language[25] refers to the same variable as DESTINATION and then DES. Internally, both references refer to a variable designated DE: 01.80 ASK DESTINATION 02.30 IF (DES-14) 2.4,3.1,2.4 Any variable may be treated as an array, allowing subscripts from -2048 through 2047.[2] MathFOCAL contained five mathematical operators:[26]
One curiosity of the 1968 version of FOCAL was that the operators had independent precedence, as in the order above. Although this certainly applies to exponentiation, multiplication, and division, there is some ambiguity in the 1968 FOCAL manual with regards to addition and subtraction. Specifically, examples that demonstrate operator precedence for multiplication and division are provided, but examples demonstrating operator precedence for addition and subtraction are lacking. Nevertheless, the literal interpretation of the 1968 FOCAL manual suggests that the formula However, the + and - have the same precedence in FOCAL-69 and FOCAL-71, so FOCAL was unusual in that mathematical expressions could use (), [], and <> interchangeably in matched pairs to establish precedence.[26] For example, the following is a valid expression: 01.30 SET A=<10*[5+1]*(1+5)> All of these are the same level of precedence and read left-to-right when at the same level, so this statement will be evaluated [], then (), then <>, to produce 360.[26] The language contained the following built-in functions:[27]
Character functionsFOCAL-71 added two new functions for inputting single-character values, similar to ASK but returning ASCII values.
Other functionsFOCAL also included several special-purpose functions:[28]
Environment commandsRunning programsFOCAL used Editing commandsNew lines are entered into a program by simply starting the command with a line number. The editing commands were
File commandsThe file command was OPEN (abbreviation O):
Library commandsFOCAL included the ability to manage collections of FOCAL programs as a code library. Programs could call other programs in a chain fashion using
FOCAL-71 added:
Error codesSince the interpreter lacked sufficient memory space to store error messages, or even a table of error numbers, FOCAL used a workaround by reporting the address of the error-detecting code as a fixed-point number. For example, the division by zero error was detected it would report Changes between versionsDEC released three versions of FOCAL for the PDP-8 series, the original, known simply as FOCAL, and two updated versions, FOCAL,1969 and FOCAL,1971. FOCAL,1969 was largely identical to the original, but FOCAL,1971 was major update that added file handling, new mathematics, and a variety of other changes. In contrast to the first two versions, which were stand-alone systems, FOCAL,1971 was based on the emerging OS/8 (then still known as PS/8) and relied more heavily on that operating system for file handling and editing. FOCAL,1971One change in the new version was a 10-digit math package for added precision. The As all of these options used up limited memory, when started, FOCAL,1971 entered a dialog that asked the user what features they wanted to use. Comparison with JOSSFOCAL is, for all intents, a cleaned-up version of JOSS with changes to make the syntax terser and easier to parse. Almost all FOCAL commands have a one-to-one correspondence with JOSS and differ only in details. The most obvious change at first glance is that JOSS is case-insensitive and outputs keywords in mixed-case whereas FOCAL was upper-case only. Additionally, JOSS statements end with a period, making them look like written statements, whereas FOCAL has no required line-ending. One major difference is that JOSS included a complete set of comparison operations and a boolean logic system that operated within 1.10 Type A if X>10. 1.20 Type i for i=1(1)10. The first line optionally prints A based on the value of X, and the second prints the numbers 1 to 10. In contrast, FOCAL lacked the ability to compare values, and loops were applied by skipping to the next line when they completed. The equivalent code in FOCAL would be: 1.10 IF (X-10),,1.30 1.20 TYPE A! 1.30 FOR I=1,1,10;TYPE I,! JOSS' implementation makes common constructs easier to build and more closely match a programmer's intentions, at the cost of making the runtime more complex. For example, JOSS allowed ranges in loops to be described in a flexible fashion like 1,2,3,10(5)50,75,78. This flexibility comes at a cost; in FOCAL the start, stop, and step can be written in a custom in-memory structure and easily updated as the loop is performed, whereas JOSS requires it to reevaluate an expression that may be, but often isn't, more complex. In order to make the code terser in FOCAL, changes were relatively minor. For example, JOSS' To simplify the parser, some JOSS constructs were removed. For example, JOSS could perform multiple assignments with Comparison with BASICComparisons between FOCAL and BASIC were inevitable since both languages were common on minicomputers of the same era, and the two languages have much in common in syntax and structure. In most cases, there is a direct conversion of FOCAL code to and from BASIC. For example, to ask a user to input a value, in FOCAL one would: ASK "What is your age?",AGE while in BASIC the equivalent is: INPUT "What is your age?",AGE
With the exception of a few features that were missing from one or the other, and some relatively minor differences in syntax, the two languages are very similar. One notable exception is the Another major difference between the two is that FOCAL lacked inherent support for strings as data elements that could be assigned to variables. As was the case in early BASICs or FORTRAN versions before the addition of strings (in F77), this limitation was generally avoided through the use of literal strings in input and output commands. It was only when manipulating individual strings, or characters in them, that this became a significant problem. As string variables were not supported, inputting a string used a kludge that converted any characters typed in by a user to their numeric character value. For example, if one typed HELLO at an input statement, FOCAL would convert the H to "8", the numeric value of "H" in the PDP-8's six-bit character codes ("H" is the eighth letter). It would then interpret the "E" as starting an exponent, then it would try to compute "8" to the "LLO" power, which would take several seconds of CPU time and result in a value of 0.76593020E+103, not a helpful response. Nevertheless, by asking questions that would be responded to using single-letter responses, like "Do you need instructions, Y or N", programmers could test the result against known character values to produce what looked like character input. Prepending a zero to a string would coerce it to numeric, so programs could test for specific multicharacter strings using IF statements such as FOCAL's PDP-8 implementation used a floating point representation that represented numbers as four 12-bit words, forty-eight bits in total, with thirty-six bits of mantissa and twelve bits of exponent. This allowed for both significantly higher precision and a significantly wider range of values than most contemporary interpreters, making FOCAL a reasonable choice for serious numerical work. This high precision, and good choices for default decimal output formatting, meant that difficulties with binary-to-decimal rounding were not evident to beginning users. For comparison, Microsoft BASIC initially used a 32-bit format, while later versions expanded this to 40-bits. Most BASICs had problems with rounding that led to simple equations resulting in tiny non-zero remainders. It is generally agreed that FOCAL was more efficient in its use of resources than comparable BASIC systems. On a typical machine of the day, often with 6 to 24 kilobytes of magnetic-core memory, FOCAL could handle larger and more complex programming tasks than BASIC. Versions and spinoffsThe Coca-Cola Corporation used a customized version of FOCAL called COKE.[citation needed] FOCAL was later implemented on the PDP-7, PDP-9, PDP-10, PDP-11, PDP-12, PDP-5 and LINC-8. The FOCAL manual showed how to add commands to the FOCAL parser, so many sites added specialized commands for operating custom hardware. The Digital Equipment Computer Users' Society collected many patches and enhancements for FOCAL. There were even major enhanced offshoots of FOCAL, such as FOCAL-W, which added many features, including better mass storage file I/O and even virtual variable memory. In the mid-1970s DELTA was a more sophisticated version of FOCAL. Program line numbers went from 00 to 99 "parts" and 000000 to 999999 "steps" executed in alphanumeric order. DELTA had some specialized commands for the Tektronix 4010/14 display scope. In Russia, it saw use as late as the early 1990s in mass-produced home computers of the Electronika BK series. Microsoft sold a version of FOCAL supplied on paper-tape.[30] According to Raymond Chen, the master tape is missing and FOCAL is no longer available. Example codeThe original Lunar Lander makes an excellent example for examining FOCAL code, as it uses most of the features of the language. This code is from the original, found on Jim Storer's Lunar Lander page.[31] 01.04 T "CONTROL CALLING LUNAR MODULE. MANUAL CONTROL IS NECESSARY"! 01.06 T "YOU MAY RESET FUEL RATE K EACH 10 SECS TO 0 OR ANY VALUE"! 01.08 T "BETWEEN 8 & 200 LBS/SEC. YOU'VE 16000 LBS FUEL. ESTIMATED"! 01.11 T "FREE FALL IMPACT TIME-120 SECS. CAPSULE WEIGHT-32500 LBS"! 01.20 T "FIRST RADAR CHECK COMING UP"!!!;E 01.30 T "COMMENCE LANDING PROCEDURE"!"TIME,SECS ALTITUDE," 01.40 T "MILES+FEET VELOCITY,MPH FUEL,LBS FUEL RATE"! 01.50 S A=120;S V=1;S M=32500;S N=16500;S G=.001;S Z=1.8 02.10 T " ",%3,L," ",FITR(A)," ",%4,5280*(A-FITR(A)) 02.20 T %6.02," ",3600*V," ",%6.01,M-N," K=";A K;S T=10 02.70 T %7.02;I (200-K)2.72;I (8-K)3.1,3.1;I (K)2.72,3.1 02.72 T "NOT POSSIBLE";F X=1,51;T "." 02.73 T "K=";A K;G 2.7 03.10 I (M-N-.001)4.1;I (T-.001)2.1;S S=T 03.40 I ((N+S*K)-M)3.5,3.5;S S=(M-N)/K 03.50 D 9;I (I)7.1,7.1;I (V)3.8,3.8;I (J)8.1 03.80 D 6;G 3.1 04.10 T "FUEL OUT AT",L," SECS"! 04.40 S S=(FSQT(V*V+2*A*G)-V)/G;S V=V+G*S;S L=L+S 05.10 T "ON THE MOON AT",L," SECS"!;S W=3600*V 05.20 T "IMPACT VELOCITY OF",W,"M.P.H."!,"FUEL LEFT:"M-N," LBS"! 05.40 I (1-W)5.5,5.5;T "PERFECT LANDING !-(LUCKY)"!;G 5.9 05.50 I (10-W)5.6,5.6;T "GOOD LANDING-(COULD BE BETTER)"!;G 5.9 05.60 I (22-W)5.7,5.7;T "CONGRATULATIONS ON A POOR LANDING"!;G 5.9 05.70 I (40-W)5.81,5.81;T "CRAFT DAMAGE. GOOD LUCK"!;G 5.9 05.81 I (60-W)5.82,5.82;T "CRASH LANDING-YOU'VE 5 HRS OXYGEN"!;G 5.9 05.82 T "SORRY,BUT THERE WERE NO SURVIVORS-YOU BLEW IT!"!"IN " 05.83 T "FACT YOU BLASTED A NEW LUNAR CRATER",W*.277777," FT.DEEP." 05.90 T !!!!"TRY AGAIN?"! 05.92 A "(ANS. YES OR NO)"P;I (P-0NO)5.94,5.98 05.94 I (P-0YES)5.92,1.2,5.92 05.98 T "CONTROL OUT"!!!;Q 06.10 S L=L+S;S T=T-S;S M=M-S*K;S A=I;S V=J 07.10 I (S-.005)5.1;S S=2*A/(V+FSQT(V*V+2*A*(G-Z*K/M))) 07.30 D 9;D 6;G 7.1 08.10 S W=(1-M*G/(Z*K))/2;S S=M*V/(Z*K*(W+FSQT(W*W+V/Z)))+.05;D 9 08.30 I (I)7.1,7.1;D 6;I (-J)3.1,3.1;I (V)3.1,3.1,8.1 09.10 S Q=S*K/M;S J=V+G*S+Z*(-Q-Q^2/2-Q^3/3-Q^4/4-Q^5/5) 09.40 S I=A-G*S*S/2-V*S+Z*S*(Q/2+Q^2/6+Q^3/12+Q^4/20+Q^5/30) The program is cleanly separated into many subroutines. This was almost universal in FOCAL programs (and JOSS), as the line number scheme made such constructs easy to use. This program uses nine routines. The first, group 1, simply prints out the instructions using the The main game loop is driven by group 2. As the code "falls" through group 1 into group 2 during the first run, the initial values are printed out in the first two lines. Near the end of line 02.20, the user is Group 3 first tests to see if the fuel has run out, and jumps to group 4 if it has. Then it tests if the 10-second period in When the 10-second timer runs out, or it reaches the end due to the fuel test in line 03.10 or the altitude test in 07.10. In the latter cases, it will jump to group 4 and fall through to group 5, or jump to group 5 directly. Group 5 types the end-of-game results and then asks the user if they'd like to try again. If so, it jumps to 01.20 to clear out all values and print the headers again, if not if falls through to 05.98 and See also
References
Bibliography
External links
|