Mercury Documentation -- Project

λ June 19, 2019
Tags: mercury

Having recently started teaching myself Mercury it has become apparent that on the one hand, I think I am really really going to like it a lot as I already know and love Prolog enough to make learning Mercury not-too-hard, I am really beginning to not like the documentation compared to other languages I use. Haskell has Hoogle/Hayoo for example. Python, Java, PHP, C++ et al… they all have pretty good online examples and core documentation pages for people to use especially when they are starting out.

Think Big or go home!

I have therefore decided to embark on a learning project for myself which will involved the following steps, and ultimately maybe I will be able to produce output that can maybe get uploaded to readthedocs.org as the final icing on the cake.

  1. Learn to load terms from a file. By using the source distribution package, I can read in the contents of a specific module and then look for the :- pred terms and put them to one side. From a cursory read, the comment blocks could also be extracted as well but for now I will settle for term extraction.

  2. Reverse a pred into English. What do I mean by this? I mean that given the formal nature of a predicate declaration through its modes and its determinism, it should be possible to produce some kind of textual description for each predicate.

  3. Produce an internal data structure As the term extraction and conversion into “something readable” takes place I will need to build some kind of a dictionary / tree as I go. Once I have parsed as many (eventually all) source modules as I need then I can use this dictionary to consider what output forms to create.

  4. Maybe scrape the comment blocks too. A simple reading of about a quarter of the source modules shows a definite coding standard has been applied (thanks for your rigour and discipline team!) so it might be helpful if this was part of the final internal data structure.

  5. Hyperlinked to source There should also be an option to produce a file:/// link to a local copy of the source code for the version you are using.

Expanding the first four points…

Loading terms from a file

Prolog, and presumably Mercury, along with LISP is a homo-iconic language. This means that the structure of the code is such that it can be loaded and manipulated with almost zero effort as the data structure and code structure are the same. I see that REBOL is also mentioned on that Wikipedia page, another language I played with at least a decade ago, that may yet get some exposure IMHO.

The libraries I will be reading closely will be:

and whatever else looks like it might be useful as well…it’s going to be a tough but enjoyable learning journey and no matter how old I get I am never too old for one of those. Especially if there are snacks along the way…

Reverse engineer a pred

If you look at a typical predicate declaration, this one for example from the io module in the text input section:

    % Read a character (code point) from the current input stream
    % or from the specified stream.
    %

:- pred read_char(io.result(char)::out, io::di, io::uo) is det.
:- pred read_char(io.text_input_stream::in, io.result(char)::out,
io::di, io::uo) is det.

you can begin to see the evil genius plan. The above is copied verbatim, and notice that the last pred is over two lines in the HTML but by using the term reading module it should all appear as a single logical term.

If you also know what det, semidet, cc_multi etc actually mean…

  • have exactly one solution, then that mode is deterministic (det);
  • either have no solutions or have one solution, then that mode is semi deterministic (semidet);
  • have at least one solution but may have more, then that mode is multi solution (multi);
  • have zero or more solutions, then that mode is nondeterministic (nondet);
  • fail without producing a solution, then that mode has a determinism of failure.

…then it becomes possible to turn the first definition above into some text along the lines of:

read_char{1} will always have a solution. It has three parameters, the first is output, the second and third are the world state.

That’s the plan!

Internal Data Structure

Well, I will at least need a dictionary (map) for holding the basic information, the key will be the predicate raw name and then a list of entries for each mode encountered.

Mercury has pretty good user type support so I may also venture down that road if it feels like the right thing to do at the time!

Scraping the comments

If I don’t like the turning-a-pred-into-text approach then there is always the option of find a pred by manually reading the file, then backtracking until the preceding comment block starts. What that means now, who knows, but the idea would be to harvest the accompanying comment block preceding the predicate definition so it can be munged out in the final wash.

Conclusion

Lots of work, fun, learning and head scratching await! As I get through this seemingly Herculean task for my small bear brain I will attempt to write it up here.

Comments