[m-dev.] EDCGs and Higher Order Programming

David Overton dmo at ender.cs.mu.oz.au
Thu Jan 27 12:03:50 AEDT 2000


On Thu, 27 Jan, 2000 at 11:02:29AM EST, Fergus Henderson wrote:
> On 26-Jan-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> > Thanks for the update.  Just for the record, I'm very
> > uneasy about the whole EDCG thing.
> > 

[...]
> > now we have the record
> > syntax, surely that (plus DCGs) should be sufficient to
> > achieve the same thing?

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:
> 
> 	:- type my_state ---> my_state(io :: io__state, other :: int).
> 	:- inst my_state = unique(my_state(unique, ground)).
> 
> 	:- pred foo(my_state::di(my_state), my_state::uo(my_state)) is det.
> 	foo -->
> 		IO0 =^ io,
> 		{ write_string("blah", IO0, IO1) },
> 		{ write_int(42, IO1, IO) },
> 		^io := IO.

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.

> 
> This is rather nasty: you need to do explicit argument passing
> and variable numbering.  With EDCGs, you avoid both of those
> in cases like this.
> 
> There would also be some difficulty with higher-order code for the
> DCGs+records approach, similar to the issue with EDCGs discussed below.
> Your `write_strings' example would have to look something like this:
> 
>  	write_strings(Strs) -->
>  		WriteStringPred = (pred(S::in, di, uo) is det -->
> 			IO0 =^ io,
> 			{ write_string(S, IO0, IO) },
> 			^io := IO)
>  		list__foldl(WriteStringPred, Strs).
> 
> So I don't think DCGs+records solves the problem.

There's no need to extract the io__state within the closure, so you
could write:

	write_strings(Strs) -->
		IO0 =^ io,
		{ list__foldl(write_string, IO0, IO) },
		^io := IO.

or, using the syntax I just proposed:

	write_strings(Strs) -->
		( ^io --> list__foldl(write_string) ).

[...]
> 
> Well, you can do a little better by abstracting out the conversion
> function:
> 
> 	:- func io2p((pred)+hidden(changed(io))) = pred(io__state, io__state).
> 	:- mode io2p(in(pred)) = out(pred(di, uo) is det).
> 	io2p(P) = (pred(IO0::di, IO::uo) is det :-
>  			(io is changed(IO0, IO) -->> P)).
> 
> Then you can write `write_strings' as
> 
> 	write_strings(Strs) -->>
> 		list__foldl(io2p(io__write_string), Strs, $io, $=io).
> 
> You could also define a conversion function in the other direction
> (`io2p'), and thus write it as
> 
> 	write_strings(Strs) -->>
> 		p2io(list__foldl(io2p(io__write_string), Strs).

With my proposal, there is no need for the io2p function since you
don't have to worry about converting between two different types,
`(pred)+hidden(changed(io))' and `pred(io__state, io__state)', for the
same concept.  

The p2io function can be replaced by `( ^io --> ... )'.

What do other think about this?


David
-- 
David Overton       Department of Computer Science & Software Engineering
PhD Student         The University of Melbourne, Australia
+61 3 9344 9159     http://www.cs.mu.oz.au/~dmo
--------------------------------------------------------------------------
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