CWM RFE: list:lastElement builtin?

A builtin that returns the last sublist of some list would be very
useful in list processing. For example, given the following list:

_:p1 rdf:first "a" .
_:p1 rdf:rest _:p2 .
_:p2 rdf:first "b" .
_:p2 rdf:rest _:p3 .
_:p3 rdf:first "c" .
_:p3 rdf:rest rdf:nil .

The expression { _:p1 list:lastElement ?sub } should return _:p3.

This would, I believe, be the proper way of resolving my list handling
problem as previously opened on this mailing list [1]. Yosi noted a
workaround [2], which does work but is inefficient and leaves unwanted
triples lying around. Yosi and I discussed this problem on IRC and
decided that a builtin along these lines would be a workable solution.

Here is our discussion, including a sketch of a patch by Yosi. Note
that we disagreed over which name to use for the builtin; I don't
actually mind what it's called.

16:17  <sbp> I figured using list:last would let me bypass that...
because the next step was to parse from the end. seemed a bit of a
pain to have to label down into a list and then process coming back
out of it
16:17  <sbp> would it be possible to make a list:lastSublist builtin perhaps?
16:18  <sbp> or is that infeasible for the same reason?
16:18  <yosi_s> five lines
16:18  <sbp> five lines to create such a builtin?
16:19  * yosi_s looks again
16:19  <yosi_s> exactly nine lines of code in cwm_list.py
16:19  <yosi_s> list:last is so close to what you want
16:20  <yosi_s> its last line is
16:20  <yosi_s>             if isinstance(x, EmptyList): return last.first
16:20  <yosi_s> you want
16:20  <yosi_s>             if isinstance(x, EmptyList): return last
16:20  <sbp> ah yes, so I see
16:21  <yosi_s> the diff would look like
16:21  <yosi_s> 54a55,63
16:21  <yosi_s> > class BI_lastElem(LightBuiltIn, Function):
16:21  <yosi_s> >     def evalObj(self, subj, queue, bindings, proof, query):
16:21  <yosi_s> >         if not isinstance(subj, NonEmptyList): return None
16:21  <yosi_s> >         x = subj
16:22  <yosi_s> >         while 1:
16:22  <yosi_s> >             last = x
16:22  <yosi_s> >             x = x.rest
16:22  <yosi_s> >             if isinstance(x, EmptyList): return last
16:22  <yosi_s> >
16:22  <yosi_s> 133a143
16:22  <yosi_s> >     ns.internFrag("lastElement", BI_lastElement)
16:22  <yosi_s> (which is broken, I can't consistently name things today)
16:22  <sbp> sure, I can code that locally; but can it be added to the
swap codebase?
16:22  <sbp> who authorises new builtins these days? :-)
16:24  <yosi_s> I'm not sure I can
16:26  <sbp> I can file an RFE on public-cwm-bugs if that's still the
Right Thing To Do™?
16:26  <yosi_s> sounds reasonable

Given that I had to use the workaround idiom twice in one day, I think
that it's common enough an idiom to warrant having this builtin to do
it more efficiently.

Thanks,

[1] http://lists.w3.org/Archives/Public/public-cwm-bugs/2007Oct/0000
[2] http://lists.w3.org/Archives/Public/public-cwm-bugs/2007Oct/0003

-- 
Sean B. Palmer, http://inamidst.com/sbp/

Received on Saturday, 13 October 2007 13:10:11 UTC