Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!murtoa.cs.mu.oz.au!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: logic programs -> procedural lang? Summary: red herring Keywords: Prolog, typing, compiler efficiency Message-ID: <2181@munnari.oz.au> Date: 25 Sep 89 04:47:37 GMT References: <27335@shemp.CS.UCLA.EDU> <869@gamera.cs.utexas.edu> <10822@eerie.acsu.Buffalo.EDU> Sender: news@cs.mu.oz.au Lines: 118 In article <10822@eerie.acsu.Buffalo.EDU>, axaris@cs.buffalo.edu (Vassilios Axaris) writes: > I have been surprized when I first got my Turbo Prolog compiler, in that I was > required to specify the type of objects being used. In short, you were surprised to discover that what you got was NOT a Prolog compiler, but a compiler for another (closely related, but still OTHER) language. Whenever I hear that someone is thinking of getting Turbo Prolog, I tell them to look first at Trilogy. If you are willing to use a sort of Prolog/Pascal hybrid (Turbo Prolog), you ought to be happy with a logic programming language which is not a Prolog/Pascal hybrid but was designed from the start to let you do the kinds of things that Pascal is good for in a clean logic programming way. I have a copy of Trilogy, and while it's somewhere between two other countries at the moment, I was favourably impressed by it, and would prefer Trilogy to Turbo any day of the week. > Later, I realized that even > though this was putting a burden on the programmer, as well as deviating from > the standard, it could be (as it was I believe) useful in minimizing the runtime > type checking of the objects, in Common Lisp manner. You should be aware that there are Prolog systems for the PC which can run rings around Turbo Prolog, *without* sacrificing compatibility. I'll let the vendors tell you which ones. Basically, "run time type checking" is a red herring for Prolog. Consider something like append([], L, L). append([H|T], L, [H|R]) :- append(T, L, R). In Pascal terms, this would be type listPtr = ^listRrec; listTag = (kNil, kCons); listRec = record case tag: listTag of kNil: (); kCons: (head: something; tail: listPtr); end {listRec}; function append(A, Z: listPtr): listPtr; begin case A^.tag of kNil: append := Z; kCons: append := mkCons(A^.head, append(A^.tail, L)); end {case}; end {append}; The 'case' statement in the Pascal program is the equivalent of the 'indexing' done in Prolog. No amount of type checking at compile time is going to eliminate that 'case' statement. But that's where the "run-time type checking" is happening in the Prolog system. To be sure, tagging does slow arithmetic down. Static typing can help there, *IF* you also have strict mode checking as well. However, if arithmetic is more than say 30% of the cost of your Prolog program, you aren't doing things the Prolog Way. Lisp needs types much worse than Prolog, because the Lisp equivalent of append/3 would be (defun app (A Z) (if (endp A) ; check A Z (cons (car A) ; check A again (app (cdr A) ; check A again Z)))) where A gets checked three times. In the code produced by a good Prolog compiler, this effectively happens just once, and is ``paid for'' by the `if'. See Author: David H.D. Warren, Luis M. Pereira Title: Prolog: the language and its implementation compared with Lisp Journal: Proceedings of the Symposium on Artificial Intelligence and Programming Languages City: University of Rochester Date: August 1977 Pages: 109-115 Other: published as SIGPLAN Notices 12:8 and as SIGART Newsletter 64 > In today's RISC world, I > think it would be very useful to include such declarations to aid the compiler > in creating efficient code, by minimizing tag processing. Hang on a minute, Turbo Prolog runs on 80*86s, which aren't RISCs... Real Prologs (as opposed to Turbo[*] Prologs) let you pass variables around in a way which requires run-time tests ANYWAY in order to tell whether a variable is instantiated or not; given that, any other tag checking that may be required comes free. Advanced Prologs (SICStus Prolog, NU Prolog, I believe ECRC though I haven't tried it, CHIP, CLP(-)) allow variables to be ``constrained'', which also requires run-time checks in the course of which other tag checks come free. [*] ``Turbo'' is a Latin word meaning ``I swirl [things] around, make [things] confused.'' A ``turba'' is a mob. > How does the Prolog community feel about such an addition? Is it reasonable to > do it for the sake of improved execution speed on workstation type environments? Today's good Prolog compilers on today's workstations already produce fast code, to the point where you might write C or Fortran code for number- crunching or interfacing to existing libraries, but would not be tempted to rewrite your program as such in C. (Unless you have written very bad Prolog code.) Don't make the mistake of thinking that types are necessary for efficiency: BCPL, BLISS, and many other systems programming languages are not typed. However, type checking *IS* useful for detecting mistakes in programs, and types are useful when designing a program. As far as I know, Bruynooghe was the first to write about types in Prolog. But there is a large and growing literature on type checking and type inference in logic programs. The NU Prolog Debugging Environment (spelled NUDE, apparently pronounced `nood') includes a rather powerful type checker. The source code of the Mycroft & O'Keefe type checker was posted to this news group a year or so ago. [Sorry, playmates, but there is a mistake in it. It treats disjunctions as if they were conjunctions. This usually doesn't matter, but occasionally it will reject a disjunction which is in fact well typed.]