Tech News
← Back to articles

A tutorial for the Mercury programming language

read original related products more articles

With Mercury, the entry point (e.g. main in C) must be defined as a main/2 , i.e. main with 2 parameters. If you attempt to define main as anything else, you would get a compile error:

% mmc ./rall.m /usr/bin/ld: rall_init.o: in function `mercury_init': rall_init.c:(.text+0x4a0): undefined reference to `' collect2: error: ld returned 1 exit status

The two parameters of this main/2 must be of type io.state . If you don't define it as io.state , you would get a compile error:

./rall.m:005: Error: `main'/2 must have mode `(di, uo)'. ./rall.m:005: Error: both arguments of `main/2' must have type `io.state'.

So we now have the first few lines of Mercury:

:- interface . % NOTE: to use io.state we must import the io module. :- import_module io. :- pred main(io. state , io. state ).

You might wonder what exactly is io.state and why main needs two of them. We will explain this later. At the very least, these are not the argc argv thing you would see in C. There are dedicated predicates for retrieving command line arguments; we will get to that later.

The (di, uo) part needs explanation. The message says it's a mode. What is a mode? Modes are things that describe the change of instantiatedness before and after the execution of a goal. Instantiatedness - that's a long word. What is instantiatedness? Roughly speaking, it's a concept for describing whether a slot is free or bound. (In Mercury, instantiatedness is actually a tree, because obviously you'd have - or at the very least you could manually construct - terms that are only bounded at certain parts.) Two kinds of basic instantiatedness exists in Mercury: free , which refers to variables that are not bound by any values; bound , which means that the term is not a variable but rather some concrete term at least at that level. Consider the term blah(A, b) ; it's bound at the top (with blah ) and at one of the children node (at b ) but free at another children node (at A , provided that A does not have a value already). A mode, ground , also exists, and refers to the terms that are completely bound (e.g. blah(a, b) is ground but blah(A, b) isn't, provided that A is still free .)

With this knowledge, we should first understand what in and out modes actually are. If you have worked with some other languages you might have seen thing similar to this before: C libraries often ask you to pass in a reference for retrieving the actual result because the return value is used for returning error status; you can think of it as "in" (inputting) parameters and "out" (returning) parameters; some languages (e.g. Ada) even explicitly label them as such. I do not wish to introduce you to wrong analogies that will become detrimental for your future learning, but I have to say they do be somewhat similar.

That said, in and out is properly defined in Mercury, as follows:

... continue reading