[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