guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New ‘--list-generations’ and ‘--delete-generations’ options


From: Nikita Karetnikov
Subject: Re: New ‘--list-generations’ and ‘--delete-generations’ options
Date: Sun, 08 Sep 2013 14:59:55 +0400

> I’m asking because if we do that, ‘--list-generations’ may just as well
> print out *all* the generation records.  Users who want to select only
> less than one-month old generations can do that with ‘recsel’, and we
> don’t have anything more to do.

> WDYT?

I see recutils as an advanced option (for those who need it), not a
replacement for the basic functionality.

> OTOH, for ‘--delete-generations’ it will still be more convenient to
> support ‘--delete-generations’.

Could you rephrase?  I don’t understand the above.  I believe we should
think from a user’s perspective.  One should be able to select the
needed generations without relying on a different program.

> I think you find it difficult to test because the parsing and generation
> enumeration are intermingled.

Right, I agree.

>>> What about splitting it in two functions:

>>>   ‘string->time-range’ → return two SRFI-19 time objects representing a
>>>                           time interval, or #f and #f on failure

>>>   ‘generation-within-time-range?’

>>> Writing tests for the former will be easy.

> What do you think of the separation I proposed?

We have the following cases: ‘1’, ‘1,2,3’, ‘1..9’, ‘1..’, ‘..9’,
‘first-month’, and ‘last-month’.  It’s easy to parse the first three and
output a list of generations without checking them.  However, you’ll
have to check the profile in the other cases.  That’s the problem.

It’s also possible to write something like this (untested):

(define (available-generations str)
  (define (integer?*)
    (integer? (string->number str)))

  (define (comma-separated-integers?)
    (every integer?
           (delete-duplicates
            (map string->number
                 (delete "" (string-split str #\,))))))

  (define (safe-match:substring->number match n)
    (false-if-exception (string->number (match:substring match n))))

  (define (maybe-whole-range-lst)
    (let* ((rx  (make-regexp "^([0-9]+)\\.\\.([0-9]+)$"))
           (res (regexp-exec rx str))
           (x   (safe-match:substring->number res 1))
           (y   (safe-match:substring->number res 2)))
      (list x y)))

  (define (whole-range?)
    (let ((x (first maybe-whole-range-lst))
          (y (last maybe-whole-range-lst)))
      (and (every integer? (maybe-whole-range-lst))
           (<= x y))))

  (define (maybe-start-range)
    (let* ((rx  (make-regexp "^([0-9]+)\\.\\.$"))
           (res (regexp-exec rx str)))
      (safe-match:substring->number res 1)))

  (define (start-range?)
    (integer? (maybe-start-range)))

  ;; ...

  )

First, this is quite wordy.  Moreover, we’ll have to move every
definition to the global namespace if we want to test only syntax.
I doubt that the above is the way to go.

I don’t understand how the ‘string->time-range’ function will help to
solve the above problem.  There are only two time-related cases:
‘first-month’ and ‘last-month’.  Why do you want to return a time range
for every case?  Could you show an example?

Attachment: pgpp4xavBHau3.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]