From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: guix-package --search Date: Thu, 24 Jan 2013 22:14:12 +0100 Message-ID: <87ip6mjnbv.fsf@gnu.org> References: <87libor1c9.fsf@karetnikov.org> <87r4lfr0r3.fsf@karetnikov.org> <87obgi6v7f.fsf@gnu.org> <87r4lb29sy.fsf@karetnikov.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([208.118.235.92]:46405) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TyU7n-0004aW-Bd for bug-guix@gnu.org; Thu, 24 Jan 2013 16:14:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TyU7i-0003Jz-V2 for bug-guix@gnu.org; Thu, 24 Jan 2013 16:14:19 -0500 Received: from mail1-relais-roc.national.inria.fr ([192.134.164.82]:57507) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TyU7i-0003Jh-PC for bug-guix@gnu.org; Thu, 24 Jan 2013 16:14:14 -0500 In-Reply-To: <87r4lb29sy.fsf@karetnikov.org> (Nikita Karetnikov's message of "Wed, 23 Jan 2013 10:33:50 -0500") List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org To: Nikita Karetnikov Cc: bug-guix@gnu.org Nikita Karetnikov skribis: >> Instead, you can directly build the list of matching packages, like: > >> (fold-packages (lambda (package result) >> (if (or (regexp-exec rx (package-synopsis package)) >> (regexp-exec rx (package-description package)= )) >> (cons package result) >> result)) >> '()) > >> This way, only one traversal is done. > > 'regexp-exec' will raise an error if either 'synopsis' or 'description' > is not a string. That's why I wrapped it in 'false-if-exception'. OK. >> For i18n, we should actually use (gettext (package-description >> package)), likewise for synopsis. This way, that will search through >> text in the user=E2=80=99s native language. > > I added it, but I haven't properly tested it. Also, there is > 'remove-duplicates' that works in the REPL. Yes, see below. > +(define (find-packages-by-description rx) > + "Search in SYNOPSIS and DESCRIPTION using RX. Return a list of > +matching packages." > + (define (remove-duplicates pred lst) > + ;; Remove duplicates from sorted LST using PRED. > + (cond ((null-list? lst) lst) > + ((=3D (length lst) 1) lst) > + ((=3D (length lst) 2) > + (if (pred (first lst) (second lst)) (cdr lst) lst)) > + ((pred (first lst) (second lst)) > + (remove-duplicates pred (cdr lst))) > + (else (cons (first lst) (remove-duplicates pred (cdr lst)))))) First, can you use =E2=80=98delete-duplicates=E2=80=99 from (srfi srfi-1) i= nstead? > + (define (same-location? p1 p2) > + ;; Compare locations of two packages. > + (eq? (package-location p1) (package-location p2))) Here you need to use =E2=80=98equal?=E2=80=99, not =E2=80=98eq?=E2=80=99: = =E2=80=98equal?=E2=80=99 checks for structural equality, whereas =E2=80=98eq?=E2=80=99 checks for pointer equality (info "= (guile) Equality"). > + (remove-duplicates > + same-location? > + (stable-sort > + (fold-packages > + (lambda (package result) > + (if (or (false-if-exception > + (regexp-exec rx (gettext (package-synopsis package)))) > + (false-if-exception > + (regexp-exec rx (gettext (package-description package)))= )) > + (cons package result) > + result)) Instead of =E2=80=98false-if-exception=E2=80=99, I=E2=80=99d prefer: (lambda (package result) (define matches? (cut regexp-exec rx <>)) (if (or (and=3D> (package-synopsis package) (compose matches? gettext)) ... Other than that it looks good to me! Could you please also add a couple of tests in tests/guix-package.sh, and the corresponding doc in guix.texi? Thanks! Ludo=E2=80=99.