From: alberto@cs.umd.edu (Jose Alberto Fernandez R)
Newsgroups: comp.lang.prolog
Subject: Re: Writing portable code.
Date: 29 Sep 92 18:18:59 GMT
	<14758@goanna.cs.rmit.oz.au>
Organization: University of Maryland Computer Sc.
In-reply-to: ok@goanna.cs.rmit.oz.au's message of 29 Sep 92 03:50:34 GMT

In article <14758@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:

   Nice if conditional compilation had been provided as part of Prolog?
   But it doesn't need to be.

   Suppose we use
       :- if(Condition).
       /* stuff */
       :- endif.
   for conditional processing, and let them nest.

   ....... nice coding .....

This code is a very good starting point for the kind of thing I
envisioned. It has some problems though:

1) Its granularity -- The minimum level of control that you have is a
clause. There is no way to specify that some part of a clause must
change depending on the installation. In particular, the way you offer
to solve the original problem is something like:

:- if(environment(dialect(quintus))).
retract_all_clauses(X) :- retractall(X).
:- endif.
:- if (environment(dialect(sepia))).
retract_all_clauses(X) :- retract_all(X).
:- endif.

which has the overhead of an extra call each time you want to retract
all clauses.

In my approach, as I said, one can define a macro RETRACTALL(x) that
will expand to the correct prolog term depending on the installation.
Although I think this problem could be solved by adding to your
preprocesor a facility to define rewriting rules (simple rewriting
rules). In that case on could say:

:- if(environment(dialect(quintus))).
:- retract_all_clauses(X) ==> retractall(X).
:- endif.
:- if (environment(dialect(sepia))).
:- retract_all_clauses(X) ==> retract_all(X).
:- endif.

Since then on, the preprocessor would expand every occurrece of
	retract_all_clauses(foo(X,Y))
by 	retract_all(foo(X,Y))
when using SEPIA.

   There are several problems with using the C pre-processor to do this job.
   The first is that the C pre-processor is a *C* pre-processor, and it uses
   C syntax, not Prolog syntax.  For example, it does not understand "%"
   comments.  It may well report syntax errors for things that are valid
   Prolog:  'FLIGHT' is not portable C.  It may get things wrong:
	   0x
   is perfectly valid Prolog, in the presence of a postfix operator
   declaration for x, but it isn't valid C.  It may generate output that is
   not valid Prolog (but you can read the ANSI C standard for yourself).

I just try your examples and it works just fine. Of cource you must
use the -C and -P flags to tell the processor not generate 'C'
specific output. Although as I just said in a previous message, you
could use other macro processors instead of CPP.

   The second major problem with using the C pre-processor is that it may not
   exist.  An ANSI C compiler may build the pre-processor in (and some do).
   I've used a Classic C compiler which did not have a separate preprocessor
   and gave you no access to the preprocessed output.

There are other systems that use CPP. For example 'xrdb' the resource
database loadder for X11 uses CPP to maccro expand resource files. I
think that the usage of a macro processor DIFFERENT from the object
language itself is a very good way to separate the codification of two
very different problems a) how to express my algorithm. b) How to
install for a particular system.

   And of course the C pre-processor is rather restricted in what it can do.
   Writing the pre-processor in Prolog gives you something rather better
   suited to Prolog.

   For example, I have an
	   environment/1
   predicate (check the Quintus library) which I have adapted to every
   Prolog that I use.  If I define
	   condition_is_true(X) :- call(X).
   then I can write code like

	.......

   I can also use that table at run-time to do things like

	   write_error_message(M) :-
		   telling(Old),
		   environment(stream(error(Stream))),
		   tell(Stream),
		   write(Msg), nl,
		   tell(Old).


As I said in my previous message, the problem with this is that you
are mixing your declarative program, with the declaratios of how the
code must be process in a particular installation. I don't like that,
I believe that the programmer should be able to clearly distinguish
between the two. That facilitates the portability of software to
different architectures.

	Jose Alberto.

--
:/       \ Jose Alberto Fernandez R | INTERNET: alberto@cs.umd.edu
:| o   o | Dept. of Computer Sc.    | BITNET: alberto@cs.umd.edu
:|   ^   | University of Maryland   | UUCP: {...}!mimsy!alberto
:\  \_/  / College Park, MD 20742   | 
Newsgroups: comp.lang.prolog