[m-dev.] op/3 syntax and semantics

Julien Fischer juliensf at cs.mu.OZ.AU
Mon Feb 20 17:32:16 AEDT 2006


On Mon, 20 Feb 2006, Peter Schachte wrote:

> On Wed, Feb 01, 2006 at 04:35:40PM -0500, doug.auclair at logicaltypes.com wrote:
> >
> > Fergus asked for a semantic and syntactic definition of the op/3
> > declaration.  Since it is implemented the same way in Mercury as it is
> > in Prolog (except the extent of the effect: in Mercury I've limitted
> > its extent to the module in which it is declared.
>
> This seems too restrictive to me.  I've never found an operator useful
> enough to bother to define it if I just want it in one module.
> However, I've defined many operators to be used in clients of a module
> I've developed.
>
> Limiting an operator to the module that defines it means that every
> client of a module that defines an operator for an exported predicate,
> function, or constructor will have to include an op declaration in
> addition to importing the module (or else not use the operator).  This
> seems stylistically wrong:  to use the features of a module, I
> shouldn't have to do anything but import it.
>
> > Prolog's op/3 has
> > universal extent (I consider this to be a misfeature, but this cannot
> > be helped: the Prolog module system was an afterthought, added long
> > after op/3, so there is a corpus of Prolog code that depend on this
> > misfeature.  Ugh!)).
>
> Prolog definitely got it wrong.  A big problem in Prolog is that, eg,
> if module b defines operator o and some other module m says:
>
> 	:- use_module(a).
> 	:- use_module(b).
> 	:- use_module(c).
>
> then operator o is visible in c when loaded by m, but not when
> separately compiling c.  Worse yet, if the user reloads m, then o is
> visible when loading a.  If a or c uses o as an ordinary symbol, this
> may cause syntax errors in a or c when compiling m that do not occur
> when compiling them separately.  This has caused me trouble more than
> once.  But what Prolog does get right is that the rest of module m can
> use operator o.  This can't cause problems because m depends on b.
>
> The correct thing for Mercury, I believe, is for operators defined in
> the interface section to be usable in terms appearing later in that
> file, as well as terms appearing after an import of that module in
> other files.  Basically, the operator defintion of a symbol should be
> visible everywhere its predicate, function, or constructor definition
> is.  Eg, if the interface section of module m contains
>
> 	:- op(700, xfx, !=).
> 	:- pred T:in != T:in is semidet.
>
> 	X != Y :- \+ X = Y.
>
> then any file that contains
>
> 	:- import_module m.
>
> should be able to use operator != anywhere after the import_module
> declaration.  I would expect this could be implemented by including
> the op declaration in the interface file for m.

Cast your mind back to 1999.  It's not quite that simple, at least with
the current system of interfaces files that we use:

<http://www.cs.mu.oz.au/research/mercury/mailing-lists/mercury-developers/mercury-developers.9907/0095.html>

> I believe what you're proposing is the right thing to do for operators
> declared in the *implementation* section, though.

What Doug is proposing, I think, is that the `:- op' directives would
not be exported to sub-modules, which differs from the usual Mercury
visibility rules, i.e. that entities defined in the implementation
section of a parent module are visible in its children.

Julien.

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