[m-users.] boiler plate reduction, or leave it alone as 'self documenting code' ?

Zoltan Somogyi zoltan.somogyi at runbox.com
Sat Nov 5 19:58:44 AEDT 2022



On Sat, 5 Nov 2022 08:44:52 +0000, "Sean Charles (emacstheviking)" <objitsu at gmail.com> wrote:

> The idea was to take the above function and refactor like this, passing in the term...
> 
> tr_inclusions(Pos, Body, Term, Out) :-
>     Len = list.length(Body),
>     ( if Len > 0 then
>         convert_terms(Body, Res),
>         (
>             Res = ok(TrInst),
>             Out = ok(Term)
>         ;
>             Res = error(Errors),
>             Out = error(Errors)
>         )
>     else
>         Out = checkfail(Pos, require_form_error)
>     ).
> 
> ... tr_inclusions(Pos, Body, t_require(Pos, HOLE), Out)
> 
> but I can't use an unbound variable on those constructors
> as they have to be fully instatiated and how would I know
> where to put TrInst anyway when composing the returned value?

It is possible to express this in Mercury, but that does not matter,
because the compiler cannot modecheck code that fills in
partially instantiated data structures.

What you want seems to be a way to use the same code
to handle four constructs for which the code is all but identical,
differing only in the function symbol you want to wrap around
two terms. You can do that using code like this:

:- type require_kind
    --->    rk_req
    ;       rk_req_once
    ;       rk_incl
    ;       rk_incl_once.

syntax_require(Pos, Kind, Body, Out) :-
    Len = list.length(Body),
    ( if Len > 0 then
        convert_terms(Body, Res),
        (
            Res = ok(TrInst),
            ( Kind = rk_req,       Req = t_require(Pos, TrInst)
            ; Kind = rk_req_one,   Req = t_require_once(Pos, TrInst)
            ; Kind = rk_incl,      Req = t_include(Pos, TrInst)
            ; Kind = rk_incl_once, Req = t_include_once(Pos, TrInst)
            ),
            Out = ok(Req)
        ;
            Res = error(Errors),
            Out = error(Errors)
        )
    else
        Out = checkfail(Pos, require_form_error)
    ).

This is not quite as elegant, but it should work.

Zoltan.


More information about the users mailing list