Skip Menu |

This queue is for tickets about the List-UtilsBy CPAN distribution.

Report information
The Basics
Id: 105907
Status: new
Priority: 0/
Queue: List-UtilsBy

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: head(1) and tail(1)-like functions
From the newly-added docs: Consider perhaps head_before { COND } LIST # excludes terminating element head_upto { COND } LIST # includes terminating element tail_since { COND } LIST # includes initiating element tail_after { COND } LIST # excludes initiating element --- I like the idea of naming them related to "head" and "tail", because that reminds people of the UNIX head(1) and tail(1) utilities, hopefully making them memorable enough. I'm still a little unsure of the naming of before vs. upto, and since vs. after. Something suitable obvious to distinguish whether it includes or not the matching element is good. -- Paul Evans
On Thu Jul 16 14:40:14 2015, PEVANS wrote: Show quoted text
> Consider perhaps > > head_before { COND } LIST # excludes terminating element > head_upto { COND } LIST # includes terminating element > > tail_since { COND } LIST # includes initiating element > tail_after { COND } LIST # excludes initiating element
Thinking further, it's still a bit too subtle whether or not these names imply that the terminating element is included or not, so I think maybe it's best to be really clear in the names: head_upto { COND } LIST head_upto_including { COND } LIST tail_since_including { COND } LIST tail_since { COND } LIST As well as head/tail there's also what Haskell calls "drop" - I.e. scan over the headmost items until some matching item, and then take the remaining elements after that. For completeness there'd also be the analogous one, scanning backwards over the list and returning the headmost items "before" the matching one, though in practice that would be rare enough people can play games with reverse() on the dropping function. The dropping one still needs a name though. drop_upto + drop_upto_including ? but then does "including" drop that item, and thus its return value "excludes" it? Naming after a negative action like that doesn't help the "including" prefix. Maybe better to suggest it's the rest of the list, perhaps rest_since + rest_since_including but then we're using 'since' to still refer to a scan from the beginning of the list here, rather than from the end, which is what it means for 'tail'. Additional thoughts: rather than having pairs of inclusive+exclusive functions, it might be nicer if the test function could return a three-way value of "keep going"/"stop but include this element"/"stop and exclude this element", but there doesn't seem to be a convenient "natural" value in perl that could represent this. It isn't the undef/defined-but-false/true of e.g. wantarray, nor is it the -ve/zero/+ve of <=>. Finally, it might be the case that since List::Util now adds head() and tail() as functions and there is a feature to add first_index and rfirst_index, some of these behaviours can be expressed using these new functions if the LIST is available in a variable: head_upto { COND } LIST == head( first_index { COND } LIST, LIST) head_upto_including { COND } LIST == head(1 + first_index { COND } LIST, LIST) rest_since { COND } LIST == tail(-1 - first_index { COND } LIST, LIST) rest_since_including { COND } LIST == tail( - first_index { COND } LIST, LIST) tail_since_including { COND } LIST == tail( - rfirst_index { COND } LIST, LIST) tail_since { COND } LIST == tail(-1 - rfirst_index { COND } LIST, LIST) The tail variants are a little more subtle due to the negative number indexing feature of tail(); plus all cases still require that temporary variable. If added here though, they do suggest adding a rest() function to List::Util acting like rest(INDEX, LIST) === LIST[INDEX .. $#LIST] -- Paul Evans