gnus: Ranges

 
 11.7.5 Ranges
 -------------
 
 GNUS introduced a concept that I found so useful that I’ve started using
 it a lot and have elaborated on it greatly.
 
    The question is simple: If you have a large amount of objects that
 are identified by numbers (say, articles, to take a _wild_ example) that
 you want to qualify as being “included”, a normal sequence isn’t very
 useful.  (A 200,000 length sequence is a bit long-winded.)
 
    The solution is as simple as the question: You just collapse the
 sequence.
 
      (1 2 3 4 5 6 10 11 12)
 
    is transformed into
 
      ((1 . 6) (10 . 12))
 
    To avoid having those nasty ‘(13 . 13)’ elements to denote a lonesome
 object, a ‘13’ is a valid element:
 
      ((1 . 6) 7 (10 . 12))
 
    This means that comparing two ranges to find out whether they are
 equal is slightly tricky:
 
      ((1 . 5) 7 8 (10 . 12))
 
    and
 
      ((1 . 5) (7 . 8) (10 . 12))
 
    are equal.  In fact, any non-descending list is a range:
 
      (1 2 3 4 5)
 
    is a perfectly valid range, although a pretty long-winded one.  This
 is also valid:
 
      (1 . 5)
 
    and is equal to the previous range.
 
    Here’s a BNF definition of ranges.  Of course, one must remember the
 semantic requirement that the numbers are non-descending.  (Any number
 of repetition of the same number is allowed, but apt to disappear in
 range handling.)
 
      range           = simple-range / normal-range
      simple-range    = "(" number " . " number ")"
      normal-range    = "(" start-contents ")"
      contents        = "" / simple-range *[ " " contents ] /
                        number *[ " " contents ]
 
    Gnus currently uses ranges to keep track of read articles and article
 marks.  I plan on implementing a number of range operators in C if The
 Powers That Be are willing to let me.  (I haven’t asked yet, because I
 need to do some more thinking on what operators I need to make life
 totally range-based without ever having to convert back to normal
 sequences.)