[m-dev.] EDCGs and Higher Order Programming

Peter Nicholas MALKIN pnmalk at students.cs.mu.oz.au
Thu Jan 27 21:09:16 AEDT 2000


Hi,

On Thu, 27 Jan 2000, David Overton wrote:

> I've been having similar thoughts about this:  DCGs + record syntax
> gives you most of the benefits of EDCGs, but with _much_ less added
> complication to the language.
> 
> > Good question.  But I don't think it works out quite so nicely.
> > For example, suppose you want to pass the io__state and something
> > else, so you put them both in a record.  Now you want to call
> > something simple like `io__write_string' or `io__write_int'.
> > To do that, you need to extract the io__state from the record,
> > pass it to io__write_string and/or io__write_int,
> > and then set the resulting io__state:

> Why not add a simple construct similar to the proposal for embedded EDCG goals,
> but using DCGs instead?  E.g.
> 
> foo -->
> 	( ^io -->
> 		write_string("blah"),
> 		write_int(42)
> 	).
> 
> would be transformed by the compiler to Fergus's code above.  This is
> still a much simpler transformation than EDCGs.

I considered this, two years ago, and the basic problem is along the lines 
Fergus suggested. Fundamentally the problem is that solely using record syntax
means that you a grouping potentially mostly unrelated bits of information
together in a single structure. Since the different bits information are
potentially unrelated they are often likely to be used in different ways, passed
to different predicates, their flow through the program differs greatly. 

Consider the following:

We have a structure, passed to q, containing three fields, names a, b and c
respectively. Also, r uses a only, s uses b only and t uses c.
Then the code using DCGs and the record syntax using embedded DCG goal syntax
is (assuming appropriate declarations for all predicates already exist):

q -->
	( ^a -->
		r,
	),
	( ^b -->
		s,
	),
	( ^c --> 
		t
	).

Prehaps this could be shortened to:

q -->
	{ r(^a) },
	{ s(^b) },
	{ t(^c) }.

In either case the code is basically not much better than when written
verbosely.  

However in EDCGs it is simply:

q -->>
	r,s,t.

(I realise that this example is not great, but I hope you can generalise it and
see my point.)

Such a structure being passed around using DCGs can only be of much use if it
carries around a lot of unnecessary information a lot of the time, but I do not
believe this to be a good coding style. 

Avoiding excessive carrying of information requires both creating a lot of
different types which have no semantic value only syntactic, and creating a lot
of predicates to convert between these types. Or developing a syntax which
specifies which of the fields are passed to which predicate and this is
basically the specification of EDCGs.

EDCGs also provide you with more flexibility than DCGs because DCGs always pass
two extra parameters, whereas with EDCGs the option of only passing one 
argument is available. Also EDCGs handles variable renaming problems, which
record syntax and DCGs do not.

The cases where record syntax and DCGs are better is when strongly related
different types that are passed in similar fashion are placed in the one data 
structure, however this is standard practice and the preferred method. Where
this cannot be applied, because the types are not strongly related and or the
types are not passed in a similar fashion either EDCGs or explicit parameter
passing are useful.

Peter

P.S. I think you are also forgetting about those annoying curly braces, I
believe Zoltan is with me on this point.

--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list