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

Sean Charles (emacstheviking) objitsu at gmail.com
Sat Nov 5 20:11:14 AEDT 2022


Absolutely perfect Zoltan, thanks again! 
Implemented and tested already,

:- type inclusion_type
   --->    req
   ;       req_once
   ;       incl
   ;       incl_once.

:- pred syntax_include(location::in, lsnode::in, checked::out) is det.
:- pred syntax_include_once(location::in, lsnode::in, checked::out) is det.
:- pred syntax_require(location::in, lsnode::in, checked::out) is det.
:- pred syntax_require_once(location::in, lsnode::in, checked::out) is det.

syntax_include(Pos, Body, Out) :-
    tr_inclusions(Pos, Body, include_form_error, incl, Out).

syntax_include_once(Pos, Body, Out) :-
    tr_inclusions(Pos, Body, include_form_error, incl_once, Out).

syntax_require(Pos, Body, Out) :-
    tr_inclusions(Pos, Body, require_form_error, req, Out).

syntax_require_once(Pos, Body, Out) :-
    tr_inclusions(Pos, Body, require_form_error, req_once, Out).



> On 5 Nov 2022, at 09:00, Sean Charles (emacstheviking) <objitsu at gmail.com> wrote:
> 
> Yes, that would def. work!
> 
> :D
> 
> Thanks Zoltan, sometimes the obvious things aren't that obvious...
> 
> Sean
> 
> 
>> On 5 Nov 2022, at 08:58, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
>> 
>> 
>> 
>> 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.
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20221105/009280d6/attachment-0002.html>


More information about the users mailing list