[m-rev.] diff: Implemented review comments.

Paul Bone pbone at csse.unimelb.edu.au
Thu Oct 7 16:01:39 AEDT 2010


Implement review comments from my previous change.

extras/lazy_evaluation/README:
    Note that lazy.m is now in the standard library.

extras/lazy_evaluation/lazy.m:
library/Mercury.options:
NEWS:
    Implemented review comments from my previous change.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.536
diff -u -p -b -r1.536 NEWS
--- NEWS	7 Oct 2010 02:38:09 -0000	1.536
+++ NEWS	7 Oct 2010 04:00:37 -0000
@@ -16,8 +16,9 @@ Changes to the Mercury standard library:
   to the predicates of the same name in the list module, but do the relevant
   operations on keys instead of entire list elements.
 
-* We have added a new module, lazy,to the standard library.  It facilitates
-  the construction of lazy data structures.
++ We have moved the lazy evaluation module out of the extras distribution and
+  into a new standard library module called `lazy'.  It has also been made
+  backend-agnostic.
 
 * We have added a new predicate to the list module of the standard library.
   list.member_index0/3.  It is like list.member/2 except that it also takes a
Index: extras/lazy_evaluation/README
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/lazy_evaluation/README,v
retrieving revision 1.2
diff -u -p -b -r1.2 README
--- extras/lazy_evaluation/README	5 Jan 2000 03:52:51 -0000	1.2
+++ extras/lazy_evaluation/README	7 Oct 2010 03:57:01 -0000
@@ -9,10 +9,6 @@ lazy evaluation requires the creation or
 
 This directory contains the following files:
 
-	lazy.m:
-		This module defines the lazy(T) type, and the force/1
-		and delay/1 functions.
-
 	lazy_list.m:
 		This module defines a type lazy_list(T) using the lazy(T) type,
 		and also defines a few functions and predicates that operate
@@ -22,6 +18,12 @@ This directory contains the following fi
 		This is just a very simple example showing the use of lazy
 		lists.
 
+Mercury's standard library contains.
+    
+    lazy.m:
+		This module defines the lazy(T) type, and the force/1
+		and delay/1 functions.
+
 In comparison with lazy functional languages, the disadvantage of our
 approach is that inserting the lazy(T) types and the explicit calls to
 force/1 and delay/1 requires additional work when you are writing your
Index: extras/lazy_evaluation/lazy.m
===================================================================
RCS file: extras/lazy_evaluation/lazy.m
diff -N extras/lazy_evaluation/lazy.m
--- extras/lazy_evaluation/lazy.m	5 Aug 2010 06:55:43 -0000	1.6
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,151 +0,0 @@
-%---------------------------------------------------------------------------%
-% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
-%-----------------------------------------------------------------------------%
-% Copyright (C) 1999, 2006, 2009-2010 The University of Melbourne.
-% This file may only be copied under the terms of the GNU Library General
-% Public License - see the file COPYING.LIB in the Mercury distribution.
-%-----------------------------------------------------------------------------%
-%
-% lazy.m - provides support for optional lazy evaluation.
-%
-% Author: fjh.
-% Stability: medium.
-%
-% This module provides the data type `lazy(T)' and the functions
-% `val', `delay', and `force', which can be used to emulate lazy
-% evaluation.
-%
-% Note that laziness is most useful for recursive data types,
-% and for that case, you can't just use e.g. `lazy(list(T))',
-% since that would only be lazy at the top-level; instead
-% you need to define a new recursive data type lazy_list(T)
-% which uses lazy(T) for the recursion.  See the module
-% `lazy_list.m' for an example of how to do this.
-%
-% See the file README in this directory for additional documentation.
-%
-%-----------------------------------------------------------------------------%
-
-:- module lazy.
-:- interface.
-
-    % A lazy(T) is a value of type T which will only be evaluated on
-    % demand.
-    %
-:- type lazy(T).
-% :- inst lazy(I).
-
-    % Convert a value from type T to lazy(T)
-    %
-:- func val(T) = lazy(T).
-
-    % Construct a lazily-evaluated lazy(T) from a closure
-    %
-:- func delay((func) = T) = lazy(T).
-
-    % Force the evaluation of a lazy(T), and return the result as type T.
-    % Note that if the type T may itself contains subterms of type lazy(T),
-    % as is the case when T is a recursive type like the lazy_list(T) type
-    % defined in lazy_list.m, those subterms will not be evaluated --
-    % force/1 only forces evaluation of the lazy/1 term at the top level.
-    %
-:- func force(lazy(T)) = T.
-
-%-----------------------------------------------------------------------------%
-%
-% The declarative semantics of the above constructs are given by the
-% following equations:
-%
-%   val(X) = delay((func) = X).
-%
-%   force(delay(F)) = apply(F).
-%
-% The operational semantics satisfy the following:
-%
-% - val/1 and delay/1 both take O(1) time and use O(1) additional space.
-%   In particular, delay/1 does not evaluate its argument using apply/1.
-%
-% - When force/1 is first called for a given term, it uses apply/1 to
-%   evaluate the term, and then saves the result computed by destructively
-%   modifying its argument; subsequent calls to force/1 on the same term
-%   will return the same result.  So the time to evaluate force(X), where
-%   X = delay(F), is O(the time to evaluate apply(F)) for the first call,
-%   and O(1) time for subsequent calls.
-%
-% - Equality on values of type lazy(T) is implemented by calling force/1
-%   on both arguments and comparing the results.  So if X and Y have type
-%   lazy(T), and both X and Y are ground, then the time to evaluate X = Y
-%   is O(the time to evaluate (X1 = force(X)) + the time to evaluate
-%   (Y1 = force(Y)) + the time to unify X1 and Y1).
-%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-:- interface.
-    
-    % Note that we use a user-defined equality predicate to ensure
-    % that unifying two lazy(T) values will do the right thing.
-    %
-:- type lazy(T) ---> value(T) ; closure((func) = T)
-    where equality is equal_values.
-    
-:- inst lazy(I)
-    --->    value(I)
-    ;       closure(((func) = out(I) is det)).
-
-:- pred equal_values(lazy(T)::in, lazy(T)::in) is semidet.
-
-:- implementation.
-
-equal_values(X, Y) :-
-    force(X) = force(Y).
-
-%-----------------------------------------------------------------------------%
-
-val(X) = value(X).
-delay(F) = closure(F).
-
-    % If the compiler were to evaluate calls to delay/1 at compile time,
-    % it could put the resulting closure/1 term in read-only memory,
-    % which would make destructively updating it rather dangerous.
-    % So we'd better not let the compiler inline delay/1.
-    %
-:- pragma no_inline(delay/1).
-
-%-----------------------------------------------------------------------------%
-
-    % The promise_equivalent_solutions scope is needed to tell the compiler
-    % that force will return equal answers given arguments that are equal
-    % but that have different representations.
-    %
-force(Lazy) = Value :-
-    promise_pure (
-        promise_equivalent_solutions [Value]
-        (
-            Lazy = value(Value)
-        ;
-            Lazy = closure(Func),
-            Value = apply(Func),
-
-            % Destructively update the Lazy cell with the value to avoid
-            % having to recompute the same result next time.
-            impure update_in_place(Lazy, value(Value))
-        )
-    ).
-
-    % Note that the implementation of this impure predicate relies on
-    % some details of the Mercury implementation.
-    %
-:- impure pred update_in_place(lazy(T)::in, lazy(T)::in) is det.
-
-:- pragma foreign_proc("C", 
-    update_in_place(HeapCell::in, NewValue::in),
-    [will_not_call_mercury],
-"
-    /* strip off tag bits */
-    MR_Word *ptr = (MR_Word *) MR_strip_tag(HeapCell);
-    /* destructively update value */
-    *ptr = NewValue;
-").
-
-%-----------------------------------------------------------------------------%
Index: library/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mercury.options,v
retrieving revision 1.34
diff -u -p -b -r1.34 Mercury.options
--- library/Mercury.options	7 Oct 2010 02:38:10 -0000	1.34
+++ library/Mercury.options	7 Oct 2010 04:02:18 -0000
@@ -92,5 +92,5 @@ MCFLAGS-bitmap += --no-erlang-native-cod
 
 # Work around a warning for termination analysis of the user defined equality
 # and comparison code for lazy values.
-MCFLAGS-lazy += --no-halt-at-warn
+MCFLAGS-lazy += --no-warn-non-term-special-preds
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20101007/1e984689/attachment.sig>


More information about the reviews mailing list