Re: Ann: SWI-Prolog 7.1.0

"Richard A. O'Keefe" <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 26/11/2013, at 4:11 AM, Jan Wielemaker wrote:
>  I've always felt that =.. was a bad idea.  Not
> only because it works on atomic data, but also because the right
> hand is a list, but the first element plays a special role, and
> even worse, this role depends on whether or not there are
> additional arguments (e.g. X =.. [42] is legal).

No, the special role does NOT depend on whether or not there
are additional arguments.  The first element of the list is
ALWAYS the function symbol and the number of remaining elements
is ALWAYS the arity and X =.. [X] for EVERY term X that is neither
a variable nor a compound term.

The only thing that is special is that numbers cannot be the
function symbols of compound terms, but that has nothing to do
with univ.  You can implement the traditional univ as

	=..(Term, [Function|Arguments]) :-
	    (   nonvar(Term) ->
		functor(Term, Function, Arity),
		length(Arguments, Arity)
	    ;   length(Arguments, Arity),
	        functor(Term, Function, Arity)
	    ),
	    '=.. arguments'(Arguments, 0, Term).

	'=.. arguments'([], _, _).
	'=.. arguments'([Arg|Args], N0, Term) :-
	    N1 is N0 + 1,
	    arg(N1, Term, Arg),
	    '=.. arguments'(Args, N1, Term).

Do you see any variation there depending on whether or not
there are additional arguments?  No, neither do I.
Do you see anything there that checks whether the Term is
a number?  No, neither do I.  The code, as written, also
works perfectly for SWI Prolog strings.

>  Surely, you can
> can defend this from a logical perspective, but from a software
> engineering point of view it is weird at best (at least, that is
> my opinion).

The weirdness is in your description, not in univ.
I agree that I too would have preferred the function constant
to be separated from the arguments, but if your previous exposure
to AI languages had been to Lisp, you would think that
	(foo 3 4)
should *obviously* correspond to
	[foo,3,4]
and would think separating the function constant out to be
seriously weird and unmotivated.  If you look at the definition
of (=..)/2 above -- which I labelled "traditional" because I
made no attempt to get ISO error reporting right -- you will
see nothing that any software engineer should find "weird",
unless perhaps it is the code that schedules the relative order
of the calls to length/2 and functor/3 depending on whether
Term is bound or not.  But that's fairly typical of low-level
multidirectional Prolog code.

The original univ was trickier, because it split constants
into their characters, e.g.,
	-univ(foo(bar), L)
=>	L = (f.o.o.nil).bar.nil

The idea of having non-variable terms that functor *doesn't*
work on, now *THAT* is bizarre and hostile to good engineering!
All the metalogical code I have should work perfectly with
strings, but the distinction between [] and '[]' and the
distinction between f and f() would utterly break all of it.
(Like the fact that the description of =.. above *does* work
with strings but *not* with f().)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.