Subject: Re: bug#36763: `guix search` does unexpected logical and

From: Ludovic Courtès <[email-masked]>
Date: Thu, 25 Jul 2019 19:35:46 +0200

Hi Simon,

zimoun <[email-masked]> skribis:

> As discussed here [1], the `relevance` in `guix/ui.scm` does not match
> "inter-field".
>
> Attached a fix.
> Now,  the example from the manual
>   $ guix search crypto library | \
>         recsel -e '! (name ~ "^(ghc|perl|python|ruby)")' -p name,synopsis
> outputs the expected crypto libraries as `libb2`.

Nice!

> Then, please indicate me how the commit has to be filled.
> The commit 8874faaaac665100a095ef25e39c9a389f5a397f introducing the
> logical AND says:
>
> ui: 'relevance' considers regexps connected with a logical and.
>
> * guix/ui.scm (relevance)[score]: Change to return 0 when one of REGEXPS
> doesn't match.
> * tests/ui.scm ("package-relevance"): New test.

Yes, you can provide a commit log along these lines.

> Should another test be added?

Yes please, that would be perfect!

> +  (define (update relevance weight scores)
> +    (map + relevance
> +           (map (lambda (score)
> +                  (* weight score))
> +                scores)))
> +
> +  (let ((scores (fold (lambda (metric relevance)
> +                        (match metric
> +                          ((field . weight)
> +                           (match (field obj)
> +                             (#f  relevance)
> +                             ((? string? str)
> +                              (update relevance weight (score str)))
> +                             ((lst ...)
> +                              (update relevance weight
> +                                      (fold (lambda (elem prev)
> +                                              (if (zero? (length elem))
> +                                                  prev
> +                                                  (map + elem prev)))
> +                                            (make-list (length regexps) 0)
> +                                            (map score lst)))
> +                              )))))
> +                      (make-list (length regexps) 0)
> +                      metrics)))

I don’t have a clear mind on that, but I feel like this could be
simplified somehow.  For instance,

  (fold p (make-list …) metrics)

looks a lot like:

  (map (lambda (x) (fold p x metrics)) regexps)

Well, something like that.  :-)

Thanks for working on it!

Ludo’.