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().)