info-mac@uw-beaver (info-mac) (11/30/84)
From: Stuart Reges <REGES@SU-SCORE.ARPA> I'm not sure anyone is interested in these messages I have posted about MacPascal, but I will charge on anyway. I'm one of those people who digs for all the details and I've also seen a lot of Pascal systems, so I think I'm in a good position to write these critiques. As you all probably know, terminal I/O varies quite a bit from Pascal to Pascal. The question for terminal output is usually: o When is the text of a WRITE or WRITELN sent to the terminal? There are two popular schemes: o Everytime a WRITELN is executed. o Everytime either a WRITE or WRITELN is executed. MacPascal uses the second of these, which is the right way to go. Terminal input is not quite so simple. Most schemes can be distinguished by answering the following questions: o When does the computer pause for input? o How much input does the computer expect when it pauses? Old-style Pascal systems were usually of the form: o The computer pauses whenever the input buffer is empty. o An entire line of input is read. This leads to problems because when the program starts executing the input buffer will be empty and the user will be expected to type input when he hasn't been prompted for it. MacPascal uses what is called lazy I/O. Probably a better term would be procrastinating I/O. In lazy I/O the computer delays obtaining input until it actually needs it (i.e., the input buffer can be empty as long as we aren't using it). The computer needs something in the input buffer whenever there is a reference to INPUT, INPUT^, READ, READLN, GET, EOLN or EOF. The answers in MacPascal, then, are: o The computer pauses when it needs to. o A single character is read. I think that using lazy I/O is definitely the right way to go, but I think it was a mistake to choose character-by-character I/O. This makes it difficult to read character-by-character, as in: program Fun (input, output); var str: array [1..20] of char; len: integer; begin write ('prompt>'); len := 0; while not eoln do begin len := len + 1; read (str [len]); end; writeln ('Length = ', len); end. This program runs into trouble if the user tries to type something and then uses the delete key to correct his input. Consider the following scenario: o User types "hi there" o User types backspaces to delete the word "there" o User types the word "ho" instead You would want the array to contain "hi ho" but it will instead contain the word "there" and the backspaces between "hi" and "ho". Systems that do line-by-line I/O usually take care of these problems automatically, so that the programmer doesn't have to worry about processing backspace characters. You can do line-by-line reading in MacPascal if you use the built-in STRING type, but that's not standard Pascal. This is yet another example where we find that MacPascal works well if you use the neat extensions that have been provided but doesn't work well if you program the way you normally would in standard Pascal. That's a big problem for me because in my course students are using different machines. Most of the students are using the University's DEC-20s, but some students in the class have their own Macintoshes and are using MacPascal. I also have TV students all over the country who are using all kinds of computers. I always teach standard Pascal and encourage my students to stick to the standard as much as possible. MacPascal terminal input has another odd characteristic. In order to distinguish it from other Pascal systems you need to look at one more question: o When are the characters typed by the user echoed to the terminal? Usually the answer is "immediately." In MacPascal, however, the answer is: o When the characters are actually read. The following program illustrates the difference: program Fun (input, output); var ch: char; begin write ('prompt>'); while not eoln do begin write ('!'); read (ch); write (ch); end; write ('*'); readln; writeln ('done'); end. The program first pauses for input when it hits the EOLN test. It doesn't echo the character at that point, though. It instead waits until it executes the READ statement. We also get the asterisk written out before the carriage return typed by the user is echoed. A typical execution yields something like this: prompt>!ww!ee!ii!rr!dd* done If characters were echoed immediately we instead get: prompt>w!we!ei!ir!rd!d *done Echoing immediately is much more intuitive. This weird behavior of MacPascal makes it harder to explain terminal input conventions and I don't believe it really gains us anything. Most Pascal systems have really terrible terminal I/O, so I'm not being overly critical of MacPascal here. Think Technologies should be congratulated on getting something that works fairly well and that follows the standard. I think that it would be more useful, however, if the questions were answered as follows: o Empty output buffer on every WRITE/WRITELN. o Pause for input only when you need it. o Pause for an entire line of input when you pause. o Echo characters immediately after they are typed. (MacPascal has the first two of these right.) -------
info-mac@uw-beaver (info-mac) (12/04/84)
From: ihnp4!utzoo!henry@uw-beaver.arpa Sounds like the Mac is all set to stumble over something that the Unix community learned long ago: if you want line editing (e.g., backspacing over typos) to work uniformly across all programs, it must be centralized. Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry