for review: Add implementation of reference types, plus examples
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Jan 27 17:55:17 AEDT 1998
On 27-Jan-1998, Peter Schachte <pets at cs.mu.OZ.AU> wrote:
> max_of.m an example of non-backtrackable references
> maxtest.m test case for max_of.m
>
> reftest.m tests of reference.m, nb_reference.m
> and scoped_update.m
For consistency with the naming conventions used elsewhere,
I would prefer it if these were instead called `test_max_of'
and `test_ref' (or perhaps `test_refs').
> New File: extras/references/README
> ===================================================================
> This directory contains two impure reference type modules, and a
> module that allows scoped non-backtrackable update, plus two
> example modules using these types. These serve as an example of
> impure coding. Generally this sort of coding is not necessary, and it
> can be quite tedious and error-prone, but occasionally it may permit
> greater efficiency than using pure Mercury code, or may permit you to
> write in Mercury what you would otherwise have to write in C.
It would be helpful to explain briefly here what is meant by "impure"
coding, and/or to give a pointer to the "Impurity" section
in the Mercury language reference manual.
> % Copyright (C) 1997 University of Melbourne.
s/1997/1998/g
(Check all the files)
> :- pred between(int, int, int).
> :- mode between(out, in, in) is nondet.
>
> between(I, Low, High) :-
> Low =< High,
> ( I = Low
> ; between(I, Low+1, High)
> ).
I've implemented that too often myself.
That predicate is worth putting in library/int.m, I think.
The following implementation
between(I, Low, High) :-
( Low = High ->
I = Low
;
Low < High,
(
I = Low
;
Low1 is Low + 1,
between(I, Low1, High)
)
).
creates fewer choice points, so it is probably a better choice
for a standard library implementation of it.
> New File: extras/references/nb_reference.m
> % File : nb_reference.m
...
> % Note that in order to use this module, you *must* compile with the
> % --use-trail switch.
Why? Is that a cut-and-paste error?
> :- pragma c_header_code("
> #include <mercury_memory.h>
> #include <mercury_deep_copy.h>
...
> global_heap = create_zone(""global_heap"", 1, global_heap_size,
> next_offset(), global_heap_zone_size, default_handler)
Hmm, this is using some undocumented interfaces to the Mercury runtime.
I suggest that
(1) to ensure that this doesn't suffer from the otherwise
inevitable software rot, you need to modify tools/test_mercury
to run your test cases
and
(2) it might be a good idea to put this stuff in the Mercury
runtime, and have extras/references/nb_reference.m use
a higher-level interface.
> % File : reference.m
I would insert
This module is implemented using the trailing
features described in the "Trailing" subsection of the
"C interface" section of the "Pragmas" chapter of the
Mercury Language Reference Manual.
somewhere appropriate.
> :- module reference.
> :- interface.
>
> % A backtrackably destructively modifiable reference type.
> :- type reference(T).
>
> % Create a new reference given a term for it to (initially) refer to.
> :- impure pred new_reference(T::in, reference(T)::out) is det.
>
> % Get the value currently referred to by a reference.
> :- semipure pred value(reference(T)::in, T::out) is det.
>
> % (backtrackably) modify a reference to refer to a new object.
> :- impure pred update(reference(T)::in, T::in) is det.
>
> :- implementation.
>
> :- type reference(T) == c_pointer.
Currently there's a compiler bug which means that using equivalence types
in this way doesn't work. If you didn't find this, then your testing
wasn't thorough enough ;-)
The work-around is to put this type definition in the interface
rather than the implementation.
> :- pragma inline(new_reference/2).
> :- pragma c_code(new_reference(X::in, Ref::out), will_not_call_mercury, "
> {
> incr_hp(Ref, (sizeof(reference)+sizeof(Word)-1)/sizeof(Word));
Must be time we had `incr_hp_bytes'...
> % File : reftest.m
> % Authors : pets (Peter Schachte)
> % Stability : low
The "Stability" comments in the Mercury library modules are supposed to refer
to the stability of the module's interface. It doesn't make much sense
to use them for test modules.
Can you please send another diff when you've addressed these comments?
Thanks,
Fergus.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list