NEWS for Mercury 22.01.1
========================

This is a bug-fix release.

* [Mantis bug #557]. We have fixed a bug in module qualification that was
  causing the compiler to fail without printing an error message.

NEWS for Mercury 22.01
======================

Changes that may break compatibility
------------------------------------

* We have removed `is` as a synonym for unification.

* We have reserved `=<`/2 as a type name.

* A term with a top-level functor `coerce/1` is now treated as a
  type conversion expression. To call a function named `coerce/1`,
  you can module qualify the name at the call site,
  or wrap parentheses around the name, e.g. `(coerce)(Arg)`.

* We have renamed the `lexer` and `parser` modules of the Mercury standard
  library to `mercury_term_lexer` and `mercury_term_parser` respectively.

* We have made slight changes to the names and/or the functionality
  of several predicates in the `getopt` and `getopt_io` modules.

* We have removed the legacy support for the Alpha architecture.

* We have dropped support for macOS 10.8 and earlier.

* We have removed the Erlang backend as it was unmaintained.

Changes to the Mercury standard library
---------------------------------------

### New module: `random.system_rng`

* This module provides an interface to a platform specific cryptographically
  secure random number generator that is seeded from the OS entropy pool.

### Changes to the `array` module

* The following obsolete predicates and functions have been removed:

    - func `bsearch/3`              (replacement: `binary_search/3`)
    - pred `bsearch/4`              (replacement: `binary_search/4`)
    - func `least_index/1`          (replacement: `min/1`)
    - func `greatest_index/1`       (replacement: `max/1`)

* The following predicate has been added:

    - pred `generate_foldl2/7`

### Changes to the `array2d` module

* The following predicates and functions have been added:

    - func `lookup/3`               (synonym for `Array ^ elem(R, C)`)
    - pred `lookup/4`               (synonym for `Array ^ elem(R, C)`)
    - func `unsafe_lookup/3`        (synonym for `Array ^ unsafe_elem(R, C)`)
    - pred `unsafe_lookup/4`        (synonym for `Array ^ unsafe_elem(R, C)`)

* The `lists/1` function now returns an empty list for a 0x0 array.

### Changes to the `assoc_list` module

* The following predicates and functions have been added:

    - func `common_subset/2`
    - pred `maybe_from_corresponding_lists/3`

### Changes to the `bag` module

* The following obsolete predicates and functions have been removed:

    - func `to_set_without_duplicates/1`    (replacement: func `to_set/1`)
    - pred `to_set_without_duplicates/2`    (replacement: func `to_set/1`)

### Changes to the `bitmap` module

* The following predicates and functions have been added:

    - func `get_bit/2`
    - func `get_bits/2`
    - func `get_byte/2`
    - pred `set_bit/4`
    - pred `set_bits/4`
    - pred `set_byte/4`
    - func `unsafe_get_bit/2`
    - func `unsafe_get_bits/2`
    - func `unsafe_get_byte/2`
    - pred `unsafe_set_bit/4`
    - pred `unsafe_set_bits/4`
    - pred `unsafe_set_byte/4`

### Changes to the `char` module

* The following predicates have been added:

    - pred `unsafe_base_digit_to_int/3`
    - pred `to_utf8_uint8/2`
    - pred `to_utf16_uint16/2`

* The following obsolete predicates and functions have been removed:

    - func `det_int_to_digit/1`     (replacement: `det_int_to_decimal_digit/1`)
    - pred `det_int_to_digit/2`     (replacement: `det_int_to_decimal_digit/2`)
    - pred `digit_to_int/2`         (replacement: `decimal_digit_to_int/2`)
    - pred `int_to_digit/2`         (replacement: `int_to_decimal_digit/2`)

### Changes to the `cord` module

* The following predicates have been added:

    - pred `foldl2/6`
    - pred `foldl3/8`

### Changes to the `dir` module

* The following predicate has been added:

    - pred `general_foldl2/8`

### Changes to the `getopt` module

* The following new predicates have been added:

    - pred `record_arguments/8`
    - pred `expand_file_specials/8`

* The following variants of the existing process_options predicate
  have been added:

    - pred `process_options_io/6`
    - pred `process_options_io/7`
    - pred `process_options_track_io/9`
    - pred `process_options_userdata/8`
    - pred `process_options_userdata_io/10`

    The ones whose names have an `_io` suffix do the same jobs as the
    corresponding predicates without the `_io` suffix, with the exception
    that they also have a pair of I/O state arguments that allow them
    to implement `file_special` options. This functionality used to be
    available only from the `getopt_io` module.

* The following predicates have had their argument types changed:

    - pred `process_options/6`
    - pred `process_options/7`
    - pred `process_options_track/7`

    All these predicates used to return error indications in the form of a
    simple string. They now return error indications using the existing
    structured type `option_error`, which can be converted into a string
    on demand.

* The following predicates have been deleted:

    - pred `process_options_se/6`
    - pred `process_options_se/7`
    - pred `process_options_track_se/7`

    Their functionality is now available from the predicates with the same name
    minus the `_se` suffix.

### Changes to the `getopt_io` module

* This module has been deprecated. For now, it exports the same functionality
  as the updated `getopt` module, but it is scheduled to be deleted after
  the next release.

### Changes to the `int` module

* The following functions have been added:

    - func `uint_to_lc_hex_string/2`    (synonym for `uint_to_hex_string/2`)
    - func `uint64_to_lc_hex_string/2`  (synonym for `uint64_to_hex_string/2`)

* The following obsolete predicates and functions have been removed:

    - pred `is/2`                   (replacement: `=`, i.e. unification)
    - func `legacy_left_shift/2`    (replacement: `<<`)
    - func `legacy_right_shift/2`   (replacement: `>>`)

### Changes to the `int32` module

* The following functions have been added:

    - func `cast_to_int8`
    - func `cast_from_int8`
    - func `cast_to_int16`
    - func `cast_from_int16`
    - func `cast_to_int64`
    - func `cast_from_int64`

### Changes to the `integer` module

* The following obsolete functions have been removed:

    - func `from_base_string/2`     (replacement: pred `from_base_string/3`)
    - func `from_string/2`          (replacement: pred `from_string/2`)
    - func `int/2`                  (replacement: `det_to_int/1`)

### Changes to the `io` module

* The following predicates have been added to this module:

    - pred `get_environment_var_map/3`
    - pred `read_binary_int8_unboxed/5`
    - pred `read_binary_uint8_unboxed/5`
    - pred `read_named_file_as_string/4`
    - pred `read_named_file_as_lines/4`
    - pred `write_line_cc/4`

* The following obsolete predicates have been removed:

    - pred `make_temp/3`            (replacement: `make_temp_file/3`)
    - pred `make_temp/5`            (replacement: `make_temp_file/5`)

* The following predicates have been marked as obsolete:

    - pred `see/4`                  (replacement: `prolog.see/4`)
    - pred `see_binary/4`           (replacement: `prolog.see_binary/4`)
    - pred `seen/2`                 (replacement: `prolog.seen/2`)
    - pred `seen_binary/2`          (replacement: `prolog.seen_binary/2`)
    - pred `tell/4`                 (replacement: `prolog.tell/4`)
    - pred `tell_binary/4`          (replacement: `prolog.tell_binary/4`)
    - pred `told/2`                 (replacement: `prolog.told/2`)
    - pred `told_binary/2`          (replacement: `prolog.told_binary/2`)

* The following predicate has been renamed:

    - pred `report_stats/2` to `report_standard_stats/2`.

### Changes to the `lexer` module

* This module has been renamed to `mercury_term_lexer`, to make
  name clashes between it and user-written modules less likely.

### Changes to the `list` module

* The following predicates have been added:

    - pred `delete_nth/3`
    - pred `foldl7/16`
    - pred `foldl8/18`
    - pred `foldl4_corresponding/11`

* The following obsolete predicate has been removed:

    - pred `takewhile/4`            (replacement: `take_while/4`)

### Changes to the `map` module

* The following predicates have been added to this module:

    - pred `foldl6/14`
    - pred `foldl6_values/14`
    - pred `foldr6/14`

### Changes to the `maybe` module

* The following predicates have been added to this module:

    - pred `foldl3_maybe/8`
    - pred `foldl4_maybe/10`
    - pred `foldl5_maybe/12`
    - pred `map_foldl4_maybe/11`
    - pred `map_foldl5_maybe/13`

### Changes to the `parser` module

* This module has been renamed to `mercury_term_parser`, to make
  name clashes between it and user-written modules less likely.

### Changes to the `prolog` module

* The following predicate has been added to this module:

    - pred `is/2`                   (moved here from the `int` module)
    - pred `see/4`                  (moved here from the `io` module)
    - pred `see_binary/4`           (moved here from the `io` module)
    - pred `seen/2`                 (moved here from the `io` module)
    - pred `seen_binary/2`          (moved here from the `io` module)
    - pred `tell/4`                 (moved here from the `io` module)
    - pred `tell_binary/4`          (moved here from the `io` module)
    - pred `told/2`                 (moved here from the `io` module)
    - pred `told_binary/2`          (moved here from the `io` module)

### Changes to the `random` module

* The following obsolete predicate has been removed:

    - pred `test/4`                 (replacement: none)

### Changes to the `std_util` module

* The following obsolete predicates and functions have been removed:

    - func `maybe_func/2`           (replacement: func `maybe.func_to_maybe/1`)
    - pred `maybe_pred/3`           (replacement: func `maybe.pred_to_maybe/1`)

### Changes to the `string` module

* The following functions have been added:

    - func `add_suffix/2`
    - func `split_into_lines/1`
    - pred `to_uint/2`
    - func `det_to_uint/1`
    - pred `base_string_to_uint/3`
    - func `det_base_string_to_uint/2`
    - func `uint_to_hex_string/1`
    - func `uint_to_uc_hex_string/1`
    - func `uint_to_octal_string/1`
    - func `uint64_to_hex_string/1`
    - func `uint64_to_uc_hex_string/1`
    - func `uint64_to_octal_string/1`

* The following function symbols have been added to the type `poly_type`:

    - `i8(int8)`
    - `i16(int16)`
    - `i32(int32)`
    - `i64(int64)`
    - `u8(uint8)`
    - `u16(uint16)`
    - `u32(uint32)`
    - `u64(uint64)`

  This allows predicates such as `string.format` and `io.format` to operate
  on values of not just the word sized integer types `int` and `uint`, but on
  sized versions of them as well.

### Changes to the `term` module

* The following obsolete predicates and functions have been removed:

    - func `var_id/1`               (replacement: `var_to_int/1`)

    - func `relabel_variable/3`     (replacement: `rename_var_in_term/4`)
    - pred `relabel_variable/4`     (replacement: `rename_var_in_term/4`)
    - func `relabel_variables/3`    (replacement: `rename_var_in_terms/4`)
    - pred `relabel_variables/4`    (replacement: `rename_var_in_terms/4`)

    - func `rename/3`               (replacement: `rename_var_in_term/4`)
    - pred `rename/4`               (replacement: `rename_var_in_term/4`)
    - func `rename_list/3`          (replacement: `rename_var_in_terms/4`)
    - pred `rename_list/4`          (replacement: `rename_var_in_terms/4`)

    - func `apply_renaming/3`       (replacement: `apply_renaming_in_term/3`)
    - pred `apply_renaming/3`       (replacement: `apply_renaming_in_term/3`)
    - func `apply_renaming_to_list/3`
                                    (replacement: `apply_renaming_in_terms/3`)
    - pred `apply_renaming_to_list/3`
                                    (replacement: `apply_renaming_in_terms/3`)

    - func `apply_variable_renaming/2`
                                    (replacement: `apply_renaming_in_term/3`)
    - pred `apply_variable_renaming/3`
                                    (replacement: `apply_renaming_in_term/3`)
    - func `apply_variable_renaming_to_list/2`
                                    (replacement: `apply_renaming_in_terms/3`)
    - pred `apply_variable_renaming_to_list/3`
                                    (replacement: `apply_renaming_in_terms/3`)

    - func `apply_variable_renaming_to_var/2`
                                    (replacement: `apply_renaming_in_var/3`)
    - pred `apply_variable_renaming_to_var/3`
                                    (replacement: `apply_renaming_in_var/3`)
    - func `apply_variable_renaming_to_vars/2`
                                    (replacement: `apply_renaming_in_vars/3`)
    - pred `apply_variable_renaming_to_vars/3`
                                    (replacement: `apply_renaming_in_vars/3`)

    - func `substitute/3`           (replacement: `substitute_var_in_term/4`)
    - pred `substitute/4`           (replacement: `substitute_var_in_term/4`)
    - func `substitute_list/3`      (replacement: `substitute_var_in_terms/4`)
    - pred `substitute_list/4`      (replacement: `substitute_var_in_terms/4`)

    - func `substitute_corresponding/3`
                        (replacement: `substitute_corresponding_in_term/4`)
    - pred `substitute_corresponding/4`
                        (replacement: `substitute_corresponding_in_term/4`)
    - func `substitute_corresponding_list/3`
                        (replacement: `substitute_corresponding_in_terms/4`)
    - pred `substitute_corresponding_list/4`
                        (replacement: `substitute_corresponding_in_terms/4`)

    - func `apply_substitution/2`
                        (replacement: `apply_substitution_in_term/3`)
    - pred `apply_substitution/3`
                        (replacement: `apply_substitution_in_term/3`)
    - func `apply_substitution_to_list/2`
                        (replacement: `apply_substitution_in_terms/3`)
    - pred `apply_substitution_to_list/3`
                        (replacement: `apply_substitution_in_terms/3`)

    - func `apply_rec_substitution/2`
                        (replacement: `apply_rec_substitution_in_term/3`)
    - pred `apply_rec_substitution/3`
                        (replacement: `apply_rec_substitution_in_term/3`)
    - func `apply_rec_substitution_to_list/2`
                        (replacement: `apply_rec_substitution_in_terms/3`)
    - pred `apply_rec_substitution_to_list/3`
                        (replacement: `apply_rec_substitution_in_terms/3`)

### Changes to the `thread` module

* The following predicate and functions have been added:

    - func `init_thread_options/0`
    - pred `set_min_stack_size/3`
    - pred `spawn_native/5`

### Changes to the `thread.mvar` module

* The following obsolete function has been removed:

    - func `init/1`                 (replacement: `impure_init/1`)

### Changes to the `thread.semaphore` module

* The following obsolete function has been removed:

    - func `init/1`                 (replacement: `impure_init/1`)

### Changes to the `time` module

* The following obsolete functions have been removed:

    - func `ctime/1`                (replacement: `localtime/4` and `asctime/1`)
    - func `localtime/1`            (replacement: `localtime/4`)
    - func `mktime/1`               (replacement: `mktime/4`)

### Changes to the `tree234` module

* The following predicates have been added to this module:

    - pred `foldl6/14`
    - pred `foldl6_values/14`
    - pred `foldr6/14`

### Changes to the `uint16` module

* The following functions have been added:

    - pred `from_uint/2`
    - func `det_from_uint/1`
    - func `cast_from_uint/1`
    - func `rotate_left/2`
    - func `rotate_right/2`
    - func `unchecked_rotate_left/2`
    - func `unchecked_rotate_right/2`
    - func `set_bit/2`
    - func `unchecked_set_bit/2`
    - func `clear_bit/2`
    - func `unchecked_clear_bit/2`
    - func `flip_bit/2`
    - func `unchecked_flip_bit/2`
    - func `bit_is_set/2`
    - func `unchecked_bit_is_set/2`
    - func `bit_is_clear/2`
    - func `unchecked_bit_is_clear/2`
    - func `cast_from_uint8/1`
    - func `cast_to_uint8/1`

### Changes to the `uint32` module

* The following functions have been added:

    - pred `from_uint/2`
    - func `det_from_uint/1`
    - func `rotate_left/2`
    - func `rotate_right/2`
    - func `unchecked_rotate_left/2`
    - func `unchecked_rotate_right/2`
    - func `set_bit/2`
    - func `unchecked_set_bit/2`
    - func `clear_bit/2`
    - func `unchecked_clear_bit/2`
    - func `flip_bit/2`
    - func `unchecked_flip_bit/2`
    - func `bit_is_set/2`
    - func `unchecked_bit_is_set/2`
    - func `bit_is_clear/2`
    - func `unchecked_bit_is_clear/2`
    - func `cast_from_uint8/1`
    - func `cast_to_uint8/1`
    - func `cast_from_uint16/1`
    - func `cast_to_uint16/1`

### Changes to the `uint64` module

* The following functions have been added:

    - func `cast_from_uint/1`
    - func `rotate_left/2`
    - func `rotate_right/2`
    - func `unchecked_rotate_left/2`
    - func `unchecked_rotate_right/2`
    - func `set_bit/2`
    - func `unchecked_set_bit/2`
    - func `clear_bit/2`
    - func `unchecked_clear_bit/2`
    - func `flip_bit/2`
    - func `unchecked_flip_bit/2`
    - func `bit_is_set/2`
    - func `unchecked_bit_is_set/2`
    - func `bit_is_clear/2`
    - func `unchecked_bit_is_clear/2`
    - func `cast_from_uint8/1`
    - func `cast_to_uint8/1`

### Changes to the `uint8` module

* The following functions have been added:

    - pred `from_uint/2`
    - func `det_from_uint/1`
    - func `cast_from_uint/1`
    - func `rotate_left/2`
    - func `rotate_right/2`
    - func `unchecked_rotate_left/2`
    - func `unchecked_rotate_right/2`
    - func `set_bit/2`
    - func `unchecked_set_bit/2`
    - func `clear_bit/2`
    - func `unchecked_clear_bit/2`
    - func `flip_bit/2`
    - func `unchecked_flip_bit/2`
    - func `bit_is_set/2`
    - func `unchecked_bit_is_set/2`
    - func `bit_is_clear/2`
    - func `unchecked_bit_is_clear/2`

### Changes to the `varset` module

* The following obsolete predicates have been removed:

    - pred `merge_subst/4`      (replacement: `merge_renaming/4`)
    - pred `merge_subst_without_names/4`
                                (replacement: `merge_renaming_without_names/4`)

* The following functions and predicates have been added:

    - func `unname_var/2`
    - pred `unname_var/3`
    - pred `undo_default_names/2`

Changes to the Mercury language
-------------------------------

* The type system now supports subtypes, which work in tandem with
  type conversion expressions ("coerce"). For example, the following
  defines a subtype `real_color` of a discriminated union type `color`:

        :- type color
            --->    rgb(float, float, float)
            ;       cmyk(float, float, float, float)
            ;       named(string).

        :- type real_color =< color
            --->    rgb(float, float, float)
            ;       cmyk(float, float, float, float).

  A term of type `real_color` can be converted to a term of type `color`
  with `coerce(Term)`. A term of type `color` can be converted to a term of
  type `real_color` if it has an appropriate inst. Subtypes share a common
  data representation with their base types, so the type conversions do not
  cost anything at runtime.

* Field names no longer need to be unique within a module.

* The compiler can implement tabling only when generating C code.
  When compiling a predicate that has a `pragma memo` specified for it
  in a non-C grade, it necessarily ignores the pragma, but normally
  it prints a warning about this fact. The compiler now supports
  a new attribute, `disable_warning_if_ignored`, that suppresses
  such warnings for a `pragma memo` if included in the pragma's
  attribute list, like this:

        :- pragma memo(predname/arity, [disable_warning_if_ignored])]).

* A `pragma foreign_proc` declaration can now include an attribute
  `may_not_export_body` that prevents its body (i.e. the foreign code)
  from being duplicated outside of the target file for that module
  by intermodule optimization. This is useful when the foreign code
  refers to types, functions, etc. that should be kept local to the
  target file of that module. Unlike the `may_not_duplicate` attribute,
  `may_not_export_body` does not prevent inlining of the foreign procedure
  into other procedures in the same module.

* Many pragmas contain a name/arity pair for specifying the predicate
  or function they apply to; an example is

        :- pragma inline(init/1).

  If the module in which this pragma occurs contains both
  a function `init/1` and a predicate `init/1`, then this pragma
  is ambiguous. Traditionally, the Mercury compiler applied such
  ambiguous pragma to both the function and the predicate.
  The programmers who wished the pragma to apply to only one of them
  had to rename the other.

  Now, pragmas that take a name/arity pair can specify whether they are
  intended to apply to a function or to a predicate by putting a `func()`
  or `pred()` wrapper around the name/arity pair, like this:

        :- pragma inline(func(init/1)).     % applies ONLY to func init/1.
        :- pragma inline(pred(init/1)).     % applies ONLY to pred init/1.

  This new syntax applies to all of the following kinds of pragmas:

        check_termination
        consider_used
        does_not_terminate
        fact_table
        inline
        loop_check
        memo
        minimal_model
        mode_check_clauses
        no_determinism_warning
        no_inline
        obsolete
        promise_equivalent_clauses
        promise_pure
        promise_semipure
        require_tail_recursion
        terminates
        type_spec

Changes to the Mercury compiler
-------------------------------

* If a command line first enables an optimization (say `opt1`), and then
  sets the optimization level to `N` with `-O<N>`, then the compiler will now
  keep `opt1` enabled even if `opt1` is not normally enabled at optimization
  level `N`.

* Due to a bug fix, the `--warn-unused-imports` option is now stricter in
  warning about modules that are imported in the interface section but are
  not used in the interface section.

* We have fixed parsing of reverse implication goals (A <= B).

* By default, the compiler now checks some aspects of a module semantics
  when generating the .int and .int2 interface files for that module.
  (For example, it generates error messages for references to undefined
  types, insts and modes.) This new behavior can be switched off for now
  with the new option `--no-halt-at-invalid-interface`. This new option
  replaces the old `--no-print-errors-warnings-when-generating-interface`
  option, but once any problems caused by the new approach have been
  ironed out, we intend to delete the `--halt-at-invalid-interface`
  option as well.

* In an earlier release, we extended the syntax of `:- inst` declarations
  to allow programmers to specify which type constructor's values the inst
  is meant for. At that time, these functioned only as documentation,
  but the compiler now reports error messages for situations in which
  an inst that was declared to be intended for values of one type constructor
  is applied to values of another type constructor.

* The new option `--output-stdlib-grades` outputs the grades in which
  the Mercury standard library is available with this compiler.

* By default, the compiler now warns if the module being compiled has a name
  that shadows that of Mercury standard library module. The warning can be
  disabled using the new option `--no-warn-stdlib-shadowing`.

* The new options `--output-java-class-dir` and `--output-java-class-directory`
  are now supported as synonyms for `--output-class-dir`.

* The new option `--halt-at-warn-make-interface` causes the compiler to
  treat all warnings as if they were errors when generating interface files.

* The new option `--halt-at-warn-make-opt` causes the compiler to
  treat all warnings as if they were errors when generating optimization files.

* The new option `--warn-potentially-ambiguous-pragma` causes the compiler to
  generate a warning for all pragmas that include a name/arity pair,
  but lack a `func()` or `pred()` wrapper around it to indicate whether they
  are intended to apply to a function or to a predicate.

Portability improvements
------------------------

* We have ported Mercury to Linux AArch64 (ARM64) systems.

* The `tools/configure_mingw_cross` script has been replaced by
  `tools/configure_cross`. It now supports aarch64-linux-gnu and
  aarch64-linux-musl as targets (i.e. Linux on aarch64 with GNU or
  musl C libraries).

Changes to the Mercury debugger
-------------------------------

* The `list` command may now call an external command to print source listings;
  the command is set using `list_cmd`.  For example, the command could
  produce syntax highlighted source listings.

* We have removed support for browsing terms as XML (`browse --xml`)
  as it was unmaintained and did not work any more. The `browse --web`
  command provides an alternative method for interactively exploring a term.

For news about earlier versions, see the HISTORY file.
