[m-users.] di / uo -- some clarification please.

Julian Fondren jfondren at minimaltype.com
Tue Aug 6 05:37:06 AEST 2019


On 2019-08-05 14:07, Julian Fondren wrote:
> Anyway, I'd gotten the impression from somewhere that uniqueness
> wasn't something you can really exploit in Mercury for your own
> code. I'm not sure why, but note that even the array stdlib module
> punts on ui/uo modes:
> 

Long example, so not indented. Since it's not required that unique
variables end up inst 'dead' before the program ends, it's not an
error to comment out out the close/3.

So uniqueness is not enough. You could still do something like a
'with_open' that accepts a predicate, and requires that the unique
value be given back to it by the predicate.

And, I might've gotten that impression from the language reference:

"We have not yet implemented unique modes fully, and the details
are still in a state of flux. So the following should be considered
tentative."


:- module safeopen.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.

:- type fd == int.
:- type result
     --->    ok(fd)
     ;       error.
:- inst result for safeopen.result/0
     --->    ok(unique)
     ;       error.

main(!IO) :-
     open_append("test.log", Res, !IO),
     (
         Res = ok(Fd),
         writeln(Fd, "Hello, world", !IO),
         writeln(Fd, "Hello again", !IO)
         %close(Fd, !IO)
     ;
         Res = error
     ).

:- pragma promise_pure open_append/4.
:- pred open_append(string::in, safeopen.result::out(safeopen.result),
     io::di, io::uo) is det.
open_append(Filename, Res, !IO) :-
     ( if impure open_append_2(Filename, Fd) then
         Res = ok(Fd)
     else
         Res = error
     ).

:- pragma foreign_decl("C", "
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
").
:- impure pred open_append_2(string::in, fd::uo) is semidet.
:- pragma foreign_proc("C",
     open_append_2(Filename::in, Fd::uo),
     [will_not_call_mercury],
"
     Fd = open(Filename, O_WRONLY | O_APPEND | O_CREAT, 0644);
     SUCCESS_INDICATOR = Fd >= 0;
").

:- pred writeln(fd::ui, string::in, io::di, io::uo) is det.
:- pragma foreign_proc("C",
     writeln(Fd::ui, String::in, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure],
"
     dprintf(Fd, ""%s\\n"", String);
").

:- pred close(fd::di, io::di, io::uo) is det.
:- pragma foreign_proc("C",
     close(Fd::di, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure],
"
     close(Fd);
").


More information about the users mailing list