diff mbox series

[bug#50614,core-updates,v2] build: utils: Add ‘list-when’ macro.

Message ID ccbe07b719e498438a8f610cffa9ba274f6d608d.1632059166.git.public@yoctocell.xyz
State New
Headers show
Series [bug#50614,core-updates,v2] build: utils: Add ‘list-when’ macro. | expand

Checks

Context Check Description
cbaines/applying patch fail View Laminar job
cbaines/issue success View issue

Commit Message

Xinglu Chen Sept. 19, 2021, 1:50 p.m. UTC
* guix/build/utils.scm (list-when): New syntax
* tests/build-utils.scm ("list-when: expr1 is non-#f", list-when: expr1 is #f"):
  Test it.
* guix.texi (Build Utilities): Document it.
* .dir-locals.el: Set ‘scheme-indent-function’ to 1 for ‘list-when’.
---
Changes since v1:

* Add an entry for ‘list-when’ in .dir-locals.el.

* Some fixes to the documentation.

 .dir-locals.el        |  1 +
 doc/guix.texi         | 34 ++++++++++++++++++++++++++++++++++
 guix/build/utils.scm  | 17 ++++++++++++++++-
 tests/build-utils.scm |  8 ++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)


base-commit: 22f7d4bce1e694b7ac38e62410d76a6d46d96c5d

Comments

M Sept. 19, 2021, 2:35 p.m. UTC | #1
Xinglu Chen schreef op zo 19-09-2021 om 15:50 [+0200]:
> * guix/build/utils.scm (list-when): New syntax
> * tests/build-utils.scm ("list-when: expr1 is non-#f", list-when: expr1 is #f"):
>   Test it.
> * guix.texi (Build Utilities): Document it.
> * .dir-locals.el: Set ‘scheme-indent-function’ to 1 for ‘list-when’.
> ---

If you will be doing this in (guix build utils), leading to a world-rebuild,
you light want to define list-unless as well.  E.g., 'boost' has

    (native-inputs
     `(("perl" ,perl)
       ,@(if (%current-target-system)
             '()
             `(("python" ,python-wrapper)))
       ("tcsh" ,tcsh)))

with 'list-when', this could be rewritten to

    (native-inputs
     `(("perl" ,perl)
       ,@(list-when (not (%current-target-system))
           `("python" ,python-wrapper))
       ("tcsh" ,tcsh)))

but '(when (not ...) EXP ...)' is simply '(unless EXP ...)',
so it would be nice to be able to do

    (native-inputs
     `(("perl" ,perl)
       ,@(list-unless (%current-target-system)
           `("python" ,python-wrapper))
       ("tcsh" ,tcsh)))

Greetings,
Maxime.
Simon Tournier Sept. 20, 2021, 11:03 a.m. UTC | #2
Hi,

On Sun, 19 Sep 2021 at 15:50, Xinglu Chen <public@yoctocell.xyz> wrote:

> +@lisp
> +(if @var{test}
> +    (list @var{consequent} @dots{})
> +    '())
> +@end lisp

[...]

> +@lisp
> +(arguments
> + `(#:configure-flags (list "--localstatedir=/var"
> +                           "--sysconfdir=/etc"
> +                           ,@@(list-when (hurd-target?) "--with-courage"))))
> +@end lisp

Personally, I am not convinced it helps the readibility.  But that’s a
matter of taste. :-)

My concern is about the coherence.  First, ’list-unless’ is also
required by a similar pattern, see for instance:

--8<---------------cut here---------------start------------->8---
gnu/packages/guile.scm:162:             ,@(if (target-mingw?) '() `(("bash" ,bash-minimal)))))
--8<---------------cut here---------------end--------------->8---

And second, these 2 patterns ’list-when’ and ’list-unless’ are used in
by many files, see guix/build-system, guix/import, guix/describe,
gnu/packages, gnu/system, gnu/services files.  For the oneline pattern:
“ag --scheme '@\(if' | grep '()'”.  All should be replaced; which
implies a world-rebuild I guess.

Well, all in all, I am not convinced that all this work is worth for a
small debatable readibility improvement. :-)

All the best,
simon
diff mbox series

Patch

diff --git a/.dir-locals.el b/.dir-locals.el
index 919ed1d1c4..554044ee8c 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -56,6 +56,7 @@  ((nil
    (eval . (put 'lambda* 'scheme-indent-function 1))
    (eval . (put 'substitute* 'scheme-indent-function 1))
    (eval . (put 'match-record 'scheme-indent-function 2))
+   (eval . (put 'list-when 'scheme-indent-function 1))
 
    ;; 'modify-inputs' and its keywords.
    (eval . (put 'modify-inputs 'scheme-indent-function 1))
diff --git a/doc/guix.texi b/doc/guix.texi
index 9a3e8ae12c..4bea366b8e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8801,6 +8801,40 @@ 
         `("PATH" ":" prefix ,(list coreutils))))))
 @end lisp
 
+@subsection Miscellaneous
+
+@cindex miscellaneous build utilities
+This section documents some miscellaneous utilities.
+
+@deffn {Scheme Syntax} list-when @var{test} @var{consequent} @dots{}
+Like @code{when} (@pxref{Conditionals,,, guile, GNU Guile Reference
+Manual}), but if @var{test} evaluates to true, return @code{(list
+@var{consequent} @dots{})}, and if @var{test} evaluates to false, return
+the empty list.  This replaces the following idiom:
+@end deffn
+
+@lisp
+(if @var{test}
+    (list @var{consequent} @dots{})
+    '())
+@end lisp
+
+with this:
+
+@lisp
+(list-when @var{test} @var{consequent} @dots{})
+@end lisp
+
+It can be useful when certain targets require additional configure
+flags, e.g.,
+
+@lisp
+(arguments
+ `(#:configure-flags (list "--localstatedir=/var"
+                           "--sysconfdir=/etc"
+                           ,@@(list-when (hurd-target?) "--with-courage"))))
+@end lisp
+
 @subsection Build Phases
 
 @cindex build phases
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 3beb7da67a..d3fb207ee5 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -8,6 +8,7 @@ 
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
+;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -123,7 +124,9 @@  (define-module (guix build utils)
 
             make-desktop-entry-file
 
-            locale-category->string))
+            locale-category->string
+
+            list-when))
 
 
 ;;;
@@ -1613,6 +1616,18 @@  (define (locale-category->string category)
              LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE
              LC_TIME)))
 
+
+;;;
+;;; Misc.
+;;;
+
+;; If EXPR1 evaluates to a non-#f value, return '(EXPR2 ...).  Otherwise,
+;; return an empty list.
+(define-syntax list-when
+  (syntax-rules ()
+    ((_ expr1 expr2 ...)
+     (if expr1 (list expr2 ...) '()))))
+
 ;;; Local Variables:
 ;;; eval: (put 'call-with-output-file/atomic 'scheme-indent-function 1)
 ;;; eval: (put 'call-with-ascii-input-file 'scheme-indent-function 1)
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 6b131c0af8..b558feb47d 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -3,6 +3,7 @@ 
 ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
+;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -287,5 +288,12 @@  (define-module (test build-utils)
           ("guile/bin" . ,(dirname (which "guile"))))
         "guile"))))
 
+(test-equal "list-when: expr1 is non-#f"
+  (list 3 'bar)
+  (list-when 'foo (+ 1 2) 'bar))
+
+(test-equal "list-when: expr1 is #f"
+  '()
+  (list-when #f (+ 2 3) 'bar))
 
 (test-end)