[m-rev.] for review: better error messages for lambda exprs

Mark Brown mark at mercurylang.org
Tue May 17 09:26:11 AEST 2016


Hi Zoltan,

Here's my views on the proposed keywords.

On Mon, May 16, 2016 at 10:13 AM, Zoltan Somogyi
<zoltan.somogyi at runbox.com> wrote:
> +    ( Name = "."                    % symname qualifier
> +    ; Name = "!"                    % state variable notation
> +    ; Name = "!."                   % state variable notation
> +    ; Name = "!:"                   % state variable notation

Ok.

> +    ; Name = "("                    % universal grouping
> +    ; Name = ")"                    % universal grouping

Can these ever be confused? The name tokens must always be written
with single quotes, whereas the grouping tokens must never be.

> +    ; Name = "int"                  % primitive type
> +    ; Name = "float"                % primitive type
> +    ; Name = "character"            % primitive type
> +    ; Name = "string"               % primitive type
> +    ; Name = "{}"                   % type ctor
> +    ; Name = "pred"                 % type ctor, inst ctor, decl kind, etc
> +    ; Name = "func"                 % type ctor, inst ctor, decl kind, etc
> +    ; Name = "is"                   % type ctor, mode ctor, detism prefix, etc
> +    ; Name = "="                    % type ctor, inst ctor, unify op, etc
> +    ; Name = ""                     % type ctor (apply)
> +    ; Name = "pure"                 % type ctor, attribute
> +    ; Name = "impure"               % type ctor, attribute
> +    ; Name = "semipure"             % type ctor, attribute

Ok.

> +    ; Name = "=="                   % type defn, mode defn
> +    ; Name = "--->"                 % type defn
> +    ; Name = ";"                    % type defn, goal
> +    ; Name = "where"                % type defn, typeclass defn, etc

Ok.

> +    ; Name = "equality"             % type defn
> +    ; Name = "comparison"           % type defn
> +    ; Name = "representation"       % type defn
> +    ; Name = "constraint_store"     % type defn
> +    ; Name = "direct_arg"           % type defn
> +    ; Name = "type_is_abstract_enum"            % type defn
> +    ; Name = "type_is_abstract_noncanonical"    % type defn

I don't agree with these. They only have significance after the
"where" keyword has been seen, and most likely will also involve "is".
Can you give an example where we can't produce a good error?

> +
> +    ; Name = "free"                 % inst ctor
> +    ; Name = "ground"               % inst ctor, solver type defn
> +    ; Name = "unique"               % inst ctor
> +    ; Name = "mostly_unique"        % inst ctor
> +    ; Name = "clobbered"            % inst ctor
> +    ; Name = "mostly_clobbered"     % inst ctor
> +    ; Name = "any"                  % inst ctor, solver type defn
> +    ; Name = "unique_any"           % inst ctor
> +    ; Name = "mostly_unique_any"    % inst ctor
> +    ; Name = "clobbered_any"        % inst ctor
> +    ; Name = "mostly_clobbered_any" % inst ctor
> +    ; Name = "not_reached"          % inst ctor
> +    ; Name = "bound"                % inst ctor
> +    ; Name = "bound_unique"         % inst ctor
> +    ; Name = "=<"                   % inst ctor
> +    ; Name = "any_pred"             % inst ctor, decl kind, etc
> +    ; Name = "any_func"             % inst ctor, decl kind, etc
> +
> +    ; Name = "for"                  % inst defn
> +
> +    ; Name = ">>"                   % mode ctor
> +
> +    ; Name = "module"               % marker
> +    ; Name = "end_module"           % marker
> +    ; Name = "interface"            % marker
> +    ; Name = "implementation"       % marker
> +    ; Name = "include_module"       % marker
> +    ; Name = "import_module"        % marker
> +    ; Name = "use_module"           % marker
> +    % ; Name = "version_numbers"    % marker
> +    ; Name = "type"                 % decl kind
> +    ; Name = "solver"               % decl kind
> +    ; Name = "inst"                 % decl kind
> +    ; Name = "mode"                 % decl kind
> +    ; Name = "promise"              % decl kind
> +    ; Name = "promise_exclusive"    % decl kind
> +    ; Name = "promise_exhaustive"   % decl kind
> +    ; Name = "promise_exhaustive_exhaustive" % decl kind
> +    ; Name = "typeclass"            % decl kind
> +    ; Name = "instance"             % decl kind
> +    ; Name = "initialise"           % decl kind
> +    ; Name = "initialize"           % decl kind
> +    ; Name = "finalise"             % decl kind
> +    ; Name = "finalize"             % decl kind
> +    ; Name = "mutable"              % decl kind
> +    ; Name = "pragma"               % decl kind

Ok to all of these.

> +    ; Name = "source_file"          % pragma decl
...
> +    ; Name = "foreign_name"         % mutable decl

I don't agree with reserving any of these, as they only have
significance in specific places after a "pragma" or "mutable" keyword
has been seen. Can you give an example where we can't produce a good
error?

> +
> +    ; Name = "::"                   % arg in predmode decl
> +
> +    ; Name = ":-"                   % clause neck
> +    ; Name = "-->"                  % clause neck
> +
> +    ; Name = "if"                   % goal
> +    ; Name = "then"                 % goal
> +    ; Name = "else"                 % goal
> +    ; Name = "promise_pure"         % goal, pragma_decl
> +    ; Name = "promise_semipure"     % goal, pragma_decl
> +    ; Name = "promise_impure"       % goal
> +    ; Name = "not"                  % goal
> +    ; Name = "\\+"                  % goal
> +    ; Name = "some"                 % goal
> +    ; Name = "all"                  % goal
> +    ; Name = ","                    % goal
> +    ; Name = "&"                    % goal
> +    ; Name = "catch"                % goal
> +    ; Name = "catch_any"            % goal
> +    ; Name = "->"                   % goal
> +    ; Name = "=>"                   % goal
> +    ; Name = "<="                   % goal
> +    ; Name = "<=>"                  % goal

Ok.

> +    ; Name = "atomic"               % goal
> +    ; Name = "or_else"              % goal
> +    ; Name = "outer"                % goal
> +    ; Name = "inner"                % goal

A bit harsh - these are not openly documented. As above, if "atomic"
is reserved I don't think "inner" and "outer" need to be. I don't know
what "or_else" is.

> +    ; Name = "vars"                 % goal

I don't know what "vars" is either.

> +    ; Name = "promise_equivalent_solutions"     % goal
> +    ; Name = "promise_equivalent_solution_sets" % goal
> +    ; Name = "arbitrary"            % goal
> +    ; Name = "require_det"          % goal
> +    ; Name = "require_semidet"      % goal
> +    ; Name = "require_multi"        % goal
> +    ; Name = "require_nondet"       % goal
> +    ; Name = "require_cc_multi"     % goal
> +    ; Name = "require_cc_nondet"    % goal
> +    ; Name = "require_erroneous"    % goal
> +    ; Name = "require_failure"      % goal
> +    ; Name = "require_complete_switch"          % goal
> +    ; Name = "require_switch_arms_det"          % goal
> +    ; Name = "require_switch_arms_semidet"      % goal
> +    ; Name = "require_switch_arms_multi"        % goal
> +    ; Name = "require_switch_arms_nondet"       % goal
> +    ; Name = "require_switch_arms_cc_multi"     % goal
> +    ; Name = "require_switch_arms_cc_nondet"    % goal
> +    ; Name = "require_switch_arms_erroneous"    % goal
> +    ; Name = "require_switch_arms_failure"      % goal
> +    ; Name = "event"                % goal
> +    ; Name = "trace"                % goal

Ok.

> +    ; Name = "compiletime"          % goal
> +    ; Name = "compile_time"         % goal
> +    ; Name = "runtime"              % goal
> +    ; Name = "run_time"             % goal
> +    ; Name = "flag"                 % goal
> +    ; Name = "grade"                % goal
> +    ; Name = "tracelevel"           % goal
> +    ; Name = "env"                  % goal
> +    ; Name = "io"                   % goal
> +    ; Name = "state"                % goal

I don't agree, as they only have significance right after "trace". Any
compelling examples?

> +    ; Name = "or"                   % goal
> +    ; Name = "and"                  % goal
> +    ; Name = "try"                  % goal
> +    ; Name = "@"                    % goal
> +    ; Name = "true"                 % goal
> +    ; Name = "fail"                 % goal

Okay.

> +    ; Name = "with_type"            % goal
> +    ; Name = "with_inst"            % goal

I'd rather deprecate these as significant.

> +    ; Name = ":"                    % goal
> +    ; Name = "^"                    % goal
> +    ; Name = "^="                   % goal
> +    ; Name = ":="                   % goal

Okay.

Note that I'm happy to prohibit all of these names in the compiler
coding standard.

Mark


More information about the reviews mailing list