Path: utzoo!attcan!uunet!ns-mx!iowasp!deimos!ux1.cso.uiuc.edu!uwm.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!vega!vanroy From: vanroy@vega (Peter Van Roy) Newsgroups: comp.lang.prolog Subject: Re: incrementing values Message-ID: <34197@ucbvax.BERKELEY.EDU> Date: 8 Feb 90 04:40:35 GMT References: <17467@megaron.cs.arizona.edu> <31462@shemp.CS.UCLA.EDU> <34699@iuvax.cs.indiana.edu> <17483@megaron.cs.arizona.edu> <7926@cognos.UUCP> <704@cluster.cs.su.oz> Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: vanroy@vega (Peter Van Roy) Organization: University of California at Berkeley Lines: 81 In article <704@cluster.cs.su.oz> andrewt@cluster.cs.su.oz (Andrew Taylor) writes: -> ->I've thought of writing of pre-processor to effectively allow ->a variable's scope to include more than one predicate. -> He then presents the following example: -> ->scope(main/0, [main/0, a/0, b/0], X). ->main :- X = hello, a, write(X). ->a :- b. ->b :- write(X), X <- world. -> ->/* The preprocessor would output */ -> ->main :- X0 = hello, a(X0, X), write(X). ->a(X0, X) :- b(X0, X). ->b(X0, X) :- write(X0), X = world. -> -> ->Lately I've been writing a lot code which be much easier to read and ->less tedious to write the above preprocessor was used. -> ->Has anyone done something like this already, or think its a bad idea? -> ->Andrew Andrew has touched on a problem which I have felt as well. Writing large programs without side effects implies that all information is passed in arguments. In practice the number of arguments needed becomes large, which makes writing and reading such programs difficult. One way to solve this problem is by using a preprocessor which adds the extra arguments without significantly increasing the size of the source program. I have written a preprocessor which does just that. It adds pairs of arguments to predicates, chained together to implement accumulators. This generalizes the transformation done by the DCG (Definite Clause Grammar) preprocessor which is already part of Prolog. Andrew's example can be rewritten in the Extended DCG notation as follows: % Declaration of accumulator: acc_info(foo, X, In, Out, Out=X). % Declaration of predicates using the accumulator: pred_info( main, 0, [foo]). pred_info( a, 0, [foo]). pred_info( b, 0, [foo]). % The program: main -->> X/foo, X=hello, a, Y/foo, write(Y). a -->> b. b -->> X/foo, write(X), [world]:foo. The preprocessor uses the expand_term hook implemented in C-Prolog and compatible systems. Its use is transparent to the programmer. When loaded into Prolog the above code is directly translated into the following: (Names have been changed for clarity) main(X0,X1) :- X0=hello, a(X0,X1), write(X1). a(X0, X1) :- b(X0, X1). b(X0, X1) :- write(X0), X1=world. which corresponds closely to what Andrew has presented. The accumulator 'foo' corresponds to the variable X in Andrew's example. In this particular example, with only one accumulator, the advantage of the notation is not directly visible. When writing larger programs, however, I find it indispensable. A package containing the preprocessor, a user manual, and several examples is available by anonymous ftp from arpa.berkeley.edu, or send me mail to get a copy. The November 1989 issue of SIGPLAN Notices has an article which describes and justifies the preprocessor in more detail. Peter Van Roy vanroy@ernie.berkeley.edu