[m-dev.] EDCGs and Higher Order Programming
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Jan 27 11:02:29 AEDT 2000
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.
>
> It seems to me that EDCGs are a leap *away* from
> declarative programming in the sense that code using
> them can no longer be directly associated with logical
> formulae without reference to some auxiliary machinery.
> DCGs at least have { big red warning signs } indicating
> where strange things are afoot.
Well, with EDCGs you still have the `-->>' as a big red
warning sign (assuming appropriate syntax highlighting
support in your editor, of course ;-).
> The functional programming community seem to avoid the
> need for this sort of thing by having good mechanisms
> for boxing up bits of state;
I think the recent introduction of dynamically scoped
variables in Hugs/ghc suggests the opposite; the existing
mechanisms in Haskell 98 are _not_ sufficient, it seems.
> now we have the record
> syntax, surely that (plus DCGs) should be sufficient to
> achieve the same thing?
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.
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.
> > But reusing list__foldl is more difficult.
> > For that, you would need to write something like
> >
> > write_strings(Strs) -->>
> > WriteStringPred = (pred(S::in, A0::di, A::uo) is det :-
> > (io is changed(A0, A) -->> io__write_string(S))),
> > list__foldl(WriteStringPred, Strs, $io, $=io).
>
> This is terrible! I make good use of higher order
> programming and I'm hampered enough as it is by the
> mode system (the polymorphic modes extension is
> eagerly awaited) without having to jump through hoops
> like this one!
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).
but the ", $io, $=io" notation is sufficiently concise that there is
no need.
Using conversion functions like this is in fact closer to the typical
Haskell style; the Haskell people call their equivalent of functions
like `io2p' and `p2io' "monad transformers", I believe.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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