[mercury-users] Exceptions and unique modes
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Feb 22 00:21:47 AEDT 2001
On 21-Feb-2001, Peter Ross <peter.ross at miscrit.be> wrote:
> On Fri, Feb 16, 2001 at 02:01:22AM +1100, Fergus Henderson wrote:
> > On 15-Feb-2001, Peter Ross <peter.ross at miscrit.be> wrote:
> > > I am really starting to think that threaded unique objects, should be
> > > treated specially in the language, maybe with some sort of special
> > > syntax which allowed you to use one name to talk about a threaded unique
> > > object and the compiler was smart enough to do a source-to-source
> > > transformation which made this all declarative.
> >
> > Well, if using one name to talk about a threaded unique object is what
> > you want, I think you may perhaps be able to do it using mutvars
> > (see library/store.m).
> >
> > It would be nice if we were to provide something similar to that
> > but which works on the io__state rather than a separate store type.
...
> While I think this is a nice idea and the equivalent of IORef in
> Haskell, it faces the problem that we must have an io__state around to
> use it. This is an unacceptable constraint for me.
OK, so use `store' then!
We can add a cc_multi `try_store', just like `try_io', but for stores.
[Note for implementors: there is one tricky aspect. If we're not
careful, the user could use `store__extract_ref_value', which destroys
the store and extracts the referenced value without making a copy.
The user could then throw the extracted value, and if the handler gets
both the extracted value and a unique version of the store, then it
can update the reference, which would modify the extracted value,
breaking referential transparency.
In other words, with a naive implementation of `try_store',
the following program
:- module tricky.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- import_module exception, store.
:- pred tricky(store__ref(T, S), store(S), store(S)).
:- mode tricky(in, di, uo) is det.
tricky(Key, Store0, _Store) :-
store__extract_ref_value(Store0, Key, Value),
throw(Value).
main -->
{ store__new(Store0) },
{ store__new_ref(Key, "initial", Store0, Store1) },
{ exception__try_store(tricky(Key), Result, Store1, Store2) },
print("Result = "), print(Result), nl,
{ store__set_ref_value(Key, "updated", Store2, _Store) },
print("Result = "), print(Result), nl.
could print out
Result = exception(initial)
Result = exception(updated)
To avoid this, we need to make a copy of the thrown object before
returning it from try_store. We already do this in grades which
recover heap automatically on backtracking, but we'll need to do so
even in conservative GC grades.]
> Imagine the following situation:
>
> :- pred p(list(resource_requests)::in,
> map(key, resource)::di, map(key, resource)::uo) is det.
>
> p([], Map, Map).
> p([R | Rs], Map0, Map) :-
> allocate_resource(R, Resource),
> get_key(Resource, Key),
> map__det_insert(Map0, Key, Resource, Map).
`Rs' is a singleton variable. I think you missed a recursive call
here. Probably you intended that last line to be
map__det_insert(Map0, Key, Resource, Map1),
p(Rs, Map1, Map).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list