Re: Ann: SWI-Prolog 7.1.0

"Richard A. O'Keefe" <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 28/11/2013, at 7:00 AM, Jan Wielemaker wrote:

> Alan,
> 
> Good to point this out!  Yes, if everyone follows the Craft of Prolog's
> rules
> on this, [] \== '[]' is not needed.  But ..
> 
>  - It uses a lot more memory (1 cell for joe and 3 for word(joe)).

This is seriously misleading.

The design rules given in the Craft of Prolog
do NOT generate wrappers except to do one of two things:
 - to package together two or more piece of information
 - to distinguish one case from another.

One of the reasons that I wrote that section of the book was that
I was disturbed by the amount of Prolog code I had seen that
*over*-used wrappers, so I wanted simple clear guidelines that
would *only* result in wrappers that paid for themselves.

By the way, I used to have a 4MB desktop machine in 1990.
It had 1 core and rand about 30 MHz.
I now have an 8GB desktop machine, which has 4 cores, each
of them 100 times faster.

Using 2 extra words of memory is a GOOD thing IF it pays for
itself by making the program simpler and clearer.

As a case in point, when David Warren wrote the Quintus compiler,
he used defaulty data structures everywhere.

I rewrote it to never use defaulty data structures.
And it ran 20% faster.
It even took less memory, because the trick was to carefully
design *every* case in the data type.

>  - It makes switching on the _type_ of word(joe) fast, but switching
>    on word(joe) vs. word(john) slow.

Again, this is seriously misleading.

When you design a data type using the rules in the Craft of Prolog,
you consider *ALL* the case analyses you need to make.  If you need
to have one clause that matches joe and one that matches john,
then following the Craft of Prolog rules YOU NEVER HAVE word(joe)
or word(john) in the first place.

No, if you are checking for joe, john, or some other word,
your cases are

	joe
	john
	word(Other_Word) % which should not be joe or john

This is one of the ways that ways that the Quintus compiler
got faster, moving from

[A]	foo(X, Y, bar(Z, W), U)
	foo(X, Y, ugh(P, Q, R), U)

to
[B]	bar(foo(X,Y,U), Z, W)
	ugh(foo(X,Y,U), P, Q, R)

so that decisions were made with a minimum of matching effort.

If, most of the time, you DON'T care whether it's a bar or an ugh,
just that it's a foo, design [A] is the better design.  If, most
of the time, you DO care whether it's a bar or an ugh, design [B]
is the better design.

The example we started with was not my example, and it was one
in which there was no reason to believe that there would be
any switching on specific words at all.

In processing token lists for programming languages,
I usually turn punctuation marks and keywords into special
tokens, so there will be ',' and '(' and ')' and 'do' and
'end' tokens and so on.  Identifiers get wrapped as
identifiers.  Numbers get wrapped as numbers.  Operators
I tend to wrap, so for C we'd have rel(<), rel(>), rel(==),
rel('!='), and so on, because most of the time we care
that something is an operator in a certain class of operators,
not which specific operator it is.  (In later stages of
processing where we *do* care, naturally we use a *different*
data structure tailored to the decisions made in *that* processing.)

>  So, you need to be careful where
>    you wrap joe in word/1.

Oh, and guess what?  Once you _have_ clearly distinguished
each case, you often find that there is additional information
that needs to go there.  For (real!) example, you might go from

	word(joe)

in one stage of your design, to

	word(joe, [proper_noun,common_noun])

-- well, it might be better to use a bit mask -- in a later stage.
In programming language processing, it's often handy to include
source location information in the tokens, the way Erlang does,
for example.

>  - It is kind of awkward to read.

I weep for any Prolog programmer who isn't smart enough
 - to define portray(word(X)) :- print(X).
 - to understand the clearly and repeatedly stated distinction between
   INTERFACE data structures for people to read and write and
   PROCESSING data structures for computing with.

Defaulty structures are often nice for people; the abstract syntax of
Prolog clause bodies is itself defaulty.  They are a pain in the neck
for actual *processing*.  So you *convert*.  You design an interface
format that is nice for people, and as quickly as you can, you get
away from it.  People working on SAT solvers do not use a defaulty
data structure mirroring the surface appearance of propositional
formulas!

>  - Most Prolog programmers have given up way before they understand
>    this part of this book (probably even before they bought the
>    book in the first place).

Merci du compliment.
> 
> So, if we can fix all this (and some more) at practically zero cost,

THERE IS NOTHING TO FIX.  Only bad habits.

THE COST IS WAY ABOVE ZERO.

It doesn't matter if the actual cost of changing code to cope
with the changes is small.  The cost is NOT KNOWING what has
to be changed and FINDING OUT.

(Note that in JSON, all arrays are the *same* kind of data structure.
[] and [1] are not different kinds of animals, just different sizes.)
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.