Re: predutils package available (Re: PAC library for develop version available)
"Richard A. O'Keefe" <[email protected]> Fri, 3 Oct 2014 19:11:39 +1300
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 3/10/2014, at 6:15 PM, Kuniaki Mukai wrote:
>> The idea was that *all* the stuff relating to modules
>> (:- module, :- use_module, :- meta_predicate) should be
>> at the very top of a file, and the rest of the file
>> should as much as possible look as though modules did
>> not exist.
>
> Interesting. Thank you for fresh historical information
> and original idea on module system of Quintus Prolog.
>
> One question. I want to put meta_predicate directive close
> at the definition like this.
In order to handle circular dependencies between modules,
it was necessary to be able to read and process all the
linkage information without having to read all of a file.
In QP it was quite important therefore to put :-meta_predicate
declarations *for exported predicates* at the top. Others
just had to go before their first use.
Jan can tell you whether this is still necessary or useful in
SWI Prolog.
> :- meta_predicate my_flip(2, ?, ?).
> my_flip(F, X, Y):- call(F, Y, X).
That makes perfect sense in a multipass implementation.
Quintus Prolog was a single pass implementation:
- while reading a term does not fail
expand it
for each clause in the expansion
apply module-related transformations
compile it
add it to memory (or the .qof file)
An arguably *better* scheme would read an entire file
into memory and check it and process it before storing
any part of it (the way the Erlang compiler processes
Erlang files), but that wasn't the way Prolog worked
before Quintus, and customers depended on immediate-
incremental processing.
And that meant meta-predicates had to have their
interface declared before any definition or call.
The problem with putting the :- meta_predicate
declaration immediately before the definition is
"what if there is a *call* even earlier?" How
can you have mutually recursive meta-predicates if
:- meta_predicate declarations can follow calls?
Again, I do not speak for SWI Prolog here. For all I
know, now that we no longer have to live with 4 MB
machines, Jan may have decided to process whole files.
(ISO Prolog certainly jettisoned historic features in
order to make that straightforward.) Whether it's
portable to take advantage of that is another matter.
>
> (Though I am not sure whether the directive is necessary
> in this particular case).
To the best of my knowledge SWI does no meta-predicate
inference.
>
> Is this a bad practice ? Or are you saying on `header information`
> for use of external predicates, which sounds reasonable principle.
What I am saying is
- if a predicate is exported, include it in the :-meta_predicate
declaration at the beginning of the file.
- if a predicate is not exported, make sure its :-meda_predicate
declaration precedes the first use. (And a good way to do
_that_ is to put it before any predicate definitions or
initialisation commands.)
It was historic practice before Quintus Prolog to put
:- mode declarations for all the predicates in a file
at the beginning of that file. More precisely, it was
the practice to write a single :- mode declaration
listing all the predicates, typically in alphabetic
order, so that the user had a handy list of predicates.
:- meta_predicate declarations are just :- mode
declarations with a few extra options.
If we were designing Prolog these days, when people carry around
lightweight laptops with 8 GB of memory, we'd probably do what
Haskell and Erlang do, and that is parse and check a whole module
before acting on any part of it
SWI Prolog 7.x has cut the umbilical cord of backwards
compatibility, so it would not be out of place for SWI 8.x
to adopt a whole-file-processing approach. It always did
feel a little bit wrong that a declarative language should
have any dependency on the order in which declarations and
definitions were written.