[m-rev.] for review: try goals

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Feb 18 12:59:44 AEDT 2009


Hi Peter,

Here are some initial comments that cover the change to the reference
manual.

On Tue, 17 Feb 2009, Peter Wang wrote:

> Branches: main
>
> Add support for `try' goals, syntactic sugar on top of the exception handling
> predicates in the standard library.  The syntax is documented in the reference
> manual.  Currently one of the proposed try parameters, io(!IO), is implemented,
> and the user must import the `exception' and `univ' modules explicitly.

Is there some reason that add_implict_imports in
compiler/module_imports.m can not be extended to import them if a
module uses a try goal?

In the long run it might be nice to redefine the exception_result/1 type
as:

 	:- type exception_result(T)
          	--->    succeeded(T)
          	;       failed
          	;       some [E] exception(E).

and do away with the univ there entirely.

It might also be nice to break the exception module in two module and move
the lowlevel primitives used to implement exception handlers into
a new exception_builtin module.  Then the source-to-soruce
transformation can add calls to them directly rather than going through
the exception module's public interface.

> Try goals are implemented by *two* source-to-source transformations, one at the
> parse tree level, then a later one on the HLDS.  The reason for this is given
> in try_expand.m.
>
>
> library/ops.m:
> 	Add three new operators: try, catch, catch_any.
>
> compiler/prog_item.m:
> 	Add representations of try goals to parse tree.
>
> compiler/prog_io_goal.m:
> 	Parse try goals.
>
> 	Unrelated: fix spelling of "parameter".
>
> compiler/add_clause.m:
> 	Perform the initial transformation on try goals.
>
> compiler/hlds_goal.m:
> 	Add try goals to HLDS, as shorthand goals.
>
> compiler/try_expand.m:
> 	New module to perform the latter transformation on try goals.
>
> compiler/check_hlds.m:
> 	Import the new module.
>
> compiler/mercury_compile.m:
> 	Call the try_expand pass near the end of the front-end pass.
>
> compiler/det_analysis.m:
> 	Conform to addition of try goals in HLDS.  Make it not wrap a commit
> 	scope around the intermediate try goal (as it might if there are no
> 	outputs) as it is inappropriate.
>
> compiler/prog_util.m:
> 	Conform to parse tree changes.
>
> compiler/assertion.m:
> compiler/build_mode_constraints.m:
> compiler/cse_detection.m:
> compiler/delay_partial_inst.m:
> compiler/dependency_graph.m:
> compiler/det_report.m:
> compiler/equiv_type_hlds.m:
> compiler/format_call.m:
> compiler/goal_form.m:
> compiler/goal_path.m:
> compiler/goal_util.m:
> compiler/hlds_out.m:
> compiler/intermod.m:
> compiler/lambda.m:
> compiler/make_hlds_warn.m:
> compiler/mercury_to_mercury.m:
> compiler/mode_util.m:
> compiler/modes.m:
> compiler/module_imports.m:
> compiler/module_qual.m:
> compiler/ordering_mode_constraints.m:
> compiler/polymorphism.m:
> compiler/post_typecheck.m:
> compiler/prop_mode_constraints.m:
> compiler/purity.m:
> compiler/quantification.m:
> compiler/simplify.m:
> compiler/stm_expand.m:
> compiler/stratify.m:
> compiler/structure_reuse.lfu.m:
> compiler/switch_detection.m:
> compiler/typecheck.m:
> compiler/unique_modes.m:
> compiler/unused_imports.m:
> 	Conform to changes in HLDS.
>
> library/exception.m:
> 	Add two helper predicates for the try goal transformations.
>
> doc/reference_manual.texi:
> NEWS:
> 	Document and announce the new language feature.
>
> compiler/notes/compiler_design.html:
> 	Note new compiler module.
>
> tests/hard_coded/Mmakefile:
> tests/hard_coded/try_syntax_1.exp:
> tests/hard_coded/try_syntax_1.m:
> tests/hard_coded/try_syntax_2.exp:
> tests/hard_coded/try_syntax_2.m:
> tests/hard_coded/try_syntax_3.exp:
> tests/hard_coded/try_syntax_3.m:
> tests/hard_coded/try_syntax_4.exp:
> tests/hard_coded/try_syntax_4.m:
> tests/hard_coded/try_syntax_5.exp:
> tests/hard_coded/try_syntax_5.m:
> tests/hard_coded/try_syntax_6.exp:
> tests/hard_coded/try_syntax_6.m:
> tests/invalid/Mmakefile:
> tests/invalid/try_bad_params.err_exp:
> tests/invalid/try_bad_params.m:
> tests/invalid/try_io_else.err_exp:
> tests/invalid/try_io_else.m:
> 	Add test cases.
>
> tests/invalid/trace_goal_env.err_exp:
> 	Update test case for fixed spelling for "parameter".
>
> vim/syntax/mercury.vim:
> 	Add try, catch, catch_any as keywords.
>

...


> diff --git a/doc/reference_manual.texi b/doc/reference_manual.texi
> index a027612..93ad1e6 100644
> --- a/doc/reference_manual.texi
> +++ b/doc/reference_manual.texi
> @@ -105,6 +105,7 @@ into another language, under the above conditions
> for modified versions.
> * Impurity::          Users can write impure Mercury code.
> * Trace goals::       Trace goals allow programmers to add debugging and
>                       logging code to their programs.
> +* Try goals::         Exception handling.

I think that the new chapter should occur much earlier in the reference
manual - I suggest placing it just after the ``Existential types''
chapter.  The name of the chapter should be ``Exception handling'' rather
than ``Try goals''.

> * Pragmas::           Various compiler directives, used for example to
>                       control optimization.
> * Implementation-dependent extensions::
> @@ -867,6 +868,21 @@ but to be confined to the provision of extra information
> for the user of the program.
> See @ref{Trace goals} for the details.
>
> + at item @code{try @var{Params} @var{Goal} @dots{} catch @var{Term} ->
> @var{CGoal} @dots{}}
> +A try goal. Exceptions thrown during the execution of @var{Goal}
> +may be caught and handled. A summary of the try goal syntax is:
> +
> + at example
> +    try @var{Params} @var{Goal}
> +    then @var{ThenGoal}
> +    else @var{ElseGoal}
> +    catch @var{Term} -> @var{CatchGoal}
> +    ...
> +    catch_any @var{CatchAnyVar} -> @var{CatchAnyGoal}
> + at end example
> +
> +See @ref{Try goals} for the full details.
> +
> @item @code{@var{Call}}
> Any goal which does not match any of the above forms
> must be a predicate call.
> @@ -9459,6 +9475,100 @@ but one with an implicit promise_pure around
> the clause in which they occur.
> @c The trace goal scope itself acts
> @c as a promise_pure scope for any impure code inside it.
>
> + at node Try goals
> + at chapter Try goals
> +
> +Mercury procedures may throw exceptions.  Exceptions may be caught using
> +the predicates defined in the @samp{exception} library module,
> +or using try goals.
> +
> + at noindent
> +A @samp{try} goal has the following form:
> +
> + at example
> +        try @var{Params} @var{Goal}
> +        then @var{ThenGoal}
> +        else @var{ElseGoal}
> +        catch @var{Term} -> @var{CatchGoal}
> +        ...
> +        catch_any @var{CatchAnyVar} -> @var{CatchAnyGoal}
> + at end example
> +
> + at var{CondGoal}, @var{ThenGoal}, @var{ElseGoal}, @var{CatchGoal},

s/CondGoal/Goal/

> + at var{CatchAnyGoal} must be valid goals.

@var{Goal} must have one of the following determinisms: det, semidet,
cc_multi, or cc_nondet.

The non-locals of @var{Goal} must (presumably) not have an inst
equivalent to (mostly-)unique or any?  (Unless they have the type I/O state
or (later) the store/1.)

> + at var{Params} must be a valid list of zero or more try parameters.
> +
> +The try parameter @samp{io} takes a single argument, which must be the name
> +of a state variable prefixed by @samp{!}; for example, @samp{io(!IO)}.
> +The state variable must have the type @samp{io.state}, and be in scope
> +of the try goal.

Is the @samp{io} parameter really needed at all?  Can't the compiler
just infer it by the use of I/O state in @var{Goal}?

> The state variable is threaded through @samp{Goal},
> +so it may perform I/O but cannot fail.
> +If no @samp{io} parameter exists, @samp{Goal} may not perform I/O and may
> +fail.

I would swap the order of this paragraph and the next one.

> +
> +The ``then'' part is mandatory.
> +The ``else'' part is mandatory if @var{Goal} may fail; otherwise it
> +must be omitted.
> +There may be zero or more ``catch'' branches.
> +The ``catch_any'' part is optional.  @var{CatchAnyVar} must be a single
> +variable.
> +
> +A try goal has determinism @samp{cc_multi}.
> + at c Exception: if all of the then/else/catch/catch_any parts only succeed
> + at c without binding non-local variables then the determinism is det.
> + at c In the implementation we may still infer cc_multi though.
> +
> +On entering a try goal, @var{Goal} is executed.  If it succeeds
> +without throwing an exception, @var{ThenGoal} is executed.
> +Any variables bound by @var{Goal} are visible in @var{ThenGoal} only.
> +If @var{Goal} fails, then @var{ElseGoal} is executed.
> +
> +If @var{Goal} throws an exception, the exception object is unified

s/object/value/ (and below)

> +with each the @var{Term}s in the ``catch'' branches in turn.
> +On the first successful unification, the corresponding @var{CatchGoal} is
> +executed (and other ``catch'' and ``catch_any'' branches ignored).
> +Variables bound during the unification of the @var{Term} are in scope
> +of the corresponding @var{CatchGoal}.
> +
> +If the exception object does not unify with any of the terms in ``catch''
> +branches, and a ``catch_any'' branch is present, the exception is bound
> +to @var{CatchAnyVar} and the @var{CatchAnyGoal} executed.
> + at var{CatchAnyVar} is visible in the @var{CatchAnyGoal} only, and
> +is existentially typed.

It might be worth expanding on that last bit, i.e. that it is has
type ``some [S] S''.

> +Finally, if the thrown object did not unify with any ``catch'' term,
> +and there is no ``catch_any'' part, the exception is rethrown.

s/part/branch/

The above description covers the operational semantics of try goals,
I think there needs to be a description of their declarative semantics
as well.  (Like what we have in the library reference manual for
try and friends.)

Cheers,
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list