[m-dev.] getting type representation decisions from .int files

Peter Wang novalazy at gmail.com
Sun Jul 4 14:13:58 AEST 2021


On Sat, 03 Jul 2021 10:24:34 +1000 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> 
> I am attaching a proposed diff to the reference manual, for review by both
> Peter and Julien.
> 
> > That's not necessarily the case, as in:
> > 
> >     :- type non_empty_list_of_citrus =< list(citrus)
> >         --->    [citrus | list(citrus)].
> > 
> >> And where is this restriction enforced?
> >> I couldn't find anything related to this in check_subtype_defn in add_type.m.
> > 
> > It's checked in check_supertype_vars in parse_type_defn.m.
> 
> Is there some special reason why this check is not in add_type.m, with all
> the other checks on subtype definitions? I would have thought that
> having all the semantic checks for a given construct being in one place
> is a good thing.

It's the same place where we check for free variables in constructors.

> diff --git a/doc/reference_manual.texi b/doc/reference_manual.texi
> index 7f59c058f..be8c2c47a 100644
> --- a/doc/reference_manual.texi
> +++ b/doc/reference_manual.texi
> @@ -2525,17 +2525,30 @@ in that every term of a subtype is a valid term in the supertype.
>  It is possible to convert terms between subtype and supertype
>  using type conversion expressions (@pxref{Type conversions}).
>  
> -A subtype is defined using the form
> +While the syntax for non-subtype discriminated union types is
> + at example
> +:- type @var{type} ---> @var{body}.
> + at end example
> +the syntax for subtypes is
>  @example
>  :- type @var{subtype} =< @var{supertype} ---> @var{body}.
>  @end example
> -
> - at var{subtype} must be a name term
> -whose arguments (if any) are distinct variables.
> -
> - at var{supertype} must be a type (that may contain variables).

> +In both cases, @var{body} is
> +a sequence of constructor definitions separated by semicolons.
> +In both cases, any universally quantified type variable
> +that occurs in @var{body} must occur in the @var{head} of the type definition,
> +i.e. in the part before @code{--->}.
> +

By describing both non-subtype and subtype du type definitions together,
you have to state a restriction that is true for both:

    any universally quantified type variable
    that occurs in @var{body} must occur in the @var{head} of the type definition,
    i.e. in the part before @code{--->}.

and then refine the restriction for subtypes later on:

    Any universally quantified type variable
    that occurs in @var{body} must occur also in @var{subtype}.

The other thing I don't like is describing the body before the head.

I suggest to start the chapter something like this:

    Recall that / as previously described,
    the syntax for non-subtype discriminated union types is ...

    In contrast, the syntax for subtype type definitions is ...

    @var{subtype} must be a type constructor
    applied to zero or more arguments, ...

    @var{supertype} must be a type constructor
    applied to zero or more argument types, ...

    As with other discriminated union type definitions,
    the @var{body} of a subtype definition is
    a sequence of constructor definitions separated by semicolons.
    Any universally quantified type variable
    that occurs in @var{body} must occur in the @var{subtype} part of
    the type definition.

> + at var{subtype} must be a type constructor
> +applied to zero or more arguments,
> +which (if any) must be distinct variables.
> +
> + at var{supertype} must be a type constructor
> +applied to zero or more argument types,
> +which @emph{may} be type variables, but they do not have to be,
> +and if they are, do not need to be distinct.

Add:

    Any type variables in @var{supertype} must also occur
    in @var{subtype}.

>  After expanding out equivalences,
> -the principal constructor must specify a discriminated union type
> +the principal type constructor must specify a discriminated union type
>  whose @emph{definition} is in scope where the subtype definition occurs,
>  by normal module visibility rules.

Ok.

> @@ -2543,32 +2556,60 @@ The discriminated union type specified by @var{supertype}
>  may itself be a subtype.
>  Following a chain of visible subtype definitions,
>  it must be possible to arrive at a @emph{base type},
> -which is not a subtype.
> +which is a discriminated union type but @emph{not} a subtype.

Ok.

> -
> -Any variable that occurs in @var{supertype} must occur in @var{subtype}.
>  

It seems this sentence was lost.

> -The @var{body} term is defined as
> -a sequence of constructor definitions separated by semicolons.
> -Any universally quantified type variable that occurs in @var{body}
> -must occur in @var{subtype}.
> +The body of the subtype may differ from the body of its supertype in two ways.
> + at itemize @bullet
> + at item
> +It may omit one or more constructor definitions.
> +The ability to do this is the main motivation for the use of subtypes.
> + at item
> +It may change the types of some of the arguments of some of the constructors,
> + at emph{provided} that each replacement replaces a type with one of its subtypes.
> +Formally, this means that
> +if the supertype @samp{t} has a constructor @samp{f(T1, ..., Tn)},
> +and the subtype @samp{s =< t} has a constructor @samp{f(S1, ..., Sn)}.
> +then for each @var{Si}, the condition @samp{Si =< Ti} must hold.

Ok.

> +This is often required when one wants to create
> +subtypes of two or more mutually recursive types.
> + at end itemize

I'm not sure what this sentence is saying.

> -The constructor definitions must be a
> -subset of the constructors of the supertype;
> -we recommend they appear in the same relative order
> +Since the subtype cannot add definitions of constructors,
> +the set of constructor definitions in the subtype
> +must be a subset of the constructors definitions in the supertype.
> +We recommend that they should appear in the same relative order
>  as in the supertype definition.

Ok.

> -If the supertype @samp{t} has constructor @samp{f(T1, ..., Tn)} then
> -a subtype @samp{s =< t} may have a constructor @samp{f(S1, ..., Sn)}.
> -For each @var{Si}, it must be that @samp{Si =< Ti}.
> +
> +If the subtype retains a constructor from the super type
> +that has one or more existentially quantified type variables, then
> +there must be a one-to-one mapping between
> +the existentially quantified type variables
> +for the constructor in the subtype definition
> +and the same constructor in the supertype definition.
> +The subtype constructor must repeat
> +exactly the same set of existential class constraints
> +on its existentially quantified type variables as in the supertype;
> +the subtype constructor cannot add or remove any existential class constraints.
> +

Ok.

> +Any universally quantified type variable
> +that occurs in @var{body} must occur also in @var{subtype}.

(This would be moved earlier per my suggestion.)

> +However, the list of parameters in @var{subtype} is not otherwise restricted;
> +for example, it need not have any particular relationship
> +with the list of parameters
> +of the principal type constructor of @var{supertype}.
> + at c There should be some discussion here
> + at c of the possible uses of this flexibility.

I think the "not otherwise restricted" part is misleading. There *are*
restrictions on the parameters in @var{subtype} as stated elsewhere.
I'm inclined to leave the paragraph out, unless it is clarified.

>  (In the following discussion,
> -assume that equivalence types are expanded out
> -as required.)
> +assume that all equivalence types have been expanded out.)
>  

Ok.

> @@ -2590,18 +2632,12 @@ and purity.
>  (The current implementation does not admit subtyping in
>  higher-order arguments.)
>  
> + at c This should not be here. It should be replaced by a statement at the top
> + at c that says: these cases list *all* the situations in which S =< T may hold
> + at c without S = T. In every other situation, S =< T if and only if S = T."
>  @samp{P =< Q} holds if @var{P} and @var{Q} are both
>  existentially quantified type variables, and @samp{P = Q}.

That should be okay.

Peter


More information about the developers mailing list