[m-dev.] for review: add lazy evaluation to library

Peter Schachte schachte at cs.mu.OZ.AU
Wed Mar 10 15:31:00 AEDT 1999


Firstly, I agree with Lee that the utility of this module may be
suspect.  I think an example or two would go a long way.  Particularly
an example of a lazy list generator.  Maybe the classic Sieve of
Eristoths -- Eris -- Whatsisname?

> Index: NEWS
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/NEWS,v
> retrieving revision 1.132
> diff -u -u -r1.132 NEWS
> --- NEWS	1998/12/06 06:23:38	1.132
> +++ NEWS	1999/03/09 23:53:46
> @@ -9,4 +16,9 @@
>    The interface is based on the C functions dlopen(), dlsym(), and co.,
>    which are supported by most modern Unix systems.
>    See the files in extras/dynamic_linking for details.
> +
> +* The debugger now supports interactive queries.
> +
> +  See the "Interactive query commands" subsection of the "Debugger commands"
> +  section of the "Debugging" chapter of the Mercury User's Guide for details.

This change doesn't really belong in this commit.


> library/lazy.m:
> :- interface.
> 
> % a lazily-evaluted value of type T
> :- type lazy(T).
> 
> % convert a value from type T to lazy(T)
> :- func val(T) = lazy(T).
> :- mode val(in) = out(lazy) is det.

I know Mercury doesn't support abstract insts, but you should at least
mention the lazy/0,1 insts here in the interface section in a comment.


> % Note that we use a user-defined equality predicate to ensure
> % that unifying two lazy(T) values will do the right thing.

Cool.

> :- pragma c_code(inst_cast(F::in) = (F2::out(lazy)),
> 	[will_not_call_mercury, thread_safe], "F = F2;").

Uh.  There really ought to be a prettier way to do this....


> % Note that the implementation of this impure predicate relies on
> % some implementation details of the Mercury implementation.

s/some implementation/some/

> :- pragma c_code(
> 	update_closure(MercuryTerm::in, NewValue::in),
> 	[will_not_call_mercury],
> "{
> 	/* strip off tag bits */
> 	Word *ptr = (Word *) strip_tag(MercuryTerm);
> 	/* destructively update value */
> 	*ptr = NewValue;
> }").

This is something, I would argue, that should be encapsulated in a
module somewhere in the standard library.  As it is, there's no
portable way to replace something with something equal, and it is
something that will come up occasionally when you have a user-defined
equality predicate for a type, and some values of that type are more
efficient in some way than others.  Sure, it's a module with an impure
interface, but it would be very useful in building efficient perfectly
pure modules.


-- 
Peter Schachte                     I disapprove of what you say, but I will
mailto:schachte at cs.mu.OZ.AU        defend to the death your right to say it.
http://www.cs.mu.oz.au/~schachte/      -- Voltaire 
PGP: finger schachte at 128.250.37.3  



More information about the developers mailing list