[net.lang.prolog] Purity, Rplaca, and Retract.

OKeefe.R.A%EDXA@sri-unix.UUCP (10/22/83)

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

     I really do wonder to what extent "rplaca" is USER-oriented
feature.  If you want a structure with replaceable parts, you can
put atoms in at key points and set their top-level value.  I've
known rplaca cause gross problems to novices.  One, for example,
wrote a function something like

        (defun pick (L fn)
            (prog (x)
                (setq x '(nil))
                ... when an element is found
                ... (tconc (car L) x) ...
                (return (cdr x))
            )
        )

When I pointed out that all instances of x were going to get the
SAME list structure, and that he was going to get longer and longer
lists, he just couldn't believe it.  He ran the function, and still
couldn't believe it.  After I'd drawn a few boxes and waved my hands
for a bit, he managed to believe it, but it still didn't make sense
to him.  Now of course there are functions that package up this whole
operation, in InterLisp it's (subset L fn), and THAT is user-oriented.

     Similarly, setof, bagof, update are user-oriented in a way that
assert and retract are not.  A "feature" can only be called
"user-oriented" if it helps people write correct programs, and to
do that people must understand it.  I have very strong evidence that
assert and retract are hard to understand.  Fernando Pereira cited
the fact that it can be very convenient to use asserta/assertz &
retract to implement a stack/queue, and gave a particular example.
But the Prolog-X system, designed by Bill Clocksin and Lawrence Byrd
(two people who should understand Prolog if anyone does) includes an
optimisation -- one which can produce ca 5-10% savings -- which
stops that example working.  (In some but not all cases, and
debugging would disable the optimisation...)

     I know how to implement assert and retract, and if I think hard
about it for a while I can usually spot the consequences of an
implementation.  However, I have NO non-implementational understanding
of assert and retract which lets me decide whether another approach
is "correct".  [This is not the case with rplaca/rplacd.  You can
prove that the "invisible pointers" approach is correct.]  What I
am looking for, and want to encourage other people to look for, is

        operations which are currently coded using assert and
        retract, but whose meaning is clear, and which may be
        implementable directly.

setof, bagof, update, and assuming are operations of this sort.
It is quite straightforward to explain what they mean, and they
can be implemented more efficiently without using the database.
[sorry, without using assert/retract]  Assert and retract introduce
very strong coupling between remote parts of the program, it is easy
to understand how that happens, but it is not easy to understand the
consequences.

     Maybe the answer is to reintroduce the distinction between
data and code, just as for example OPS5 distinguishes between tokens
in working memory and rules.

     I have been using Prolog for 4 years.  It was three years before
I felt confident about hacking the data base, and I still hate doing
it because I know how slow it is and how unlikely I am to get it
right first time.  My search for a replacement is not a search for
"purity".  It is a search for a language I can USE.

     [The mixed language approach, such as Poplog, doesn't solve
this problem.  You can indeed move all the data base hacking into
pop11, but then you have to master TWO languages AND their
interaction.  The problem gets bigger.]