[m-dev.] Re: Visual vs total arity clash example [fwd]

Peter Schachte schachte at cs.mu.OZ.AU
Fri Jan 28 15:23:39 AEDT 2000

On Thu, Jan 27, 2000 at 10:24:45PM +1100, Peter Nicholas MALKIN wrote:

> 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.

No, you only need to leave all existing predicates in io.m unchanged.
I know you think those are the same statements, but they are only the
same if you assume the translation you are planning.

I would suggest that you extend io.m by adding a bunch of new
predicates like this:

	:- pred io__write_string(string::in) + hidden(changed(io)).

	io__write_string(S) -->>  io__write_string(S, $io, $=io).

I would propose that the code generated for this would be:

	io__EDCG2_write_string(S,I0,I) :-  io__write_string(S,I0,I).

With intermodule inlining, this should introduce no overhead.

> Consider the following code:
> ****************** Old Code **********************************************
> :- pred app_all(list(char), list(char), list(char), list(char)).
> :- pred app(list(char), list(char), list(char)).
> ****************** New Code **********************************************
> :- htype(list_acc, list(char)).
> :- hmode(list_acc, changed(in, out)).
> :- pred app(list(char)) +hidden(changed(list_acc)).
> **************************************************************************
> 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.

Again, this is only true if you assume the transformation you are
planning.  If you adorn the predicate name as I suggest, there is no

> > Finally, there's very little benefit to allowing users to write
> > expanded clauses, at least compared to the cost.  Can you give a
> > realistic example of a clause that's somehow better written already
> > expanded?
> Yes, I can.
> The situation where you wish to use :- instead of -->> is for pragma
> c_code.  Actually this applies always, maybe some extra syntax for
> > pragma c_code is needed here. 

I think so.

> > Here's another idea for avoiding this problem:  put each EDCG
> > predicate/function in an 'EDCG' submodule of its proper module, and
> > export it from this module to the parent module.  That way:
> I really do not think that whether a predicate uses EDCGs or not should dictate
> to the programmer where they put it in a module. This is too artificial a
> constraint that could reduce program readability.

Of course, this would only be a problem for writing whole EDCG
predicates in already expanded form.  Ordinary EDCG predicates would
not have this problem.  But, since it's currently clumsy in Mercury to
put an individual prediate into a submodule, I'll retract this
suggestion, and go back to suggesting adding 'EDCGn_' to the front of
the predicate name, where n is the number of hidden arguments.

> Documentating how the translation works is only temporary, since the backwards
> compatability requirement is only temporary too! So only for the duration of the
> backwards compatability requirement does how the translation works need to be
> documented.

I think this is unrealistic.  It's not going to get easier to
translate old DCG code to EDCGs as time goes on.  It's also very
difficult to remove documented features.  Remember the golden rule:
thou shalt not screw your customers.

> > BTW, I can't see how this is a backward compatibility issue.  All old
> > code will continue to work whichever way you do it.  It's a question
> > of new code or old code modified to use EDCG syntax.
> Easily modifying old code to interface with new code is part of backwards
> compatability. What if I want to modify an existing predicate to receive a
> hidden variable but I only want to modify the interface because propagating the
> change would be tedious and why change code that works.

I'm trying to think of a case where your approach makes it much
easier, but I can't.  Firstly, the only real reason to use EDCGs is
when you have some information that threads through multiple
predicates, so let's assume you're the arguments you're adding thread
through several predicates.  If the old code your modifying is a
regular :- clause, then you'll have to change :- to -->>, and add
+hidden(...) to the signature.  You may have to add $whatever and/or
$=whatever in a few places, but that's about it.  Alternatively, with
your approach, you could add the +hidden(...) to the signature and
thread the extra information through by yourself.  I can't see why
you'd want to do that, but suit yourself.  With my approach, you could
do that, but you'd also have to add EDCG2_ to the front of the
predicate name throughout the file.  One global replace.  BFD.

If the old code is currently a DCG, it's going to be a bit harder to
translate it.  In addition to all the above work, you'll have to add
another hidden argument for what the DCG already hides, and you'll
have to go through removing all the stupid braces, and replace [X]
goals with $whatever=[X|$=whatever].  If you don't want to translate
it, you'll have to do the same as if it were a :- clause and you
didn't want to translate it.  Again, with my proposal you'd just need
to paste 'EDCG2_' to the predicate name in addition.  Still BFD.

The advantage of this approach is that from the user's perspective a
predicate only has one arity.  Two predicates have the same name and
arity only if they look like they do.

Peter Schachte                     I disapprove of what you say, but I will
mailto:schachte at cs.mu.OZ.AU        defend to the death your right to say it.
http://www.cs.mu.oz.au/~schachte/      -- Voltaire 
PGP: finger schachte at  
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