Remove old .cvsignore files, moving their contents to .gitignore files.
There are now no .cvsignore files in the repository.
I've also sorted some .gitignore files and avoided repeating a pattern in a
subdirectory's .gitignore file when it is already mentioned in the parent
.gitignore file.
samples/concurrency/midimon/concurrent_stream.m:
Conform to the current version of the standard library.
samples/concurrency/midimon/midi.m:
samples/concurrency/midimon/midimon.m:
samples/concurrency/dining_philosophers/philo.m:
samples/concurrency/dining_philosophers/philo2.m:
samples/concurrency/dining_philosophers/philo3.m:
Syntax and formatting fixes.
samples/java_interface/java_calls_mercury/*.m:
Use spaces instead of tabs.
Delete trailing whitespace.
Fix a cut-and-paste error where exports to C instead of
Java are referred to.
samples/java_interface/mercury_calls_java/Makefile:
Fix the compilation options for this example.
samples/java_interface/mercury_calls_java/mercury_main.m:
Fix formatting.
benchmarks/progs/quicksort/qs_always_par.m:
benchmarks/progs/quicksort/qs_utils.m:
extras/moose/check.m:
extras/posix/samples/mdprof_cgid.m:
extras/xml/parsing.m:
samples/muz/zparser.m:
samples/muz/ztype_op.m:
As above -- the compiler now rejects determinism declarations on
non-predmode predicate declarations.
Replace a call to bitmap.new with bitmap.init.
samples/Mmakefile:
Add the beer program to list of targets.
samples/*.m:
Convert (C->T;E) to (if C then T else E).
Delete trailing whitespace.
Use predmode syntax instead of separate pred and mode
declarations.
samples/interpreter.m:
Fix up one predicate that had some clauses that used
DCGs and others that used state variables.
Don't use the name 'IO' for something that isn't the I/O state.
samples/diff/*.m:
samples/c_interface/c_calls_mercury/mercury_main.m:
samples/c_interface/short_example.m:
Delete trailing whitespace.
samples/beer.m
Add this sample.
I found the original version of this sample on 99-bottles-of-beer.net.
I've updated it, _tried_ to post a comment to 99-bottles-of-beer.net,
added it to rosetta code and thought, being a small example, that it
should also belong here.
The functions det_int_to_{binary,octal,decimal,hex)_digit/1 were supposed to
have been added at the same time as the corresponding semidet predicates but
weren't: add them.
In the char module, don't call unexpected/3 in cases where the error arises as
a result of bad inputs: throwing an exception in that case *is* expected.
library/char.m:
As above.
NEWS:
Announce the above additions.
samples/e.m:
Avoid a call to an obsolete predicate and update syntax.
This file-specific setting will override a default setting of expandtabs
in $HOME/.vimrc.
*/Makefile:
*/Mmakefile:
As above.
tests/hard_coded/.gitignore:
Don't ignore the purity subdir. This ignore must have been left over
from when purity.m was a test in hard_coded, not hard_coded/purity,
and it ignored an executable, not a directory.
samples/c_interface/standalone_c/Makefile:
samples/c_interface/standalone_c/c_main.c:
As above.
samples/c_interface/README:
s/C interface/foreign language interface/
finalisers should be executed only if main/2 returns normally, it does not
throw an exception. The C backends already do this correctly but the Java
backend did not. The C# backend has the same bug, this patch does not fix
the C# backend.
java/runtime/MercuryThreadPool.java:
Add a parameter to the shutdown() method to specify whether the backend
is aborting.
In runMain(), run finalisers only if the runtime is exiting normally.
java/runtime/MercuryRuntime.java:
Add a new finalise() method that takes a parameter allowing standalone
Java applications to specify whether or not they are aborting when the
finalise the RTS.
doc/reference_manual.texi:
Specify the behaviour of finalise directives if main/2 terminates
with an uncaught exception.
samples/java_interface/standalone_java/JavaMain.java:
Conform to changes in MercuryRuntime.java.
The thread pool code used in the Java backend was tied the execution of
main/2. However if Mercury is used as a library the thread pool won't have
been started and threads created with thread.spawn would not be executed.
This patch makes it possible to start and stop the thread pool independently of
main/2 by calling startup() and shutdown(). These calls are called
implicitly by calling runMain(). The thread pool can also be started on
demand.
This patch also adds the MercuryRuntime class, which now contains methods
that may be called by users' Java code to interact with the Mercury runtime
system, including a new finalise() method.
java/runtime/MercuryThreadPool.java:
Add startup() method.
shutdown() method is now public and it's meaning has changed, it now
requests the shutdown rather than performing it.
Renamed some variables to make their meanings clearer.
java/runtime/JavaInternal.java:
Initialise the ThreadPool and MercuryOptions objects on demand.
Make all members of this class static to avoid confusion.
Add a private constructor.
java/runtime/MercuryRuntime.java:
Add methods that can be called by Mercury users to interact with the
runtime system. Including a convenient finalise() method that does all
the finalisation.
samples/java_interface/standalone_java/mercury_lib.m:
samples/java_interface/standalone_java/JavaMain.java:
Extend the standalone Java example so that it makes use of threads: Add
a fibs function in Mercury that uses concurrency and therefore starts
the thread pool; call it from the Java code.
Use the new finalise() method from the MercuryRuntime class inside of a
finally block.
samples/java_interface/standalone_java/Makefile:
Fix a minor error.
In particular, demonstrate how to invoke any module-local finalisers and
retrieve the exit status.
samples/java_interface/standalone_java/Makefile:
samples/java_interface/standalone_java/JavaMain.java:
samples/java_interface/standalone_java/mercury_lib.m:
As above.
samples/java_interface/README:
Describe the new directory.
boehm_gc/.gitignore:
Ignore .obj files
extras/xml/xml.dtd.m:
extras/xml/xml.parse.m:
Change the name of functor ('1') in the multiplicity/0 type
to one. The former name does not (yet) work with the C# grade.
samples/.gitignore:
Ignore library output and sample executables.
samples/c_interface/standalone_c/.gitignore:
Ignore mercury_lib_int output files.
samples/c_interface/standalone_c/Makefile:
chmod 0644.
samples/c_interface/.gitignore:
Ignore object files and executables.
samples/java_interface/.gitignore:
Ignore Java class files and executables.
samples/lazy_list/.gitignore:
samples/muz/.gitignore:
samples/rot13/.gitignore:
Ignore executables.
samples/rot13/rot13_concise.m:
Update call to index_det to use string.det_index.
Added comments to clarify type inference.
samples/solutions/.gitignore:
Ignore executables.
samples/solutions/all_solutions.m:
samples/solutions/n_solutions.m:
samples/solutions/one_solution.m:
samples/solutions/some_solutions.m:
chmod 0644.
samples/solver_types/.gitignore:
Ignore executables.
samples/solver_types/sudoku.m:
Output the solution in a 3x3 grid.
runtime/mercury_mm_own_stacks.c:
Use Sleep() instead of sleep() on Windows.
Avoid warnings from the C compiler.
samples/concurrency/dining_philosophers/philo.m:
samples/concurrency/dining_philosophers/philo3.m:
Use '.' as a module qualifier in a spot.
Replace calls to obsolete predicates.
Branches: main
Add two new options to the compiler for querying what flags are passed to the
C compiler at a finer level of detail than that provided by --output-cflags.
The first new option, --output-grade-defines, prints the flags passed to the C
compiler to define the macros that specify the current compilation grade.
The second new option, --output-c-include-dir-flags, prints the flags passed
to C compiler that tell it where to search for C header files.
The rationale for the addition of the new options is that when compiling C++ or
Objective-C programs that call exported Mercury procedures via a standalone
interface we need both the flags for the grade defines and the include search
directories but other flags that we usually pass the C compiler may not be
appropriate for either a C++ or Objective-C compiler.
compiler/options.m:
Recognise the new options.
compiler/mercury_compile.m:
Handle the new options.
compiler/compile_target_code.m:
Separate out the code that generates the grade macro define
flags into a separate predicate.
Do likewise with the code that generates the flags for specifying
C compiler include search directories.
doc/use_guide.texi:
Document the new options.
samples/c_interface/standalone_c/Makefile:
Illustrate how to use the new options when compiling a program that
uses a standalone interface. Explain why it may not be appropriate
to use the output of --output-cflags when compiling code that calls
exported Mercury procedures.
samples/solver_types/Makefile:
Provide a realclean target.
samples/solver_types/Mercury.options:
Provide mmc-specific options here rather than in the
Makefile.
Use a trseg grade instad of a tr one.
Branches: main
Remove deprecated modules and (most) deprecated procedures from the standard
library. (The remaining deprecated procedures probably need to stick around
for at least another release in order to give people time to adapt their code.)
library/dir.m:
library/list.m:
library/stack.m:
library/string.m:
library/type_desc.m:
Delete obsolete procedures.
library/svarray.m:
library/svbag.m:
library/svbimap.m:
library/sveqvclass.m:
library/svmap.m:
library/svmulti_map.m:
library/svqueue.m:
library/svset.m:
library/svvarset.m:
Delete these modules, they are no longer required since the
original predicates now have their arguments in the state-variable
friendly order.
library/library.m:
Delete the above modules.
compiler/frameopt.m:
compiler/par_loop_control.m:
compiler/rbmm.region_transformation.m:
browser/browser_test.m:
extras/windows_installer_generator/wix_gui.m:
samples/ultra_sub.m:
tests/hard_coded/rnd.m:
tests/hard_coded/type_spec_ho_term.m:
tests/hard_coded/xmlable_test.m:
Conform to the above changes.
Branches: main, 11.07
Make the none.gc.memprof grade work with MSVC again.
Avoid more warnings when compiling with MSVC.
compiler/layout_out.m:
Avoid an incomplete type in the declaration of the alloc_sites
array. (Similar changes need to be made for the layout structures
related to debugging and deep profiling - I am in the process of
testing the former, the latter doesn't currently work on Windows
any way.)
browser/listing.m:
Use don't-care variables in some foreign_procs.
This avoids warnings about assignments from uninitialized
variables with MSVC.
*/.cvsignore:
Update cvsignore entries.
Ignore files generated by mprof.
extras/lazy_evaluation/*:
Removed old code.
samples/lazy_list/README:
samples/lazy_list/lazy_list.m:
samples/lazy_list/lazy_list_test.m:
Code copied from old location.
lazy_list.m has been modified to ensure that it works with the current
version of library/lazy.m
extras/README:
Removed old description of lazy_evaluation
samples/README:
Describe the exitance of samples/lazy_list
Index: extras/README
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/README,v
retrieving revision 1.29
diff -u -p -b -r1.29 README
--- extras/README 2 Aug 2011 07:55:09 -0000 1.29
+++ extras/README 29 Aug 2011 06:06:42 -0000
@@ -36,11 +36,6 @@ graphics Some packages for doing graphic
GLUT, a simplified binding to Xlib, a binding
to Allegro/AllegroGL and a Mercury binding to Cairo.
-lazy_evaluation
- Some examples of the use of the standard library's
- `lazy' module, including a module `lazy_list' that defines
- a lazy list data type.
-
lex A lexer package for Mercury that works over the I/O state,
strings, and so forth. It comes with a rich set of
standard regular expressions and the user is free to add
Index: extras/lazy_evaluation/Mmakefile
===================================================================
RCS file: extras/lazy_evaluation/Mmakefile
diff -N extras/lazy_evaluation/Mmakefile
--- extras/lazy_evaluation/Mmakefile 16 Jan 2003 10:44:17 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,11 +0,0 @@
-#-----------------------------------------------------------------------------#
-# Copyright (C) 2002-2003 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.
-#-----------------------------------------------------------------------------#
-INSTALL_PREFIX := $(INSTALL_PREFIX)/extras
--include ../Mmake.params
-default_target: all
-depend: lazy_list.depend lazy_list_test.depend
-all: liblazy_list lazy_list_test
-install: liblazy_list.install
Index: extras/lazy_evaluation/README
===================================================================
RCS file: extras/lazy_evaluation/README
diff -N extras/lazy_evaluation/README
--- extras/lazy_evaluation/README 7 Oct 2010 05:03:12 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,73 +0,0 @@
-This directory contains support for optional lazy evaluation.
-Using the modules defined here, you can write Mercury code that
-makes use of lazily evaluated data structures.
-
-Our implementation of lazy evaluation requires you to use a different
-type, lazy(T), whenever you want things to be lazily evaluated, and
-requires you to insert explicit calls to delay/1 or force/1 whenever
-lazy evaluation requires the creation or evaluation of closures.
-
-This directory contains the following files:
-
- 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
- on lazy lists.
-
- lazy_list_test.m:
- 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
-code. Fortunately the Mercury compiler's static type checking will
-ensure that the calls to force/1 and delay/1 are consistent with the
-use of lazy(T) types. But even so, putting all the calls to force/1
-and delay/1 in the right place can still be rather tedious.
-
-In return, however, we get several important advantages.
-
-The first is that there are absolutely no efficiency costs resulting
-from lazy evaluation if you don't use it. This is in contrast to many
-implementations of lazy functional languages, where you often pay a
-significant efficiency cost simply because things *might* be lazy, even
-when in actual fact they are not. Compilers for lazy functional
-languages often try to avoid these costs by performing strictness
-analysis, but current compilers can only infer strictness of functions,
-not data types; using lazy data types rather than strict data types can
-have a very large impact on efficiency (e.g. a factor of 5). Also, in
-the presence of separate compilation, compilers may need to make
-conservative assumptions about strictness.
-
-The second advantage is that the creation and evaluation of closures is
-explicit in the source code, which makes it much easier to reason about
-the performance of your programs. Programs in languages where laziness
-is the default often suffer from space leaks or unexpectedly high
-memory usage, and these problems can be _extremely_ difficult to track
-down and understand, even for very experienced programmers.
-
-The third advantage is that supporting lazy evaluation via a library
-module keeps the language and its semantics simple. We're not really
-providing lazy evaluation per se, we just _emulating_ it by passing
-lambda expressions as arguments. So the "Semantics" chapter of the
-language reference manual does not need to be modified at all.
-Supporting lazy evaluation via a library module also keeps the
-implementation simple -- the module lazy.m requires only a very
-small amount of implementation-dependent code, and none of the
-rest of the implementation need change.
-
-Our current implementation of lazy evaluation is not very efficient.
-There are several reasons for this. One is that promise_only_solution/1,
-which is used in the implementation of force/1, is currently implemented
-rather inefficiently. Another is that the lazy(T) type currently uses
-two levels of indirection, whereas it really ought to use only one.
-Finally, for maximum efficiency, we would need to inline delay/1,
-but that is not possible in the current implementation. Solving these
-latter two issues would require a bit more compiler support.
Index: extras/lazy_evaluation/lazy_list.m
===================================================================
RCS file: extras/lazy_evaluation/lazy_list.m
diff -N extras/lazy_evaluation/lazy_list.m
--- extras/lazy_evaluation/lazy_list.m 5 Aug 2010 06:55:43 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,137 +0,0 @@
-%-----------------------------------------------------------------------------%
-% vim: ts=4 sw=4 et ft=mercury
-%-----------------------------------------------------------------------------%
-%
-% This is an example of how to use the `lazy' module to define
-% a recursive lazy data type, in this case lazy lists.
-% It also defines a small number of functions and predicates
-% that operate on lazy lists.
-%
-% See also lazy_list_test.m, which is an example program using this module.
-%
-% This source file is hereby placed in the public domain. -fjh (the author).
-
-:- module lazy_list.
-:- interface.
-:- import_module lazy, int, list.
-
-%-----------------------------------------------------------------------------%
-
- % The definition of the type `lazy_list(T)':
- % A lazy lazy_list is either an empty lazy_list, denoted `[]',
- % or an element `Head' of type `T' followed by a lazily
- % evaluated tail `Tail', of type `lazy(lazy_list(T))',
- % denoted `[Head | Tail]'.
-
-:- type lazy_list(T) ---> [] ; [T | lazy(lazy_list(T))].
-
-:- inst lazy_list(I) ---> [] ; [I | lazy(lazy_list(I))].
-:- inst lazy_list == lazy_list(ground).
-
-:- inst nonempty_lazy_list(I) ---> [I | lazy(lazy_list(I))].
-:- inst nonempty_lazy_list == nonempty_lazy_list(ground).
-
-%-----------------------------------------------------------------------------%
-
- % force evaluation of (the top level of) a lazy list
-:- func force_list(lazy(lazy_list(T))) = lazy_list(T).
-:- mode force_list(in(lazy(lazy_list))) = out(lazy_list) is det.
-
-%-----------------------------------------------------------------------------%
-
- % Convert a lazy_list to an ordinary list.
-:- func to_list(lazy_list(T)) = list(T).
-:- mode to_list(in(lazy_list)) = out is det.
-
- % Convert an ordinary list to a lazy_list.
-:- func from_list(list(T)) = lazy_list(T).
-:- mode from_list(in) = out(lazy_list) is det.
-
-%-----------------------------------------------------------------------------%
-
- % A lazy_list function version of the usual append predicate:
- % append(Start, End) = List is true iff
- % `List' is the result of concatenating `Start' and `End'.
- %
-:- func append(lazy_list(T), lazy(lazy_list(T))) = lazy_list(T).
-:- mode append(in(lazy_list), in(lazy(lazy_list))) = out(lazy_list)
- is det.
-
- % member(Elem, List) :
- % True iff `List' contains `Elem'.
-:- pred member(T, lazy_list(T)).
-:- mode member(in, in(lazy_list)) is semidet.
-:- mode member(out, in(nonempty_lazy_list)) is multi.
-:- mode member(out, in(lazy_list)) is nondet.
-
-%-----------------------------------------------------------------------------%
-
- % iterate(F, X0) = [X0, F(X0), F(F(X0)), F(F(F(X0))), ...]
-:- func iterate(func(T) = T, T) = lazy_list(T).
-:- mode iterate(func(in) = out is det, in) = out(lazy_list) is det.
-
- % take(N, L) returns the first N elements of L
-:- func take(int, lazy_list(T)) = lazy_list(T).
-:- mode take(in, in(lazy_list)) = out(lazy_list) is det.
-
- % map(F, [X0, X1, X2, ...]) = [F(X0), F(X1), F(X2), ...].
-:- func map(func(X) = Y, lazy_list(X)) = lazy_list(Y).
-:- mode map(func(in) = out is det, in(lazy_list)) = out(lazy_list) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-force_list(Xs) = list_inst_cast(force(Xs)).
-
-% Because the Mercury mode system is not properly polymorphic,
-% it doesn't always infer the right inst. We sometimes need
-% to use inst casts (which can be implemented using `pragma foreign_proc').
-% :-(
-
-:- func list_inst_cast(lazy_list(T)) = lazy_list(T).
-:- mode list_inst_cast(in) = out(lazy_list) is det.
-
-:- pragma foreign_proc("C",
- list_inst_cast(F::in) = (F2::out(lazy_list)),
- [promise_pure, will_not_call_mercury, thread_safe],
-"
- F2 = F;
-").
-
-%-----------------------------------------------------------------------------%
-
-to_list([]) = [].
-to_list([X | Xs]) = [X | to_list(force_list(Xs))].
-
-from_list([]) = [].
-from_list([X | Xs]) =
- [X | delay((func) = R :- R = from_list(Xs))].
-
-%-----------------------------------------------------------------------------%
-
-append([], Ys) = force_list(Ys).
-append([X | Xs], Ys) =
- [X | delay((func) = R :- R = append(force_list(Xs), Ys))].
-
-member(X, [X | _]).
-member(X, [_ | Xs]) :-
- member(X, force_list(Xs)).
-
-%-----------------------------------------------------------------------------%
-
-map(_, []) = [].
-map(F, [H|T]) = [F(H) | delay((func) = R :- R = map(F, force_list(T)))].
-
-iterate(F, X0) = [X0 | delay((func) = R :- R = iterate(F, F(X0)))].
-
-take(_, []) = [].
-take(N, [X|Xs]) =
- (if N > 0 then
- [X | delay((func) = R :- R = take(N-1, force_list(Xs)))]
- else
- []
- ).
-
-%-----------------------------------------------------------------------------%
Index: extras/lazy_evaluation/lazy_list_test.m
===================================================================
RCS file: extras/lazy_evaluation/lazy_list_test.m
diff -N extras/lazy_evaluation/lazy_list_test.m
--- extras/lazy_evaluation/lazy_list_test.m 15 Mar 1999 08:56:59 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,27 +0,0 @@
-%-----------------------------------------------------------------------------%
-%
-% lazy_list_test.m:
-% This is a trivial example of the use of lazy lists.
-%
-% This source file is hereby placed in the public domain. -fjh (the author).
-
-:- module lazy_list_test.
-:- interface.
-:- import_module io.
-
-:- pred main(io__state::di, io__state::uo) is det.
-
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-:- import_module lazy, lazy_list, int.
-
-:- func double(int) = int.
-double(X) = 2 * X.
-
-main -->
- { L = iterate(double, 1) }, % construct an infinite list...
- { L10 = take(10, L) }, % extract the first 10 elements
- print(to_list(L10)), nl. % print them
-
-%-----------------------------------------------------------------------------%
Index: samples/README
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/README,v
retrieving revision 1.13
diff -u -p -b -r1.13 README
--- samples/README 8 Jul 2011 04:08:27 -0000 1.13
+++ samples/README 29 Aug 2011 05:47:53 -0000
@@ -72,3 +72,8 @@ muz This directory contains a syntax c
solver_types This directory contains an example solver type
implementation and some sample applications.
+
+lazy_list This directory contains an example of the lazy module
+ can be used to implement lazy data structures, in this
+ case a lazy list.
+
Index: samples/lazy_list/README
===================================================================
RCS file: samples/lazy_list/README
diff -N samples/lazy_list/README
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ samples/lazy_list/README 29 Aug 2011 05:56:20 -0000
@@ -0,0 +1,69 @@
+This directory contains support for optional lazy evaluation.
+Using the modules defined here, you can write Mercury code that
+makes use of lazily evaluated data structures.
+
+Our implementation of lazy evaluation requires you to use a different
+type, lazy(T), whenever you want things to be lazily evaluated, and
+requires you to insert explicit calls to delay/1 or force/1 whenever
+lazy evaluation requires the creation or evaluation of closures.
+
+This directory contains the following files:
+
+ 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
+ on lazy lists.
+
+ lazy_list_test.m:
+ 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
+code. Fortunately the Mercury compiler's static type checking will
+ensure that the calls to force/1 and delay/1 are consistent with the
+use of lazy(T) types. But even so, putting all the calls to force/1
+and delay/1 in the right place can still be rather tedious.
+
+In return, however, we get several important advantages.
+
+The first is that there are absolutely no efficiency costs resulting
+from lazy evaluation if you don't use it. This is in contrast to many
+implementations of lazy functional languages, where you often pay a
+significant efficiency cost simply because things *might* be lazy, even
+when in actual fact they are not. Compilers for lazy functional
+languages often try to avoid these costs by performing strictness
+analysis, but current compilers can only infer strictness of functions,
+not data types; using lazy data types rather than strict data types can
+have a very large impact on efficiency (e.g. a factor of 5). Also, in
+the presence of separate compilation, compilers may need to make
+conservative assumptions about strictness.
+
+The second advantage is that the creation and evaluation of closures is
+explicit in the source code, which makes it much easier to reason about
+the performance of your programs. Programs in languages where laziness
+is the default often suffer from space leaks or unexpectedly high
+memory usage, and these problems can be _extremely_ difficult to track
+down and understand, even for very experienced programmers.
+
+The third advantage is that supporting lazy evaluation via a library
+module keeps the language and its semantics simple. We're not really
+providing lazy evaluation per se, we just _emulating_ it by passing
+lambda expressions as arguments. So the "Semantics" chapter of the
+language reference manual does not need to be modified at all.
+Supporting lazy evaluation via a library module also keeps the
+implementation simple -- the module lazy.m requires only a very
+small amount of implementation-dependent code, and none of the
+rest of the implementation need change.
+
+Our current implementation of lazy evaluation is not very efficient. This is
+because the lazy(T) type currently uses two levels of indirection, whereas it
+could be implemented with only one.
+
Index: samples/lazy_list/lazy_list.m
===================================================================
RCS file: samples/lazy_list/lazy_list.m
diff -N samples/lazy_list/lazy_list.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ samples/lazy_list/lazy_list.m 29 Aug 2011 05:44:52 -0000
@@ -0,0 +1,111 @@
+%-----------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%-----------------------------------------------------------------------------%
+%
+% This is an example of how to use the `lazy' module to define
+% a recursive lazy data type, in this case lazy lists.
+% It also defines a small number of functions and predicates
+% that operate on lazy lists.
+%
+% See also lazy_list_test.m, which is an example program using this module.
+%
+% This source file is hereby placed in the public domain. -fjh (the author).
+% Modified by Paul Bone (2011) for compatibilty with the lazy module in
+% Mercury's standard library.
+
+:- module lazy_list.
+:- interface.
+:- import_module lazy, int, list.
+
+%-----------------------------------------------------------------------------%
+
+ % The definition of the type `lazy_list(T)':
+ % A lazy lazy_list is either an empty lazy_list, denoted `[]',
+ % or an element `Head' of type `T' followed by a lazily
+ % evaluated tail `Tail', of type `lazy(lazy_list(T))',
+ % denoted `[Head | Tail]'.
+
+:- type lazy_list(T) ---> [] ; [T | lazy(lazy_list(T))].
+
+%-----------------------------------------------------------------------------%
+
+ % force evaluation of (the top level of) a lazy list
+:- func force_list(lazy(lazy_list(T))) = lazy_list(T).
+
+%-----------------------------------------------------------------------------%
+
+ % Convert a lazy_list to an ordinary list.
+:- func to_list(lazy_list(T)) = list(T).
+
+ % Convert an ordinary list to a lazy_list.
+:- func from_list(list(T)) = lazy_list(T).
+
+%-----------------------------------------------------------------------------%
+
+ % A lazy_list function version of the usual append predicate:
+ % append(Start, End) = List is true iff
+ % `List' is the result of concatenating `Start' and `End'.
+ %
+:- func append(lazy_list(T), lazy(lazy_list(T))) = lazy_list(T).
+
+ % member(Elem, List) :
+ % True iff `List' contains `Elem'.
+:- pred member(T, lazy_list(T)).
+:- mode member(in, in) is semidet.
+:- mode member(out, in) is nondet.
+
+%-----------------------------------------------------------------------------%
+
+ % iterate(F, X0) = [X0, F(X0), F(F(X0)), F(F(F(X0))), ...]
+:- func iterate(func(T) = T, T) = lazy_list(T).
+:- mode iterate(func(in) = out is det, in) = out is det.
+
+ % take(N, L) returns the first N elements of L
+:- func take(int, lazy_list(T)) = lazy_list(T).
+
+ % map(F, [X0, X1, X2, ...]) = [F(X0), F(X1), F(X2), ...].
+:- func map(func(X) = Y, lazy_list(X)) = lazy_list(Y).
+:- mode map(func(in) = out is det, in) = out is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+force_list(Xs) = force(Xs).
+
+%-----------------------------------------------------------------------------%
+
+to_list([]) = [].
+to_list([X | Xs]) = [X | to_list(force_list(Xs))].
+
+from_list([]) = [].
+from_list([X | Xs]) =
+ [X | val(from_list(Xs))].
+
+%-----------------------------------------------------------------------------%
+
+append([], Ys) = force_list(Ys).
+append([X | Xs], Ys) =
+ [X | delay((func) = R :- R = append(force_list(Xs), Ys))].
+
+member(X, [X | _]).
+member(X, [_ | Xs]) :-
+ member(X, force_list(Xs)).
+
+%-----------------------------------------------------------------------------%
+
+map(_, []) = [].
+map(F, [H|T]) = [F(H) | delay((func) = R :- R = map(F, force_list(T)))].
+
+iterate(F, X0) = [X0 | delay((func) = R :- R = iterate(F, F(X0)))].
+
+take(_, []) = [].
+take(N, [X|Xs]) =
+ (if N > 0 then
+ [X | delay((func) = R :- R = take(N-1, force_list(Xs)))]
+ else
+ []
+ ).
+
+%-----------------------------------------------------------------------------%
Index: samples/lazy_list/lazy_list_test.m
===================================================================
RCS file: samples/lazy_list/lazy_list_test.m
diff -N samples/lazy_list/lazy_list_test.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ samples/lazy_list/lazy_list_test.m 29 Aug 2011 05:35:08 -0000
@@ -0,0 +1,27 @@
+%-----------------------------------------------------------------------------%
+%
+% lazy_list_test.m:
+% This is a trivial example of the use of lazy lists.
+%
+% This source file is hereby placed in the public domain. -fjh (the author).
+
+:- module lazy_list_test.
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module lazy, lazy_list, int.
+
+:- func double(int) = int.
+double(X) = 2 * X.
+
+main -->
+ { L = iterate(double, 1) }, % construct an infinite list...
+ { L10 = take(10, L) }, % extract the first 10 elements
+ print(to_list(L10)), nl. % print them
+
+%-----------------------------------------------------------------------------%
Branches: main, 11.07
extras/graphics/README:
Delete a reference to mtogl, which was removed several
releases ago.
compiler/options.m:
HISTORY:
samples/diff/diff_out.m:
samples/diff/options.m:
Fix spelling and doubled-up words.
Estimated hours taken: 2
Branches: main
Add a simple Google App Engine sample (requested by Julien).
The sample implements a servlet that handles HTTP GET
requests by printing a message.
samples/README:
Mention the new sample.
samples/appengine/Makefile:
Rules to build, run and deploy the sample.
samples/appengine/README:
Describe how to use the sample.
samples/appengine/servlet.m:
The servlet implementation.
samples/appengine/war/WEB-INF/appengine-web.xml:
App config file.
samples/appengine/war/WEB-INF/web.xml:
Deployment descriptor.
Branches: main
samples/c_interface/standalone_c/Makefile:
Delete comments regarding the mgnuc and ml scripts.
The example was changed so that it doesn't rely on those
some time ago.
Branches: main
Change the argument order of predicates in the varset module to make
them more conducive to the use of state variable notation.
library/varset.m:
As above.
library/parser.m:
library/term_io.m:
library/svvarset.m:
compiler/*.m:
samples/interpreter.m:
tests/debugger/interpreter.m:
tests/general/interpreter.m:
tests/hard_coded/bigtest.m:
tests/hard_coded/deep_copy_bug.m:
tests/hard_coded/lp.m:
tests/hard_coded/pprint_test.m:
tests/hard_coded/type_spec_ho_term.m:
Conform to the above change and remove dependencies on the svvarset
module.
Branches: main
Change the argument order of many of the predicates in the map, bimap, and
multi_map modules so they are more conducive to the use of state variable
notation, i.e. make the order the same as in the sv* modules.
Prepare for the deprecation of the sv{bimap,map,multi_map} modules by
removing their use throughout the system.
library/bimap.m:
library/map.m:
library/multi_map.m:
As above.
NEWS:
Announce the change.
Separate out the "highlights" from the "detailed listing" for
the post-11.01 NEWS.
Reorganise the announcement of the Unicode support.
benchmarks/*/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
extras/*/*.m:
mdbcomp/*.m:
profiler/*.m:
tests/*/*.m:
ssdb/*.m:
samples/*/*.m
slice/*.m:
Conform to the above change.
Remove any dependencies on the sv{bimap,map,multi_map} modules.
Branches: main, 11.01
samples/diff/*.m:
Make this code conform to our current coding guidelines -- there
are no changes to any algorithms.
Delete imports of unused modules.
Branches: main, 11.01
Fix up various problems in some of the samples that cause the compiler
to emit warnings.
samples/diff/Mmakefile:
Delete an old workaround for gcc 2.7.2 - we no longer support
gcc versions that old.
samples/diff/options.m:
samples/muz/muz.m:
samples/typecheck.m:
Avoid some Mercury compiler warnings.
Branches: main
Fix a problem with two of the concurrency examples on MinGW.
samples/concurrency/dining_philosophers/philo2.m:
samples/concurrency/dining_philosophers/philo3.m:
Use Sleep() whenever the Win32 API is available instead
of only when MSVC is being used.
Branches: main
Fix a problem with two of the concurrency examples on MinGW.
samples/concurrency/dining_philosophers/philo2.m:
samples/concurrency/dining_philosophers/philo3.m:
Use Sleep() whenever the Win32 API is available instead
of only when MSVC is being used.
Branches: main
samples/solver_types/eqneq.m:
samples/solver_types/sudoku.m:
samples/solver_types/test_eqneq.m:
Add feature set pragmas that specify that trailing is required.
Make it impossible for the labelling predicate to be reordered
so that it is called before the constraints are posted.
Minor formatting fixes.
Branches: main
Shift the remaining concurrency example out of extras distribution and into the
samples directory.
samples/concurrency/midimon/concurrent_stream.m:
samples/concurrency/midimon/midi.m:
samples/concurrency/midimon/midimon.m:
samples/concurrency/midimon/midi_data:
Shift the midi monitor example from the extras distribution
into the samples directory.
samples/README:
Add a description of the concurrency directory.
samples/concurrency/dining_philosophers/README:
samples/concurrency/midimon/README:
Move the descriptions of the concurrency examples
to these files.
extras/concurrency/Mercury.options:
extras/concurrency/Mmakefile:
extras/concurrency/midi.m:
extras/concurrency/midi_data:
extras/concurrency/midimon.m:
Delete the midi monitor example from the extras
distribution.
extras/README:
Delete the description of the concurrency directory.
Branches: main
Shift the dining philosophers examples out of the extras distribution and into
the samples directory. (The latter location is more appropriate for them since
the concurrency support has been part of the standard library for a while.)
The remaining contents of extras/concurrency will be moved into samples/concurrency
in a separate change.
extras/concurrency/philo.m:
extras/concurrency/philo2.m:
extras/concurrency/philo3.m:
Shift these modules into samples/concurrency/dining_philosophers.
extras/concurrency/concurrency.m:
extras/concurrency/spawn.m:
Delete the top-level of the old concurrency module and the spawn
module.
extras/concurrency/Mercury.options:
extras/concurrency/Mmakefile:
Don't build libconcurrency.
Delete references to things that no longer exist or have been
moved.