The introduction of new features and new incompatibilities with the ISO
standard in SWI-Prolog version 7 has raised considerable concerns about
the future of SWI-Prolog. This page addresses some of these issues. The
page is organised as questions and answers.

What guides the development of SWI-Prolog?

With SWI-Prolog, we want to provide a language that satisfies the needs
of academic and industrial application programmers. SWI-Prolog is a
dialect of Prolog because we believe that the logic foundation provides
a good basis for many relatively simple reasoning tasks seen in
applications. Its reflective capabilities as well as its `program is
data' view makes it an ideal platform for domain specific languages
(DSLs) or micro languages, which allows for concise description of
application knowledge and separation of this knowledge from how it is
applied. And, of course, Prolog provides a safe environment, free of
crashes and memory leaks.

SWI-Prolog does not want to be an implementation that solves the
N-queens problems elegantly and in splendid isolation. Instead, we want
it to be a system that can operate as a component in modern IT
architectures. That is why it concentrates on multi threading, network
communication (sockets, HTTP, TIPC) and exchange of commonly used
structured documents (XML, JSON, RDF, CSV, etc.). That is also why it
supports relevant data types: Unicode text, big integers, rational
numbers and strings, as well as extended runtime detection of Prolog
data types that allows for a natural representation of dynamic data
while being able to distinguish a string from a list and the empty list
from an identifier without additional type information in the form of
declarations or wrapping data into terms.

With SWI-Prolog we want to maintain a living language. That means that
we will try to make the language evolve with insights and trends in the
IT world. Together with our aim to support application programming,
this leads to the following priorities:

Robustness and scalability

These should be obvious. The first aim here is to ensure that
properly debugged programs can run 24x7 reliably and without
memory leaks. This is more or less satisfied. The second is
to ensure that broken programs and development interaction
(debugging, reloading, etc.) does not crash the system. There
is still work to be done here.

(Backward) compatibility

We try to make as few as possible changes that break backward
compatibility and stay as close as possible to the ISO standard
(more about this below) and other Prolog systems (notably YAP).
If incompatible changes are needed to enhance the compatibility
or accommodate new extensions deemed necessary, we try to do this
in such a way that (1) upgrading is relatively easy and (2) it
is not hard to program in such a way that the code still runs
on older versions or other Prolog implementations.

Did SWI-Prolog give up on ISO compliance?

Not (much) more than it used to. If you are looking for a Prolog system
that restricts you to the ISO standard, SWI-Prolog should not be the
first thing to look at. ISO compliant programsthat do not explore
corner cases such as relying on specific behaviour on basically invalid
programs (e.g., expecting length(42,X) to fail silently)should run
fine.

The ISO standard has done a great job in synchronising and cleaning the
syntax and core semantics of the language. However, the standardised
core is too small to accommodate real applications, the process to
enlarge is is too slow (while some vendors do not even want to enlarge
it) and there are no mechanisms that allow us to make even tiny
incompatible changes needed to accommodate new features in a clean way.
Especially this last restriction turns it into a practically dead
language.

Below are a number of specific issues with the ISO standard that we
experience as counterproductive.

Definition of error handling

ISO Prolog defines the behaviour of all built-in predicates both when
operating on arguments within the meaningful domain for the predicate
and when faced with illegal input, such as passing a non-list to the
first argument of length/2. It often even defines the precise error that
must be raised if the call is wrong for multiple reasons. We consider
this counterproductive for the following reasons:

It puts an enormous stress on the ISO process itself. For example,
defining that length(List, Len) is true when Len is the number of
elements in the list List is easy. Defining that this predicate
is non-deterministic if List is a partial list and Len is unbound
is necessary. Defining what happens on length(List, -1) is also
necessary, because this this can be a goal resulting from a sensible
program.

However, it makes little sense to define what happens on length(42,
Len). The ISO committee decided this must fail because it wanted
implementations to allow rewriting e.g., length(List,5) into List =
[_,_,_,_,_] and 42 = [_,_,_,_,_] fails silently. These debates
are involved, trying to balance between usefulness of an exception,
performance costs and implementation effort to do the required
checking, possibilities for rewriting (as with length/2),
consistency, etc. There is no single truth here.

Defining the precise error or failure for basically invalid goals
makes it hard for systems to comply because it assumes a certain
implementation technique and order of execution. For example,
consider meta-calling, where ISO dictates that call((fail,1))
must raise a type_error. Here, SWI-Prolog complies
because call/1 compiles the argument before execution. Systems
that prefer an opportunistic approach however will execute fail/0
and never try to execute the invalid 1.

The precise error and failure conditions make it
hard to perform program rewrites that now needs to maintain the
exact behaviour on invalid input. It also does not allow for
introducing exceptions in places where failure was prescribed
because the costs of generating an exception was deemed to be
too high by the ISO committee. It even disallows systems to reject
goals like Len is A+B, length(Len, List) based on static analysis.

In the long run, we expect that SWI-Prolog will become a partially typed
language. Type systems have to choose between decidability and
expressiveness. Here, we plan to go for expressiveness by defining a
type, mode and determinism annotation that can capture the richness of
practical Prolog programming as we see it now. Based on that, we expect
analysis tools that proof errors rather than correctness. Some of
this is likely to be based on the Ciao
assertion language.

Arithmetic

Being a logic based and dynamically typed language, Prolog should offer
precise arithmetic results whenever possible. It should have unbound
integers and rational numbers at its core. Unbound integers are not
prescribed by the ISO standard and rational numbers are not even
mentioned. Arithmetic is defined almost as the C language defines it,
except that all overflow and evaluation errors must be mapped to
exceptions (a good idea). Typed languages have no choice but defining
that a specific operation returns a value of a specific type. Untyped
languages however can define that X**Y evaluates to an integer if this
represents the exact result and a rational number or floating point
number otherwise. ISO decided for two exponentiation operators (** and
^), where ^ evaluates to to an integer and raises an exception if
the result is not integral. We find this confusing. If you want ** to
do floating point arithmetic, you can cast one of the arguments to
escape from the world of integers:

?- Exp is 2**float(2).
Exp = 4.0

In the long run we expect a tighter integration of rational numbers.
This will involve integral division to be mapped to rationals and might
involve syntactical extensions to accomodate rationals.

Representing text

ISO Prolog provides no sensible way to represent a string of characters.
In general, such data cannot be represented using atoms because systems
pose limits on the length of atoms, the characters that can be inside
atoms or the number of atoms or do not provide atom garbage collection.
There are two list representations for strings, one as a list of
character codes and one as a list of characters (atoms containing
exactly one character). Both representations are expensive and neither
can be distinguished at runtime from either a list of integers or a list
of atoms or the empty list. Without runtime type information on strings,
debugging becomes hard (should the debugger print "ab" as is or as
[97,98]?) and dynamic data structures cannot be created. The two
string representations suggest a choice, but in reality this choice
needs to be made for the whole application and is therefore not a real
choice.

The SWI-Prolog extensions fix some of
these problems by reviving a string type as there was in the BSI Prolog
standard and which survived in several implementations (e.g., ECLiPSe,
Amzi!). We expect that YAP will follow. The primitives will be
synchronised with ECLiPSe.

In the long run, we might do something about the _chars and _codes
predicates, possibly by introducing a new data type char.

Syntax

The ISO Prolog syntax has several flaws.

Quoted atoms and strings

Here, we see several issues. Long strings with good looking
source layout is not supported because there is no syntax do
concatenate strings (as in C, where "hello " "world" is identical to
"hello world") and there is no escape sequence that ignores
a newline and leading white space. In addition, there is the
idiosyncratic `\XXX\` notation for numeric character codes embedded
in quoted atoms and strings, which is not compatible with older
practice in Prolog, not with anything else and means nothing because
it does not define how XXX must be interpreted.

Unicode is there now long enough for SWI-Prolog to support the
widely accepted \uXXXX and \UXXXXXXXX. In addition, SWI-Prolog
supports quasi quotations,
which can support pretty looking long strings as well as safely
interprolate Prolog variables into source code fragments of
external languages.

Lack of support for commonly seen syntactical primitives

Expressions such as array[index], X.member, function() or
function(Arg) { Body } cannot be expressed in ISO Prolog. This
results in needlessly verbose and unnatural notations (see e.g.,
library(record)) and makes it hard to define DSLs with a natural
syntax.

Should SWI-Prolog still be called Prolog?

When introducing the extensions in
version 7, several people have claimed that SWI-Prolog should choose a
new name that does not refer to Prolog, such as
Picat or
Mercury did. Both languages share concepts
with Prolog, but both differ so much that it is practically impossible
to run programs unmodified on both a Prolog processor and either Picat
or Mercury.

This is quite different for SWI-Prolog. Most `reasonable' programs that
satisfy the ISO standard or where designed for (especially YAP or
SICStus Prolog) run unmodified on SWI-Prolog or can be changed easily
to run on multiple systems.

What about vendor lock in?

With SWI-Prolog we wish to maintain as good as possible compatibility
with ISO and other Prolog implementations in the `close family' (notably
YAP and SICStus and at somewhat larger distance Ciao, ECLiPSe and XSB),
while adding extensions to the system that supports our
guiding principles). In practice, this means that an
application programmer who experiences problems running the same source
on another Prolog system while this is not a priori impossible (for
example because of completely different feature sets, such as the
(un)availability of attributed variables) and there is no sensible
work-around will be taken seriously.

YAP and SWI-Prolog have a similar drive, where YAP concentrates on
performance and SWI-Prolog concentrates on development and stability.
YAP uses many of SWI-Prolog's packages and generally copies features
that are required to support these packages.

Within the ISO core, it is fairly cheap to switch or maintain a portable
application to just about any Prolog. If ISO doesn't satisfy your
requirements and you want to be able to switch, you should carefully
examine the language features you need and which systems are capable to
support these.

And, of course, SWI-Prolog is open source, so you are free to fork it
under the conditions of the license.

How about SWI-Prolog and education?

SWI-Prolog has always been used extensively in education. The changes
introduced in version 7 do not make it significantly less suitable for
this purpose. There are two issues that might require some attention.

Double quoted strings

Courses that depend on the mapping of double quoted strings to
lists of character codes must either switch the double_quotes
flag, run using --traditional= or use back quoted strings
as illustrated in the calls below: