<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">This is the fifth and final attempt at posing this question so I apologise in advance for its potential display of rambling incoherence, because the more I thought about it the more confused I became having spent some considerable life hours coaxing the compiler with my horrid source code.<div class=""><br class=""></div><div class="">I have a type called <i class="">snode</i> and one of its constructors is <i class="">map(). A</i> map is guaranteed to have either no elements or an even number of elements as they are intended to be key-value pairs during final code rendering phase.</div><div class=""><br class=""></div><div class="">At the point of finishing parsing I currently have this code:</div><div class=""><br class=""></div><div class="">                        (if even(length(Terms)) then<br class=""><b class="">                            Res = term(map(Pos, Terms))<br class=""></b></div><div class=""><b class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>:</b></div><div class=""><b class=""><br class=""></b></div><div class="">On the highlighted line, I started thinking should I use the library pair() to make processing of them in some way ‘easier’ further along the processing pipeline ? At the time, I decided that it would not really help but, having spent some time on this now, I seek advice as I am going around in thought-spirals that end in a walk in the woods.</div><div class=""><br class=""></div><div class="">I have another language instruction called typemap:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>(#f:typemap {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">             </span>“variables” {…}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">             </span>“types” {…}</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>})</div><div class=""><br class=""></div><div class="">which allows both inline code and external files to be loaded prior to composition of the final code and each typemap defines the final output type of a variable in the final code. Given that I (‘I’, not the compiler yet) know the list is empty or even for the “variables” or “types” value, I then do:</div><div class=""><br class=""></div><div class="">    else if Lslot = "variables" then<br class="">        parse_variables(<br class="">            list.chunk(RHS,2),   % RHS is the content between {…}<br class="">            !Map,<br class="">            !Errors)<br class=""></div><div class=""><br class=""></div><div class="">As I know the list is either empty or even, I know that the chunked list is always going to be -pairs- of snode entries</div><div class=""><br class=""></div><div class="">    [ snode, snode ]</div><div class=""><br class=""></div><div class="">but I have failed to find a way to indicate via use of mode+inst instructions to the compiler that the list I expect to be given to the called predicate is guaranteed to be a list of two things, hence my earlier comment about wondering if the use of pair.pair() now may be a good idea BUT that feels like doing something earlier on just because I now can’t figure out how to tell the compiler, if it is possible at all, is some kind of giving up instead of this being another great Mercury learning opportunity.</div><div class=""><br class=""></div><div class="">I’ve tried using list.foldl on the chunked list and then calling the predicate with two distinct values:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>list.foldl(</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>(pred(KV::in, … ) is det :- </div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                     </span>list.det_index0(KV, 0, K),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                      </span>list.det_index0(KV, 1, V),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                      </span>handler( K, V, ...</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>),</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>),</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>list.chunk(RHS,2), … )</div><div class=""><br class=""></div><div class="">but that screams ugly and smells like a bucket of two day old fish soup. Trying</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>list.foldl(</div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">               </span>(pred([K,V]::in, … )  is det :-</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                  </span>list.det_index0(KV, 0, K),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                      </span>list.det_index0(KV, 1, V),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                      </span>handler( K, V, ...</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">              </span>),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>),</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">      </span>list.chunk(RHS,2), … )</div></div><div class=""><br class=""></div><div class="">just moves the same problem, that the unification of the [K,V] term can fail and so I am back to square one. The current handler looks like this:</div><div class=""><br class=""></div><div class="">:- pred parse_variables(list(lsnode)::in, tm_index::in, tm_index::out,<br class="">    lserror::in, lserror::out) is det.<br class=""><br class="">parse_variables([], !_Map, !_Errors).<br class=""><br class=""></div><div class="">parse_variables([ KV | RHS ], !Map, !Errors) :-<br class=""></div><div class="">    % I then use det_index0 to split KV into K and V</div><div class="">    % but would like to declare the predicate as</div><div class="">    % parse_variables( [ [K,V] |</div><div class=""><br class=""></div><div class="">So I guess the question is, should I use pair() right back at the start of the process or how would I inform the compiler in its language that I absolutely know and can guarantee that the received parameter is a list of size 2, always, for ever. Except when it’s empty. If I use pair() it affects other code that performs string conversions.</div><div class=""><br class=""></div><div class="">Just looking for guidance, insights, educating etc.</div><div class=""><br class=""></div><div class="">Thanks, I hope that makes sense.</div><div class="">What a terrible email.</div><div class="">Sorry.</div><div class="">Sean.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>