[mercury-users] Event handling in mercury
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Jul 17 04:04:26 AEST 2001
On 16-Jul-2001, Ralph Becket <rbeck at microsoft.com> wrote:
> > From: Fergus Henderson [mailto:fjh at cs.mu.OZ.AU]
> > Sent: 16 July 2001 16:45
> >
> > That's a good idea. It's one that has been on my to-do list for quite
> a while,
> > but for various reasons I haven't found time for it.
> > [...]
> > I think it would be enough to just do it like this:
> >
> > :- module io_store. % compare module store
> > :- interface.
> >
> > :- import_module store. % type store__mutvar(T,S).
> > :- import_module io. % type io__state.
> >
> > :- type io_store.
> >
> > :- pred io_store__new_mutvar(T,mutvar(T, io_store), io__state,
> io__state).
> > :- mode io_store__new_mutvar(in, out, di, uo) is det.
> >
> > :- pred io_store__get_mutvar(mutvar(T, io_store), T, io__state,
> io__state).
> > :- mode io_store__get_mutvar(in, out, di, uo) is det.
> >
> > :- pred io_store__set_mutvar(mutvar(T, io_store), T, io__state,
> io__state).
> > :- mode io_store__set_mutvar(in, in, di, uo) is det.
:- type global(T) == mutvar(T, io_store).
> I don't think that's the right interface. The problem is that
> once you've created a new mutvar you have to pass it around
> *in addition* to the io__state in order to get at its contents,
> which doesn't seem to be in the spirit of global variables.
Well, one way to hack around that is as follows:
to define a global variable `foo' with initial value 42,
write code like so:
:- interface.
:- func foo = global(int).
:- implementation.
:- pragma memo(foo/0).
:- pragma promise_pure(foo/0).
foo = Foo :-
impure unsafe_perform_io(io_store__new_mutvar(42), Foo).
Of course, that's rather ugly, which kind of defeats the purpose.
It's better than using extras/references, since the ugliness is
encapsulated within the definition of foo/0. But still, we ought
to be able to do better than that.
So to make this elegant, I've been thinking about a language
extension that would allow you to write
:- interface.
:- global foo = int.
:- implementation
foo := 42.
or something like that (probably you can think of a better syntax for it),
with the same effect as the code above.
> I'd rather be able to access globals by name (string or int, say)
> which I could define by convention in my application. The interface
> would look something like this:
>
> :- type global_name == string.
>
> :- pred io__init_globals(io__state::di, io__state::uo) is det.
> :- pred io__get_global(global_name::in, univ::out, io__state::di,
> io__state::uo) is det.
> :- pred io__set_global(global_name::in, univ::in, io__state::di,
> io__state::uo) is det.
>
> [obvious implementations...]
Tom Conway implemented something like that a while back.
The drawbacks of this approach are that
- it's not as efficient:
you pay the cost of a symbol table lookup
for every global variable access)
- it's not as safe:
there's no compile-time check that the global variable names are used
consistently, or that you initialize every global variable before
trying to use it.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | 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