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: Ludovic Courtès
Subject: Re: New ‘--list-generations’ and ‘--delete-generations’ options
Date: Wed, 11 Sep 2013 23:25:27 +0200
User-agent: Gnus/5.130007 (Ma Gnus v0.7) Emacs/24.3 (gnu/linux)

Nikita Karetnikov <address@hidden> skribis:

>>> How can I subtract 22 days from (current-time) using SRFI-19?
>
>> Note that the above example suggests that ‘string->duration’ returns a
>> time object with of type ‘time-duration’ (thus independent of the
>> current time.)
>
> Ah, OK.  But we’ll have to subtract from (current-time) later anyway,
> right?  Why do you want to return a ‘time-duration’ object?

To separate concerns, and to simplify testing.

> So, here’s the parsing phase.  WDYT?

Overall looks good to me, but I think it can be simplified:

> (define (string->generations str)
>   (define (maybe-integer)
>     (let ((x (string->number str)))
>       (and (integer? x)
>            (list x))))
>
>   (define (maybe-comma-separated-integers)
>     (let ((lst (delete-duplicates
>                 (map string->number
>                      (delete "" (string-split str #\,))))))
>       (and (every integer? lst)
>            lst)))


>   (define (safe-match:substring->number match n)
>     (false-if-exception (string->number (match:substring match n))))
>
>   (define (maybe-whole-range)
>     (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)))

By definition submatches 1 and 2 exist when RES is true.
Thus, I’d remove ‘safe-match:substring->number’ and do:

  (match (string-match "^([0-9]+)\\.\\.([0-9]+)$" str)
    (#f #f)
    (matches
     (let ((start (number->string (match:substring matches 1)))
           (end   (number->string (match:substring matches 2))))
       ...)))

>   (or (maybe-integer) (maybe-comma-separated-integers)
>       (maybe-whole-range) (maybe-start-range) (maybe-end-range)))

Probably this can reduce to a big ‘cond’, which would be even more
readable:

  (cond ((maybe-integer)
         =>
         list)
        ((string-match "^([0-9]+)\\.\\.([0-9]+)$" str)
         =>
         (lambda (match)
           ...))
        ...)

> (define (string->duration str)
>   (define (maybe-duration hours pattern)
>     (let ((res (regexp-exec (make-regexp pattern) str)))
>       (false-if-exception
>        (make-time time-duration 0
>                   (* 3600 hours (string->number (match:substring res 1)))))))
>
>   (define (days)
>     (maybe-duration 24 "^([0-9]+)d$"))
>
>   (define (weeks)
>     (maybe-duration (* 24 7) "^([0-9]+)w$"))
>
>   (define (months)
>     (maybe-duration (* 24 30) "^([0-9]+)m$"))
>
>   (or (days) (weeks) (months)))

Likewise, just:

  (define (hours->duration hours)
    (make-time ...))

  (cond ((string-match "^([0-9]+)d$" str)
         =>
         ...)
        ...)

Thanks,
Ludo’.



reply via email to

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