[m-dev.] Re: Visual vs total arity clash example [fwd]
Ralph Becket
rbeck at microsoft.com
Fri Jan 28 03:52:12 AEDT 2000
> Fact: to allow for *OLD* code using DCGs or code written
> explicitly using
> io__state, to still work with the new io.m predicates that
> use EDCGs I must
> allow EDCG predicates to be called in expanded form.
Can someone remind me again why EDCGs are not just a simple
source transformation and hence why there should be any problem
with integrating EDCG code with plain code? I really don't
have a problem (in fact I think it's a Good Thing) that the
hidden arguments be expanded in the order in which they are
declared.
> :- htype(list_acc, list(char)).
> :- hmode(list_acc, changed(in, out)).
>
> :- pred app(list(char)) +hidden(changed(list_acc)).
> :- mode app(in) is det.
>
> app([]).
> app([C | Cs]) -->>
> app(Cs),
> $=list_acc = [C | $list_acc].
I hope this is just a demonstration and not a suggested coding
style :) Here EDCGs have made things worse rather than better.
> But I would argue that (unlike DCGs) there's no reason to allow users
> to write EDCG clauses fully expanded. Firstly, everything that can be
> done by writing clauses directly can also be done with EDCG syntax.
I think the above example proves that this is not good. I may well
want to use app/3 with a list_acc, but I certainly don't want to have
to implement it using EDCGs nor do I want to be constrained as to
when and where I can call it.
> Now although there is no visual arity conflict here there is
> an ambiguity error
> because the compiler does not know, even based upon types
> whether the call
> within the old that the call to app/3 is a call to the old
> app/3 or the new
> app/1 with total arity 3 because it could be a call to app/1
> in expanded form.
Hmm. Given the existing code
:- pred app(list(T), list(T), list(T)).
:- mode app(in, in, out) is det.
app([], Xs, Xs).
app([C | Cs], Xs, Ys) :- app(Cs, [C | Xs], Ys).
might I not just add declarations (generalising slightly)
:- htype(list_acc(T), list(T)).
:- pred app(list(T)) + hidden(changed(list_acc(T))).
The compiler can verify that this declaration is subsumed
(or equivalent to) the existing non-EDCG one. This would
require that the EDCG expansion not play silly buggers with
the argument ordering, of course. Under this scheme,
a pred declaration including hidden/N *on its own* would
simply allow this predicate to be called in EDCG code.
A pred definition using -->> would be expanded, of course.
{REQUEST: can we change `changed' to `changes'? It's a
declaration, not a statement.)
Question: above I used a polymorphic htype - I presume that's
all right?
> > ...Yes, this can all be explained,
> > and it's not terribly difficult, but I see no reasons for users to
> > have to understand these complications. More importantly, by
> > explaining them, you lock yourself into one implementation strategy
> > when there may be better approaches.
I so disagree with this! All we're doing is providing a means of
omitting (multiple) state threads when including them would only
obfuscate the code. I feel very strongly that we should keep this
simple and understandable - the idea od threading extra arguments
through code is not hard on the programmer: in many respects it's
a scoping mechanism. More to the point, if you change the order of
hidden arguments between one release of the compiler and the next,
then all sorts of libraries will have to be recompiled in order to
guarantee that arguments are passed in the right order. By far the
simplest solution is to (a) make the translation obvious and (b)
keep the arguments in the order in which they are declared.
Ralph
--------------------------------------------------------------------------
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