[net.lang.prolog] What Should Rename Do ?

OKeefe.R.A%EDXA@sri-unix.UUCP (11/02/83)

From:  Richard HPS (on ERCC DEC-10) <OKeefe.R.A at EDXA>

What should rename do ?

     To start with, I find rename(X,[]) as a way of deleting a file
"cute" rather than clear.  It is quite awkward, in fact, on UNIX,
where "[]" is a perfectly good file name.  I don't think we'd be
doing Prolog any great harm if we split this into two:

        rename(Old, New)        - Old and New can be ANY object which
        delete(Old)             - name/2 accepts as first argument.

"2" and "3.456" are perfectly good file names in UNIX and Bottoms-10.

     That's not the problem.  The problem is what should happen to
Old if it is open ?  In fact DEC-10 Prolog *insists* that Old should
be open, and closes it.  The result is that if you had something like

        p :-
                see(fred),
                q,
                ...
        q :-
                ...
                delete(fred)
                ...
        delete(File) :-
                seeing(Old),
                see(File),
                rename(File, []),
                see(Old).

the second see/1 in delete/1 will try to reopen fred, and of course
won't find it.  And the fact that rename/2 will set the input to
'user' is not obvious.

     C-Prolog does not require that the old file be open.  It just
goes ahead and does the rename.  This has the extremely odd result
that
        seeing(Current),
        rename(Current, gotcha),
        seeing(Input),          %  succeeds bindind Input=Current
        see(Input)              %  fails!

     It would be possible for C-Prolog to change the name of the
file in its own tables, so that seeing(Input) would bind Input=gotcha
and see(gotcha) would then be a no-op.  Version 1.4a.EdAI may well do
that.  The trouble is that the user's program might still be hanging
on to the old atom, as for example

        input_redirected(File, Command) :-
                exists(File),
                seeing(Old),
                see(File),
                (   call(Command), !, seen, see(Old)
                ;   seen, see(Old), fail
                ).

How could the file module be expected to know that Old should be
changed when someone else renames it ?

     There is also something we might call the "close problem".  If
you have a program which is reading from some file, and you enter the
debugger, i/o in the debugger will be redirected to the terminal.
There is nothing then to stop you entering a break (in the DEC-10
debugger you don't even have to do that) and giving the command
close(X), where X just happens to be the file the program is reading
from...  This used to crash C-Prolog.  1.4.EdAI and 1.4.SRI solve
this problem (using different code) by rejecting an attempt to close
a file that is open in a lower break state.  I haven't dared to try
it in DEC-10 Prolog, but I would expect that the result would be for
the broken code to reopen the file from the beginning.  Ugly.

     The input-output system of DEC-10 Prolog was designed using the
principle "whatever helps the user is good".  That is, nothing was
put in until there was a need for it, and then the simplest approach
that seemed to work was adopted.  Unfortunately, PDP-11 Prolog, EMAS
Prolog, and C-Prolog have copied this "ad hack" solution in the name
of "compatibility".  The Prolog component of PopLog has library code
to mimic this behaviour as well though it also has access to Pop11's
rather cleaner i/o.

     Can we call a halt to this ?  It seems clear that representing
files by their names is a mistake.  We cannot in DEC-10 Prolog have
two pointers into the same file !  Streams of some sort have far
fewer problems.  In particular they don't have the rename problem
or the close problem.  Suggestions ?