[m-users.] parsing, seeking advice on simple combinator project and also operators.

Julien Fischer jfischer at opturion.com
Sun Oct 30 13:33:53 AEDT 2022



On Sat, 29 Oct 2022, Sean Charles (emacstheviking) wrote:

> I have spent a goodly few days on and off reading the xml.parser.m file in the extras folder for some insights but whoever wrote that is light years ahead of
> me, it's been hard to follow at best.
> 
> I also returned to reading the code for mmc-doc, another good source of inspiration, in particular I tried to adapt this code but I don't think I filly
> understand yet how Mercury does higher-order functions, nor do I fully understand modes/insts when related to HOP.
> 
> Here is the code, it provides (file: config.m) a function '//' that allows chaining, which is what I am trying to do:
> 
> :- type maybeio == (pred(maybe(string), io, io)).
> :- inst maybeio == (pred(out, di, uo) is det).
> :- func (maybeio::in(maybeio)) // (maybeio::in(maybeio))
>     = (maybeio::out(maybeio)).
> A // B = C :-
>     C = (pred(Res::out, !.IO::di, !:IO::uo) is det :-
>         A(Res1, !IO),
>         (
>             Res1 = Res @ yes(_)
>         ;
>             Res1 = no,
>             B(Res, !IO)
>         )).
> 
> I can see that the chain is started further down:
> 
>         GetConfig = get_environment_var("XDG_CONFIG_HOME")
>             // get_environment_var("APPDATA")
> :
> :
> 
> I see that the definition of '//' is such that it expects predicates on both sides and that they are executed -inside- the implementation of the function i.e.
> the get_environment_var() is not called at that point in the code but is in fact passed in as an argument to '//', and then executed by the line 'A(Res1, !IO)'
> or 'B(Res,!IO)', that much I have understood. Hope resigns supreme.
> 
> How did the author know to use '//'?  Given that Mercury doesn't allow arbitrary strings of non-alpha characters to be used as a function/operator name like
> Prolog. On page 6, section 2 'Operators' (reference manual), there is a huge list of operators but it isn't obvious where to look for the module that defines
> them, I am assuming that '//' is used in a module NOT imported into the source file but is recognised by the parser? How does one know what operators can be
> used for ones own purposes, I managed to find that '//' and '**' worked for me but I am not sure what they do, I am guessing that '**' is 'power' or
> 'exponential' ?

That section of the reference manual was re-written recently.  If you
have a look at the ROTD version, you'll find the explanation:

     Note that operators are a syntactic concept. The ‘+’ infix operator, for
     example, is only a symbol; it does not mean addition unless you write or
     import code that defines it as addition. Modules in the Mercury standard
     library, such as int and float, provide such arithmetic definitions. To
     illustrate further, the ‘-’ infix operator is defined as subtraction by
     those modules but is defined as a pair constructor by the pair module.

Julien.


More information about the users mailing list