[m-rev.] for review: combined higher-order types and insts

Julien Fischer jfischer at opturion.com
Thu Feb 4 14:41:58 AEDT 2016


Hi Mark,

On Sun, 31 Jan 2016, Mark Brown wrote:

> Hi,
>
> This implements the new language feature that I proposed recently
> under the heading of subtypes.
>
> Part of the change is that I've moved some code to a new module and
> also modified it. This doesn't show up in a full diff very well, so
> I've also attached the diff of just these modifications to the new
> module.

...

> Implement combined higher-order types and insts.
> 
> These allow types to be defined in the following manner:
>
>     :- type job ---> job(pred(int::out, io::di, io::uo) is det).

...

> compiler/prog_rep_tables.m:
> 	Ignore the new inst info for now.
> 
> compiler/*.m:
> 	Changes to conform to above.
> 
> doc/refernce_manual.texi:

s/refernce/reference/

> 	Document the new feature.
> 
> tests/hard_coded/functor_ho_inst.{m,exp}:
> tests/hard_coded/functor_ho_inst_2.{m,exp}:
> tests/hard_coded/functor_ho_inst_excp.{m,exp}:
> tests/hard_coded/functor_ho_inst_excp_2.{m,exp}:
> 	Test the new functionality.
> 
> tests/invalid/combined_ho_type_inst.{m,err_exp}:
> 	Test that we don't allow the new types where they are not permitted.
> 
> tests/invalid/functor_ho_inst_bad.{m,err_exp}:
> tests/invalid/functor_ho_inst_bad_2.{m,err_exp}:
> tests/invalid/functor_ho_inst_bad_3.{m,err_exp}:
> 	Test that the argument inst information is enforced as required.
> 
> tests/hard_coded/Mmakefile:
> tests/invalid/Mmakefile:
> 	Run the new test cases.

...

> diff --git a/doc/reference_manual.texi b/doc/reference_manual.texi
> index 283cc4a..4cd5c1e 100644
> --- a/doc/reference_manual.texi
> +++ b/doc/reference_manual.texi

> @@ -4554,6 +4563,24 @@ unifications; indirect attempts (via polymorphic predicates, for
>  example @samp{(list.append([], [P], [Q])} may result in an error at
>  run-time rather than at compile-time.
> 
> +Mercury also provides builtin @samp{inst} values for use with solver types:
> +
> + at example
> +any_pred is @var{Determinism}
> +any_pred(@var{Mode}) is @var{Determinism}
> +any_pred(@var{Mode1}, @var{Mode2}) is @var{Determinism}
> + at dots{}
> +any_func = @var{Mode} is @var{Determinism}
> +any_func(@var{Mode1}) = @var{Mode} is @var{Determinism}
> +any_func(@var{Mode1}, @var{Mode2}) = @var{Mode} is @var{Determinism}
> + at dots{}
> + at end example
> +
> +See @ref{Solver types} for more details.
> +
> + at node Default insts for functions
> + at subsection Default insts for functions
> +
>  In order to call a higher-order term, the compiler must know its higher-order
>  inst.  This can cause problems when higher-order terms are placed into a
>  polymorphic collection type and then extracted, since the declared mode for the
> @@ -4575,20 +4602,63 @@ but note that there is little value in doing so because there is no
>  default higher-order inst for predicates
>  therefore it will not be possible to call those terms.
> 
> -Mercury also provides builtin @samp{inst} values for use with solver types:
> + at node Combined higher-order types and insts
> + at subsection Combined higher-order types and insts
> +
> +A higher-order type may optionally specify an inst in the following manner:
>
>  @example
> -any_pred is @var{Determinism}
> -any_pred(@var{Mode}) is @var{Determinism}
> -any_pred(@var{Mode1}, @var{Mode2}) is @var{Determinism}
> +(pred) is @var{Determinism}
> +pred(@var{Type}::@var{Mode}) is @var{Determinism}
> +pred(@var{Type1}::@var{Mode1}, @var{Type2}::@var{Mode2}) is @var{Determinism}
>  @dots{}
> -any_func = @var{Mode} is @var{Determinism}
> -any_func(@var{Mode1}) = @var{Mode} is @var{Determinism}
> -any_func(@var{Mode1}, @var{Mode2}) = @var{Mode} is @var{Determinism}
> +(func) = (@var{Type}::@var{Mode}) is @var{Determinism}
> +func(@var{Type1}::@var{Mode1}) = (@var{Type}::@var{Mode}) is @var{Determinism}
> +func(@var{Type1}::@var{Mode1}, @var{Type2}::@var{Mode2}) = (@var{Type}::@var{Mode}) is @var{Determinism}
>  @dots{}
>  @end example
> 
> -See @ref{Solver types} for more details.
> +When used as argument types of functors in type declarations,
> +types of this form have two effects.
> +First, for any unification that constructs a term using such an argument,
> +there is an additional mode constraint that
> +the argument must be approximated by the inst.
> +In other words, to be mode correct a program must not construct any term
> +where a functor has an argument that does not have the declared inst,
> +if present.
> +
> +The second effect is that when a unification deconstructs a ground term
> +to extract an argument with such a declared inst,
> +the extracted argument may then be used as if it had that inst.
> +
> +For example, given this type declaration:
> +
> + at example
> +:- type job ---> job(pred(int::out, io::di, io::uo) is det).
> + at end example
> +
> +the following goal is correct:
> +
> + at example
> +:- pred run(job::in, io::di, io::uo) is det.
> +run(Job, !IO) :-
> +    Job = job(Pred),
> +    Pred(Result, !IO),          % Pred has the necessary inst
> +    write_line(Result, !IO).
> + at end example
> +
> +However, the following would be a mode error:
> +
> + at example
> +:- pred bad(job::out) is det.
> +bad(job(p)).                    % Error: p does not have required mode
> +
> +:- pred p(int::in, io::di, io::out) is det.
> + at dots{}
> + at end example
> +
> +Combined higher-order types and insts are currently only permitted
> +as direct arguments of functors in discriminated unions.

So the following would not (currently) be legal?

     :- type job(T) ---> job(T).
     :- type job == job(pred(int::out, io::di, io::uo) is det).

You also lacking (invlaid) test cases for when the arguments of combined
higher-order types and insts do not all of modes specified or when the
determinism as been omitted etc.  For example:

     :- type job ---> job(pred(int::in, io::di, io) is det).

or:

     :- type job ---> job(pred(int::in, io::di, io::uo)).


Other than that, I think the change looks ok.

Julien.



More information about the reviews mailing list