benchmarks/progs/icfp2000_par/main.m:
benchmarks/progs/mandelbrot/mandelbrot.m:
benchmarks/tools/log_to_r/log_to_r.m:
extras/align_right/align_right.m:
extras/error/error.m:
extras/gator/evolve.m:
extras/moose/options.m:
samples/concurrency/midimon/midimon.m:
samples/diff/diff.m:
samples/muz/muz.m:
Conform to getopt.process_options now returning structured errors
instead of strings.
The main objective of this change is to get bootchecks in the csharp
and java grades to actually build the slice, profiler, deep_profiler
and mfilterjavac directories, which (due to the bug this diff fixes)
they weren't doing before.
However, since one side effect of this change is to eliminate
one source of annoying warnings from mmake about references to undefined
variables, a subsidiary objective is to eliminate other sources of such
warnings as well, which mostly come from the rules for making tags files.
browser/Mmakefile:
deep_profiler/Mmakefile:
library/Mmakefile:
mdbcomp/Mmakefile:
profiler/Mmakefile:
slice/Mmakefile:
ssdb/Mmakefile:
When creating stage 3, the bootcheck builds, in each directory,
only the files that it wants to compare against their stage 2 versions.
This means that it wants to build all the .c, .cs or .java files,
which it does via the cs, css and javas mmake targets.
The correct definitions of the rules of these targets depends on
whether mmc --make is being used or not, so we need at least two
sets of definitions: one for mmc --make, and for no mmc --make,
and conditionally selecting the appropriate one. The latter definition
has the problem that it refers to mmake variables that are intended
to be defined in .dv files created by mmc --generate-dependencies,
but until that has been run, those mmake variables are undefined.
Until now, the only directories that had both the mmc --make
and the no mmc --make definitions were the ones needed to build
the compiler. Bootchecks in the csharp and java grades, which
always use --make make, got errors when they tried to build
the directories that bootcheck builds after the compiler:
the slice, profiler, deep_prof and mfilterjavac directories.
This diff ensures that all directories we build in bootcheck
get all both versions of the os, cs, css, and javas targets.
In fact, they get two subversions of the no mmc --make version:
one for use in the presence of .dv files, and one for use in their
absence. The latter just builds the .dv files and invokes mmake
again. This avoids one source of warnings about undefined mmake
variables.
To avoid another source, make the rules for tags files and their
proxies depends on *.m instead of mmake variables such as $(mcov.ms),
since this makes sense even before making dependencies. The only price
is that any untracked Mercury source files in the directory have to
either be given some other suffix, or moved somewhere else.
Where relevant, make the mtags invocation prefer the master versions
of files that are copied from the mdbcomp directory to other directories,
since this is the only writeable version.
Make the os and cs rules consistently NOT build the _init.[co] files.
The way we use those files in bootcheck, we never need them;
when we need them, the right target to give is the executable anyway.
In the slice directory, don't put mcov between mtc_union and mtc_diff.
Eliminate unnecessary duplication, e.g. of sources in rules.
Eliminate double negatives in conditionals.
Fix formatting.
Mmake.common.in:
bindist/Mmakefile:
bytecode/Mmakefile:
compiler/Mmakefile:
doc/Mmakefile:
grade_lib/Mmakefile:
robdd/Mmakefile:
samples/Mmakefile:
scripts/Mmakefile:
tools/Mmakefile:
trace/Mmakefile:
util/Mmakefile:
Add "ft=make" to vim modelines. This is redundant for the files whose
names is Mmakefile, but it is needed for Mmake.common.
When a user writes a clause for a predicate (or function) that does not exist
with that arity, but does exist with one or more other arities, report not
just the list of the other arity/arities, but, for each such other arity,
a diff between the declared arg types and the inferred arg types.
After this diff, we generate output like this:
bad_pred_arity.m:027: Error: clause for predicate `bad_pred_arity.p'/4
bad_pred_arity.m:027: without corresponding `:- pred' declaration.
bad_pred_arity.m:027: However, predicates of that name do exist with arities
bad_pred_arity.m:027: 3 and 5.
bad_pred_arity.m:027: Inferred :- pred p(int, string, int, string).
bad_pred_arity.m:027: The argument list difference from the arity 3 version
bad_pred_arity.m:027: is
bad_pred_arity.m:027: pred(
bad_pred_arity.m:027: int,
bad_pred_arity.m:027: + string,
bad_pred_arity.m:027: int,
bad_pred_arity.m:027: string
bad_pred_arity.m:027: )
bad_pred_arity.m:027: The argument list difference from the arity 5 version
bad_pred_arity.m:027: is
bad_pred_arity.m:027: pred(
bad_pred_arity.m:027: int,
bad_pred_arity.m:027: - float,
bad_pred_arity.m:027: string,
bad_pred_arity.m:027: int,
bad_pred_arity.m:027: string
bad_pred_arity.m:027: )
compiler/typecheck_errors.m:
Generate the diff part of the message above.
compiler/typecheck.m:
Invoke typecheck_errors.m when relevant.
compiler/error_util.m:
When comparing two error_specs, switch from a two-level comparison
(first the contexts of error_msgs, then everything else) to three levels
first the contexts of error_msgs, then their error_msg_components,
then everything else). This is needed to allow the error message from
make_hlds_error.m (which reports the error and mentions the arities
with which the named predicate or function does exist) come out before
the informational message from typecheck.m that prints the inferred
arg types and their differences from the other arities. (With the old
comparison, the difference in severity would trump the invisible order
components that this diff includes in both specs to force the desire
order.)
Base the code comparing error_specs on the code for comparing error_msgs.
Move the two previously separate pieces code for those tasks next to each
other.
compiler/make_hlds_error.m:
Add the invisble ordering component.
When we see clauses with two or more wrong arities for a given predicate
or function, don't list the automatically created pred declaration
for an *earlier* wrong-arity clause as a real declaration whose arity
is to be listed in the error messages we generate for *later* wrong-arity
clauses.
Add some documentation.
compiler/add_pred.m:
Factor out some common code.
library/edit_seq.m:
A new module for computing diffs.
library/library.m:
library/MODULES_DOC:
Add the new module to the standard library.
tests/hard_coded/edit_seq_test.{m,exp}:
A new test case for the diff algorithm.
tests/invalid/bad_pred_arity.{m,err_exp}:
A new test case for the new error message.
tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
Enable the new test cases.
tests/invalid/bigtest.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/invalid_binary_literal.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/invalid_hex_literal.err_exp:
tests/invalid/invalid_main.err_exp:
tests/invalid/invalid_octal_literal.err_exp:
tests/invalid/multimode_dcg.err_exp:
tests/invalid/multisoln_func.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/try_detism.err_exp2:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_8.err_exp:
tests/invalid/unsatisfiable_constraint.err_exp:
tests/invalid_purity/impure_func_t3.err_exp:
Update these files to expect error messages in the new order.
samples/diff/*.m:
Fix comments, mostly by moving them to where our programming style
wants them.
extras/windows_installer_generator/sample/images/Exclam.ico:
extras/windows_installer_generator/sample/images/Info.ico:
extras/windows_installer_generator/sample/images/banner.bmp:
extras/windows_installer_generator/sample/images/bg.bmp:
samples/solutions/all_solutions.m:
samples/solutions/some_solutions.m:
These files had their execute bit set unnecessarily.
samples/java_interface/standalone_java/JavaMain.java:
We need to initialise the standard library, otherwise things
like the stream database won't be set up properly.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
In preparation for supporting uint literals and literals for the fixed size
integer types, generalise the representation of integers in the term module, so
that for every integer literal we record its base, value (as an arbitrary
precision integer), signedness and size (the latter two based on the literal's
suffix or lack thereof).
Have the lexer attach information about the integer base to machine sized ints;
we already did this for the 'big_integer' alternative but not the normal one.
In conjunction with the first change, this fixes a problem where the compiler
was accepting non-decimal integers in like arity specifications. (The
resulting error messages could be improved, but that's a separate change.)
Support uints in more places; mark other places which require further work with
XXX UINT.
library/term.m:
Generalise the representation of integer terms so that we can store
the base, signedness and size of a integer along with its value.
In the new design the value is always stored as an arbitrary precision
integer so we no longer require the big_integer/2 alternative; delete it.
Add some utility predicates that make it easier to work with integer terms.
library/term_conversion.m:
library/term_io.m:
Conform to the above changes,
Add missing handling for uints in some spots; add XXX UINT comments
in others -- these will be addressed later.
library/lexer.m:
Record the base of word sized integer literals.
library/parser.m:
compiler/analysis_file.m:
compiler/fact_table.m:
compiler/get_dependencies.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/parse_class.m:
compiler/parse_inst_mode_name.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_sym_name.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
mdbcomp/trace_counts.m:
samples/calculator2.m:
extras/moose/moose.m:
Conform to the above changes.
tests/hard_coded/impl_def_lex.exp:
tests/hard_coded/impl_def_lex_string.exp:
tests/hard_coded/lexer_bigint.exp*:
tests/hard_coded/lexer_zero.exp*:
tests/hard_coded/parse_number_from_string.exp*:
tests/hard_coded/term_to_unit_test.exp:
Update these expected outputs.
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.