[net.lang.prolog] Purity of =..

U-Reddy%UTAH-20@sri-unix.UUCP (11/03/83)

From:  Uday Reddy <U-Reddy@UTAH-20>

Ref: Abbott,  Purity,              Prolog Digest, 1, 40, (20 Oct 83)
     Richard, Reply to My Critics, Prolog Digest, 1, 44, ( 1 Nov 83)

The above references discussed the purity of =.. (UNIV).  My position
is that =.. is not pure in either first-order or higher-order logic,
in the sense that it is "referentially opaque".

In the terminology of logicians, a "name" is used in a referentially
transparent way if its meaning is independent of the context in which
it appears.  In particular, a name that is "used" (to denote some
semantic object) cannot be "mentioned" (to denote the name itself),
in order to preserve referential transparency.

In the context of programming, name means any syntactic object:
identifier, expression, term, clause, program, pointer or what have
you.  We use these syntactic objects to denote semantic objects,
like, values, functions, and relations.  As long as they are used
to denote semantic objects, their syntactic structure cannot be
"referenced" in the program.  Classic cases of violations of this
principle are the use of variables in imperative languages and QUOTE
and EVAL of LISP.

Prolog has several features that violate referential transparency.
Some of them are var, functor, arg, univ and call.  To see why,
consider the simple example

        1 + 2 =.. [+, 1, 2]

Since 1+2 denotes a semantic object (the integer 3) its syntactic
structure should be transparent to the program.  But using =.. allows
the program to look at its syntactic structure.  2+1 denotes the
semantic object as 1+2. But, replacing 1+2 by 2+1 in the above
literal does not preserve its truthful-ness.

Features like =.. can, however, be used in a referentially
transparent way. When a program manipulates syntactic objects without
using them to denote semantic objects, using these features is
perfectly acceptable.  Examples of such programs are compilers and
theorem provers.  It is an interesting exercise to design languages
which allow these features to be used only in a referentially
transparent way.

Arguments of the kind "all programs with a feature X can be
transformed into first-order programs; so programs with feature X
are first-order" used by Richard should be treated with scepticism.
Transformations do not preserve first-order-ness or any such property
of programs.  All languages can be transformed into Turing machines.
It does not mean, of course, that all languages have the same
properties as those of Turing machines.

Once referential transparency is lost, there is really no point of
talking about the "order" of the language.  univ and call (like eval
and quote of LISP) can be used to convert programs into data and data
into programs and anything is possible.  Here is a definition of map
(a higher order relation) using univ and call.

   map([],[],P).
   map([A|X],[B|Y],P) :- Goal =.. [P,A,B], call(Goal), map(X,Y,P).

Whether you choose to call Prolog first-order or higher-order is your
choice.  For me, it is neither.

-- Uday Reddy