[comp.lang.prolog] End-of-file handling

bd@zyx.UUCP (Bjorn Danielsson) (03/24/88)

I can't understand why there should be a "strait-jacket solution" to this
kind of problem. Why not put in enough flexibility to allow for the most
obvious cases? In Z-Prolog, (which was never designed to be Edinburgh
compatible) the "read" predicate can handle end-of-file in three different
ways, depending on an optional argument:

	(1) signal an error,
	(2) fail,
	(3) return a value supplied by the programmer.

The default action is to signal an error.
This solution, or something like it, could easily be adopted for Edinburgh
Prolog as well, only the default there should probably be returning
'end_of_file' to ensure backward compatibility.

End-of-file handling is much less problematic for character input, since
there it is possible to have an end-of-file value (like -1) which can never
be mistaken for legal input.

-- 
Bjorn Danielsson, ZYX Sweden AB, +46 (8) 665 32 05, bd@zyx.SE

ok@quintus.UUCP (Richard A. O'Keefe) (03/26/88)

In article <2403@zyx.UUCP>, bd@zyx.UUCP (Bjorn Danielsson) writes:
> I can't understand why there should be a "strait-jacket solution" to this
> kind of problem. Why not put in enough flexibility to allow for the most
> obvious cases? In Z-Prolog, (which was never designed to be Edinburgh
> compatible) the "read" predicate can handle end-of-file in three different
> ways, depending on an optional argument:
> 	(1) signal an error,
> 	(2) fail,
> 	(3) return a value supplied by the programmer.
> 
Oh, __HOW__ I wish you were were handling the I/O part of BSI substandard!
That's EXACTLY the right sort of attitude for a standard designer.

I think that there are sound technical reasons for regarding fail-at-end
as a straight-out blunder, and I have used PL/I and Fortran enough to
convince me that end-of-file is NOT an error and shouldn't be treated
like one.  (Reading *past* end-of-file is another matter, which is one of
the things I have against fail-at-end.)  But a more powerful operation,
which is not perceptibly harder to implement, which will let me synthesise
the operation I want, and let BIM synthesize the operation they want,
that's exactly the right thing to do in the standard.

Oddly enough, I had intended to mention Algol 68.  Files in Algol 68 are
rather interesting.  One of the things you can do is say

	FILE example file;
	...
	logical file ended OF example file :=
	    (FILE file parameter) BOOL: (
		# return FALSE to get default action (e.g. error report) #
		# return TRUE to say "corrected, please try again" #
		# or jump out #
	    );

Interlisp does the same sort of thing:

	(WHENCLOSE file 'EOF (FUNCTION (LAMBDA (file) (* action *)) ))

So even if we decide to feed this goose instead of killing it, there are
at least three options:
   1.	specify in each call what action to take on end of file
	read(Stream, Term, EofAction)
	-- This affects 'read' only.

   2.	specify per stream what action to take on end of file
	eof_action(Stream, EofAction)
	-- This could affect any form of input.

   3.	allow both.

One of the constraints which is of interest to Quintus is that whatever the
end of file action is, it has to make sense if the stream was being used by
C or Lisp code.  The nice thing about sticking with -1 as the character
end-of-file mark and adopting option 3 is that it does this.

Note though that as I mentioned in my previous message, just because the
host operating system indicates an end-of-file condition doesn't mean that
it isn't possible to read any more from the file.  (UNIX fans will know
about 'tail -f' and why it is useful...)  The standard should, I said in
'84, include a predicate for testing whether the stream is really ended.
If the stream is not really ended, it should be possible to resume reading.