[net.lang.prolog] a review of Turbo Prolog

bts@unc.UUCP (Bruce Smith) (05/14/86)

I picked up the following from Arity's bulletin board, and I'm posting
it to 'net.lang.prolog', with their permission.  Clearly Arity is not an
impartial observer, and parts of the review-- e.g. comparisons between
Turbo Prolog and Arity Prolog-- may sound like advertising.  However, we
are mostly mature adults, here on the net, and we can deal with such
things.  Overall, I found it interesting reading, and I hope there will
be some comments from people who've tried Turbo Prolog.
_____________________________________________________
Bruce T. Smith              Dept. of Computer Science
USENET: decvax!mcnc!unc!bts New West Hall (035-A)
Others: bts.unc@CSNET-RELAY Chapel Hill, NC 27514
==========================================================
==========================================================
Notes on Turbo Prolog -- Part 1 Peter L. Gabel May 4, 1986

1.0  Introduction

Borland's Turbo Prolog may be "turbo" but it isn't Prolog.

Borland in its attempt to produce a fast in-core compiler for Prolog has made
certain design choices that severely impact fundamental assumptions  about the
philosophy of Prolog programming and the structure of Prolog code.

Many problems that are elegantly solved in standard Prolog must be "hacked" 
together in Turbo Prolog because of the limited data types allowed.  That is, 
the data typing system in Turbo Prolog precludes many standard Prolog programs 
from executing without major rewriting, usually at a loss of program clarity 
and maintainability.

Further, those deviations to Prolog that have been made by Borland make Turbo
Prolog an extremely weak language for symbolic processing and AI. Turbo Prolog
is suitable for conventional programming problems by applying a Prolog-ish
style of declaritive programming to a Pascal-ish data typing system.  It is not
at all clear that Turbo Prolog is superior to conventional programming
languages such as C, Pascal or Basic for conventional applications.

The central problem for Arity posed by Turbo Prolog is that neophyte
programmers may believe that this is what Prolog/symbolic programming/AI is all
about and may become turned off without further investigation.  This problem is
intensified by Borland's unfounded claims and outright misrepresentations  
about Turbo Prolog.

Turbo Pascal put fun into Pascal programming; Turbo Prolog takes the fun of
Prolog programming away.

You can call a pig a horse, but you still can't get it to run in the Kentucky 
Derby.

An analysis of Turbo Prolog follows which covers the following areas:
	- the Turbo Prolog programming environment
	- the core Turbo Prolog language (i.e. the syntax and semantics
	of the defined language) and why it differs from Prolog
	- the available evaluable predicates and how they differ from
	Clocksin and Mellish standard predicates

In addition, the following questions are addressed:
	- why did Borland deviate from Prolog?
	- how do the deviations limit Turbo Prolog?
	- what advantages do the deviations bring?
	- what is a neophyte going to think about Turbo Prolog? an expert?
	- what is Borland going to do next?

Appendicies to this document include sample Turbo Prolog and standard Prolog 
code comparisons as well as benchmark data. 

2.0 An analysis of the Turbo Prolog programming environment

The Turbo Prolog programming environment is a window-oriented system
containing:

1) A built-in editor (same as in Turbo Pascal) with functions similar to 
Wordstar. The editor is adequate for writing and modifying code; it is not a
syntax-driven editor.  The editor is entered whenever a compiler error occurs
with the cursor positioned at the point of error.  A stupid problem with the
system is that compiler error messages are truncated within the  bottom line of
the edit window and are often unreadable.

2) A compiler (that can compile in-core or to an obj file) The compiler is NOT
incremental despite Borland's claims, all compilations are from the top. 
Modularity is supported by special global declarations and "project files". 
Modularity requires a common symbol table implying that all modules must be
compiled whenever a single module changes.  (Boo hiss.)

The compiler is comparable in speed to the Arity compiler.

The compiler may be invoked to produce exe files; this is actually a finesse.
The compiler produces an obj file and then invokes the Microsoft linker.  The
system may not have enough memory for linking large programs without leaving
Turbo Prolog.

It is possible to incorporate code written in Asm, C, Pascal and Fortran. The
data typing system allows very easy interface to external routines. This is a
plus for Turbo Prolog.  On the other hand, it is not possible for external 
routines to call a Turbo Prolog predicate or for the external routine to do 
complex structure hacking such as what is supported in Arity/Prolog.

The compiler's error messages are occasionally very obscure.  The section in 
the manual concerning error messages does not elaborate beyond the actual text
of the message.  Some of the messages are inappropriate, e.g., if you try to
assert a term with unbound variables you get a message "Free variables are not
allowed in WRITE."

3) A trace facility. A window for a trace is provided.  This is not a full
debugger.  There are two trace options: normal which suppresses TRO and
shorttrace which does not. The edit window allows tracing of source code.  This
is actually pretty neat. However, it is severely faulted in not allowing for
the usual spy points and leaping, and useful information is missing such as
invokation number and depth.  This means that the tracing facillity is
completely inadequate for  debugging large programs.

4) Windows for dialog I/O and messages from the compiler and a menu system with
various pop-up boxes. In general, the appearence of the screen is attractive.
The major pitfalls are clumsy resizing of the windows and truncated messages
(that disappear if you try to resize the window to read it).  Also goals
entered in the dialog box better not contain cuts or there is a bug.  

5) A help facility. Provides minimal information but useful for looking up how
to use the editor.  With better help text this could be neat. 

The compiler allows a fast edit-compile-run cycle.  However, the lack of an 
adequate debugger, and worse, no interpreter for the usual highly interactive 
kind of experimentation severely impacts the programming environment.  Often 
you want to try out code fragments in Prolog as you write a program.  Turbo 
Prolog hinders such interaction.

To its credit, the overall impression of the programming environment is that it
is slick with a powerful windowing system.  What it has in slickness it lacks
in power for interactive development.

3.0  The core Turbo Prolog language.

Turbo Prolog requires all predicates and all forms of terms that are arguments 
to predicates to be declared at compile-time.  This is NOT optional.  This
means that all metalogical operations and predicates that can build new forms
of terms at runtime are not found in Turbo Prolog.  No reader.  No functor, arg
or univ. No =, \=, ==, \==.  Even worse is the fact that there is no way to
declare  certain forms of terms at all in Turbo Prolog.  For example, you can't
have the following lists: [1,a], [1,[1,2]], [1, 2.0], [1, foo(2)].  And many 
programs that require complex data structure manipulations have to be  hacked
together because the natural way of defining terms in standard Prolog doesn't
exist in Turbo Prolog.

Thus, Turbo Prolog doesn't do what you fundamentally want to do with a  
symbolic programming language: process general symbolic data structures and
generate new structures at run-time.  Pattern matching is restricted and 
unification in general is broken.  The type declarations allow the compiler  to
do simple assignment or equality tests in place of unification (which for those
cases where appropriate allows the compiler to generate faster executing code)
but at a huge expense in ease of programming and in generality. Many programs
that are easy to read in standard Prolog cannot run without  major
modifications if they can run at all in Turbo Prolog.  And the  beauty of
Prolog is lost.

3.1 Domain and predicate declarations

The typing system in Turbo Prolog allows new types (domains) to be composed 
from the following built-in domains: char, integer, real, string, symbol ( what
is generally called atom), file, and a special ad hoc "database" domain  
dbasedom.  Another domain is pre-defined for the bios predicate, regdom.

List domains are composed from other domains and are denoted by a star suffix, 
e.g., integer*.

The rules of composition of domains are as follows:

1. name = {reference} domain
name1, name2, ... = domain

2. name = {reference} domain*

3. name = f1(d11 .. d1N) ; f2(d21 .. d2M) ; ...
	where all functors must be unique

4. file = name ; name; ...
	(all files for processing must be pre-named) (boo hiss)

The "reference" keyword is required if predicates using a domain may have out 
arguments which leave free variables in terms.  This forces the compiler to 
generate dereferencing code.

Predicate declarations are of form: pred(d1 .. dN) pred(...)

A predicate may be declared more than once for different domains.

All "database" usage must be declared at compile-time and the only allowed 
domains are fully instantiated facts.

This is not a sufficient type system and worse it is static: no domains, atoms 
(what they call symbols) or functors may be defined at runtime.  This means 
that the only symbolic problems that may be solved by Turbo Prolog are those 
that have a static, limited set of forms.  The Zebra problem is solvable in 
Turbo Prolog.  Naive Reverse of certain lists may be solved.  But even Naive 
Reverse of the following list is impossible: [1, foo, 1.2, foo(1), [1,2], X].

3.2 The "dynamic database"

Turbo Prolog's "database" is not a database at all and I cannot see anything  
dynamic about it.  This is an area where Prolog has such a rich tradition in 
both an effective mechanism for the storage and runtime modification of  
interpreted code and the storage of arbitrary Prolog terms.

In Turbo Prolog this heritage is obliterated.  You must declare the form of 
what is to be stored in the "database" at compile-time.  You can only store 
ground terms (i.e. no free variables).  All stored terms are sequentially 
accessed and are stored in the heap.  This is totally useless for all but toy
applications.

Turbo Prolog provides five "database" predicates: asserta/1, assertz/1, 
consult/1, save/1 and retract/1. In all cases, only ground terms (facts) are  
handled.  Just a shadow of real Prolog's assert and retract.

3.3 Unification and strong equality

The "=" predicate does not exist.  You must define equal(X,X) with appropriate 
domain declarations to get any semblance of unification.  Garbage.

You must define strong equality by using the metalogical predicates free/1 or
bound/1 (the Turbo incompatible equivalents of var/1 and nonvar/1). Again, you
are still constrained by static domain declarations.

3.4  Lack of a Prolog reader (no read/1 predicate)

Because all domains are static and a Prolog reader may allow the definition of 
new functors, etc. they just threw it out.  They didn't even do the next best  
thing: a lisp-ish list reader.  This is amazing.  No operator precidence  
parsing done for you. No DCGs for natural language.  No Prolog.

3.5 Evaluable Predicates

Evaluable predicates return values by ASSIGNMENT not by unification.  This  
means that you must do extra work in the code if you are checking a value. 
Again, this just isn't Prolog.  This allows the compiler and the runtime system
to make certain assumptions which may speed execution slightly, but at a loss
of generality.  This wouldn't be such an issue if you could do real unification
or even strong equality.  In practice not a big issue.

3.6  Lack of a garbage collector and "unsafe" memory management (not strictly a
language issue).

The current implementation of Turbo Prolog does not contain a garbage
collector. All structures, strings, reals and "database" items are in a heap
that is  addressed with 32 bit addresses.  Borland does a good job with TRO and
the data typing helps dramatically with storage consumption but many programs  
will still abend with no remaining heap when they could have run if a  garbage
collector was present.

Turbo Prolog also acts incorrectly without warning if the stack or trail  
overflows.  One of the reasons why Turbo Prolog executes quickly is that it
doesn't bother to test for overflows.  Usually the system just appears to have
a predicate fail -- you don't know whether that is correct behaviour or not.   

3.7 Restrictions on names of user defined predicates

Predicates may not have the same names as built-in predicates even if they have
different arities.  Further, user defined predicates must have unique names,
you can't have both foo/2 and foo/3.  Not a big deal but a small gotcha.

3.8  Lack of general prolog clause structure.

Turbo Prolog also restricts the use of disjunction (;) to the top level of  a
clause. For example, the following clause is illegal in Turbo Prolog:
	foo :- goal1, (goal2 ; goal3). Most Prolog programs can be restructured
relatively easily to cope with this at the expense of making the program less
readable.

4.0  Built-in evaluable predicates

There is a total disregard by Borland for the Clocksin and Mellish standard. 
And, of course, except for a well developed set of screen handling predicates, 
Turbo Prolog is a mere shadow of Arity/Prolog.

The following is a comparison of C & M Prolog with Turbo Prolog.


	Clocksin and Mellish				Turbo Prolog
---------------------------------------|---------------------------------------
consult					consult -- ground facts only
reconsult				NA
list notation for consult		NA
true					NA
fail					fail (same)

var/1					free/1
nonvar/1				bound/1
atom/1					NA
integer/1				NA
atomic/1				NA

listing/1				NA (but has built-in editor)
clause/2				NA
asserta/1				asserta/1 -- ground facts only
assertz/1				assertz/1 -- ground facts only
retract/1				retract/1
functor/3				NA
arg/3					NA
=.. (univ)				NA
name/2					NA -- but includes five predicates
					for type conversion: char_int,
					str_char, str_int, str_real,
					upper_lower
!					!
repeat					NA (but easily defined)
,					, and
;					; or
call/1					NA -- major missing feature
not/1					not/1
=					NA
\=					NA
==					NA
\==					NA
get0/1					readchar/1
get/1					NA
skip/1					NA
read/1					NA -- major missing feature!!! 
put/1					NA
nl					nl
tab/1					NA
write/1					write/? -- bizzare multi-arity
					version 
display/1				NA -- but there is a predicate by
					the same name for writing strings
op/3					NA
see,seeing,seen,tell,telling,told	an equivalent set but non-standard
					names also has seek abilities
X is Y, arithmetic comp preds		X = Y, but only evalutes expressions
					at compile time; also has arithmetic
					comparison predicates; handles reals
					and various trancendental functions;
					comparison preds are oveloaded for 
					symbols and strings

Additional predicates contained by Turbo Prolog are: 1) various data typed I/O
predicates, but no standard read and write. 2) 27 screen handling predicates
for windowing, editing and turtle graphics 3) 5 string handling predicates 4)
findall/3 (worth having) 5) a variety of system predicates for beeping, hitting
interupts and ports, etc

To their credit, Borland did a good job with the screen predicates and have the
minimal string predicates.  However, the claim on the back cover of "supporting
a large superset of the Clocksin and Mellish Edinburgh standard Prolog" is a
lie.

Some simple sugars to Prolog are impossible to implement in Turbo Prolog. Most
notable is the DCG formalism which is standard in Arity/Prolog. So much for
natural language processing.

5.0 Issues

5.1 Why did Borland choose to deviate from the standard?

I believe that Turbo Prolog probably started as some student's idea of how to
improve the efficiency of Prolog's execution.  The idea is that by avoiding 
some of the generality of Prolog where it is not needed one could get much 
better generated code.  It also might be motivated by trying to make Prolog 
more "conventional".  It may be the case that Turbo Prolog is more natural to a
garden variety Turbo Pascal programmer than standard Prolog.  Indeed, they 
might think it's better.

A proper OPTIONAL typing system would improve Prolog.  It could both increase 
efficiency and potentially improve self-documentation of code and runtime error
trapping.  Arity/Prolog currently makes use of mode declarations.

Many programmers believe that explicit type declarations are good.  However, 
there are vast differences in functional usage of a conventional language  
versus a symbollic language.  The "Pascalization" of Prolog results from a lack
of insight concerning the needs of a programmer doing symbollic  applications. 
The propaganda value of the type system may be great for Borland.

5.2 How do the deviations limit Turbo Prolog?

Programs that require any of the following cannot be written in Turbo Prolog:
	- a real database
	- complex terms
	- new types of terms formed at runtime
	- term I/O
	- metalogical operations
	- interpretation of arithmetic expressions at runtime

Most non-trivial programs are uglified by the restrictions forced by the type  
system.  Programs usually need to be restructured and are less general.

One would think that adding a data type system to a language, even if not  
optional, should NOT force a different discipline of programming and break many
quite reasonable programs.  Obviously Borland does not choose to see the world
in this way.

5.3 What advantages do the deviations bring?

Programs that are relatively simple and primarily deterministic will run faster
than Arity/Prolog with relatively little pain.  The speed difference ranges
from insignificant (or slower for zebra) to 2 times faster for integer naive
reverse (not true naive reverse, by the way) and 3 times faster for sieve of
Erosthenes.  More typical programs that are composed of non-deterministic 
predicates are slower in Turbo Prolog than Arity/Prolog.

5.4 What is a neophyte going to think about Turbo Prolog?  An expert?

Someone who is new to Prolog may get turned off to the language by not  
realizing that Turbo Prolog is not Prolog.  More probably, they will  realize
that Turbo Prolog is just a toy and may get their appetite  whetted for a real
Prolog.

An expert is going to see that it is a toy right off.

"Just because it has a compiler doesn't mean that its not a toy."

5.5 What is Borland going to do next?

Go public.  Beyond that, they would need to completely re-engineer the product
to fix it.  And thats not their style.

So they will spread a tremendous amount of misinformation about Turbo  Prolog
and Prolog in general.  I'm sure that they will introduce a Turbo Toy expert
system product too.

6.0 Major features of Arity/Prolog not found in Turbo Prolog

- REAL PROLOG: true superset of C & M Prolog
- virtual dbms, arbitrary terms, 1 gigabyte, indexing, partitions
- interpreter and debugger
- modular compilation, ability to add to the interpreter
- lint
- far prolog
- garbage collector
- DCGs
- sophisticated language interfaces
- optional mode declarations
- edit/1

7.0 Planned improvements to Arity/Prolog that are similar to Turbo Prolog

The current development in systems work will subsume any advantages that Turbo 
Prolog enjoys in the following areas and will significantly increase 
Arity/Prolog execution speed (we already beat them in more typical Prolog 
programs).

- screen stuff
- bios/3 
- easy C interface

Overall, the advent of Turbo Prolog will not sway mainstream development  
efforts for the next version of Arity/Prolog.  

tfra@ur-tut.UUCP (Tom Frauenhofer) (05/16/86)

[Et tu, line-eater?]

A correction: Turbo Prolog DOES support unification using the "=" sign.  You
do NOT have to define a predicate like "equal (X,X)".

FLAME ON

The only "lies" I found was calling this :"garbage" a review.  Seemed like
a sales brochure to me.  (I have used Turbo Prolog.  It's nice, but it is more
like "Let's make Turbo Pascal and call it Turbo Prolog.  Wala!").  

FLAME OFF

Perhaps a more impartial review would be useful?

-- Tom Frauenhofer

...!seismo!rochester!ur-tut!tfra

"Gosh, if Phillipe Kahn, so Kahn I!"