<html><head><meta http-equiv="content-type" content="text/html; charset=us-ascii"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi,<div><br></div><div>As I produce more syntax checking code I am seeing a lot of repetition but I am unsure if I should attempt to reduce it and if so, how best to do it? </div><div><br></div><div>Initially I created a predicate, tr_inclusions/3 but then after calling it the code was almost the same, a disjunction around the return type and the saving in code noise was minimal so I aborted and posted here for some advice instead!</div><div><br></div><div><div>Here is one check predicate, the bold lines are basically the only lines that differ for syntax_require_once/3, syntax_include/3 and syntax_include_once/3, I think you can see my dilemma...</div></div><div><br></div><div><br></div><div><div>:- pred syntax_require(location::in, lsnode::in, checked::out) is det.</div><div><br></div><div>syntax_require(Pos, Body, Out) :-</div><div> Len = list.length(Body),</div><div> ( if Len > 0 then</div><div> convert_terms(Body, Res),</div><div> (</div><div> Res = ok(TrInst),</div><div> Out = ok(t_require(Pos, TrInst))</div><div><b> Out = ok(t_require_once(Pos, TrInst))</b></div><div><b> Out = ok(t_include(Pos, TrInst))</b></div><div><b> Out = ok(t_include_once(Pos, TrInst))</b></div><div> ;</div><div> Res = error(Errors),</div><div> Out = error(Errors)</div><div> )</div><div> else</div><div> Out = checkfail(Pos, require_form_error)</div><div> ).</div><div><br></div></div><div><br></div><div>If I could pass in the argument `t_require_once(Pos, TrInst)` that would be good but I think in the past when I have tried things like this that the compiler doesnt like it because you can't use holes in data structures.</div><div>The idea was to take the above function and refactor like this, passing in the term...</div><div><br></div><div><div>tr_inclusions(Pos, Body, Term, Out) :-</div><div> Len = list.length(Body),</div><div> ( if Len > 0 then</div><div> convert_terms(Body, Res),</div><div> (</div><div> Res = ok(TrInst),</div><div><b> Out = ok(Term)</b></div><div> ;</div><div> Res = error(Errors),</div><div> Out = error(Errors)</div><div> )</div><div> else</div><div> Out = checkfail(Pos, require_form_error)</div><div> ).</div></div><div><br></div><div>... tr_inclusions(Pos, Body, t_require(Pos, HOLE), Out)</div><div><br></div><div>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?</div><div><br></div><div>:- type lsinst == list(tr_inst).</div><div><div>:- type gps == location.</div><div>:- type tr_inst</div><div> ---> t_defun(gps, acl, ps, list(fn_sig), lsinst)</div><div> ; t_defvar1(gps, ps)</div><div> ; t_defvar2(gps, ps, tr_inst)</div><div> ; t_if1(gps, tr_inst, tr_inst)</div><div> ; t_if2(gps, tr_inst, tr_inst, tr_inst)</div><div><b> ; t_include(gps, lsinst)</b></div><div><b> ; t_include_once(gps, lsinst)</b></div><div> ; t_unary(gps, uop_type, lsinst)</div><div> ; t_binary(gps, bop_type, lsinst)</div><div> ; t_gencall(gps, ps, lsinst)</div><div> ; t_nary(gps, nop_type, lsinst)</div><div> ; t_progn(gps, lsinst)</div><div><b> ; t_require(gps, lsinst)</b></div><div><b> ; t_require_once(gps, lsinst)</b></div><div> ; t_return0(gps)</div><div> ; t_return(gps, lsinst)</div><div> ; t_literal(ps) % or does it need to be more refined?</div><div> ; t_keyword(ps)</div><div> ; t_string1(ps)</div><div> ; t_string2(ps)</div><div> .</div></div><div><br></div><div>I've been thinking about wether or not in this instance, the refactoring effort is in fact a waste of time?</div><div><br></div><div>Thanks,</div><div>Sean.</div><div><br></div></body></html>