[mercury-users] mercury-extras/posix comments, !Question, musing.
Julien Fischer
juliensf at csse.unimelb.edu.au
Mon Feb 12 14:54:03 AEDT 2007
On Sun, 11 Feb 2007, Julian Fondren wrote:
...
> The posix comments:
>
> 1. I had to comment out EBADMSG in posix.m to get it to build,
> and I see other comments there for presumably other
> discovered-nonuniversables. The attached gen_errno.m will
> print out a C program which itself will print out a list of
> (a subset of posix.m's) values of errno that exist. You
> might modify gen_errno.m to generate an errno_table.m which
> posix.m can include as a fact table (17.1 of Langref).
If you're using a recent rotd then there's no point in using a fact table.
Any functionality that was provided by fact tables has been merged into the
compiler. (We haven't announced that yet since the new code has been around
that long and we're waiting to see if it has any problems).
Concerning the posix binding, it's fairly old and may indeed be suffering
some bitrot (not to mention some portability problems).
...
> The state variable question:
>
> 1. In the attached gen_errno.m, I have this code:
>
> main -->
> % ...
> { errno(L) },
> write_errnos(L),
> % ...
>
> :- pred write_errnos(list(string)::in, io::di, io::uo) is det.
> write_errnos(!.L, !IO) :-
> list.map(format_errno, !L),
> dump_errnos(!.L, !IO).
>
> I wanted to have this instead:
>
> :- pred write_errnos(io::di, io::uo) is det.
> write_errnos(!IO) :-
> errno(!.L),
> list.map(format_errno, !L),
> dump_errnos(!.L, !IO).
State variables not in the head of a clause need to be introduced via
an explicit existential quantification, e.g.
write_errnos(!IO) :-
some [!L] (
errno(!:L),
list.map(format_errno, !L),
dumpe_errnos(!.L, !IO)
).
> but I get several errors complaining about the visibility of
> !.L and !:L , as in:
>
> gen_errno.m:022: Error: state variable !.L is not visible in this context.
>
> So, apparently the head of a predicate is more special as a
> source of state variables than a random predicate -- but why?
Section 2.10 of the reference manual.
>
>
> (and also:)
>
> FWIW, I really enjoy code like this compressed example, from
> echoserv.m :
>
> :- pred echo(fd::in, io::di, io::uo) is det.
> echo(Sock, !IO) :-
> text.create(4096, 0, Buf),
> echo(Sock, Buf, !IO).
>
> :- pred echo(fd::in, text.text::di, io::di, io::uo) is det.
> echo(Sock, !.Buf) -->
> posix.read.read(Sock, 4096, Res, !Buf),
> write(Sock, ReadCount, !Buf, Res1),
> echo(Sock, !.Buf).
>
> Although that's also interesting in that I thread 5 values,
> counting the socket, through these functions. ... I think
> I can stuff all of that into a single !State, with help from
> c_code, but I'd need to separate out the IO state whenever
> I left dealing-with-the-client world.
The compiler has an optimization that will do this for you (--tupling)
although it's currently limited to code within modules. Note though,
that there is no real benefit in doing this if you are constantly
packing and unpacking the state argument.
As a general principle, putting the I/O state inside anything is not
a good idea because (1) it makes the code quite obscure and (2) you
tend to end up with all sorts of odd errors concerning uniquness.
There's no efficiency gain doing so with the I/O state anyway since
arguments of that type aren't actually passed as arguments in the
generated C code (in fact don't exist in the generated C code.)
Julien.
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to: mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions: mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the users
mailing list