🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #3188

Re: behavior of read/get0 at end_of_file

#3188
From: Lee Naish
Date: Wed, 30 Mar 1988 07:34
100 lines
4187 bytes
In article <243@gould.doc.ic.ac.uk> cdsm@doc.ic.ac.uk (Chris Moss) writes:
>e.g.  go :- repeat,
>	    read(Term),
>            (Term=end_of_file -> true; process(Term), fail).
>
Testing for the end of file term using = is a common error.  If a
variable is read, it succeeds.
A second criticism I would make of this code is that it has a tendency
to loop.  I think that repeat/0 should also have a matching cut.

I posted a nicer way to encapsulate this backtracking style of reading
terms a while back.  It is also possible to move the read back into the
repeat loop, avoiding repeat and the need for cut.  With tro, it is just
as efficient.  Interestingly, it it works whether read fails or succeeds
on eof.

	% returns all terms read by backtracking
	% (should have stream/file arg and close file at eof?)
read_terms(Term) :-
	read(Term1),
	\+ isEof(Term1),	% if you dont want to return end_of_file
	(	Term = Term1
	;
		% \+ isEof(Term1),	% if you do want to
		read_terms(Term)
	).

Richard metioned some subtle differences between eof/1, is_eof/1 etc in
different systems.  There is another one which he missed: in NU-Prolog,
isEof/1 checks if its argument is the eof term (reading variables works)
and eof/1 returns the eof term (which is end_of_file for comatability).

Now for my suggestion of a new predicate which can be used to implement
your favourite version of read/1:

	read_term(Stream, Term)		% change the name if necessary

1) If it succeeds in reading a term T,
		Term = term(T, VarNames)
	where Varnames is some structure which allows mapping between
	variables and their names.  Wrapping a functor around the term
	enables to distinguish between variables, 'end_of_file' and real
	end of file easily.  It also lets us retain variable name
	information.

2) If end of file is encountered for the first time, or if an end of
	file marker occurs next in the stream (like ^Z on a terminal)
		Term = eof_marker

3) If eof has already been read and multiple eof markers are not
	possible
		Term = error(past_eof)
	Whether this is an error is arguable, but by explicitly
	returning something, the programmer has the choice of what
	to do.  Rather than having a proliferation of top level
	functors being returned by read_term, it seems reasonable to
	wrap the error functor around past_eof.

4) If there is a syntax error
		Term = error(syntax(X))
	where X is some indication of the error

5) If Stream is not a valid stream
		Term = error(invalid_stream(X))
	where X is some indication of the error

6) If there has just been a disk head crash
		Term = error(unix(hardware(disk_head_crash(X))))
etc, etc.

Similarly, reading characters could be done as follows

	read_character(Stream, Char)	% change name if necessary

1) If it succeeds in reading a character C,
		Char = C
	where char_to_int(C, I) can map the character to a small integer
	for get0/1.  There is no special functor needed to wrap up Char,
	assuming the other things returned by read_character/2 can be
	distinguished from characters (eg, by is_character(Char)).

2) If end of file is encountered for the first time, or if an end of
	file marker occurs next in the stream (like ^Z on a terminal)
		Char = eof_marker

3) If eof has already been read and multiple eof markers are not
	possible
		Char = error(past_eof)

4) I doubt that there will ever be a need for error(syntax(X)), but
	it should be reserved anyway.

5) If Stream is not a valid stream
		Char = error(invalid_stream(X))
etc, etc.

I think it would be useful for these (with the details fleshed out a bit
more) to be part of the standard.

	lee
Technical Details
Message-ID: <2643@mulga.oz>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!munnari!mulga!lee
References: <608> <1197@kulcs.kulcs.uucp> <783@cresswell.quintus.UUCP> <518@ecrcvax.UUCP> <801@cresswell.quintus.UUCP> <243@gould.doc.ic.ac.uk>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!munnari!mulga!lee
From: lee@mulga.oz (Lee Naish)
Newsgroups: comp.lang.prolog
Subject: Re: behavior of read/get0 at end_of_file
Message-ID: <2643@mulga.oz>
Date: 30 Mar 88 07:34:06 GMT
References: <608> <1197@kulcs.kulcs.uucp> <783@cresswell.quintus.UUCP> <518@ecrcvax.UUCP> <801@cresswell.quintus.UUCP> <243@gould.doc.ic.ac.uk>
Reply-To: lee@mulga.UUCP (Lee Naish)
Organization: Comp Sci, Melbourne Uni, Australia
Lines: 100
Keywords: get0 read end_of_file