summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Elsing <david.elsing@posteo.net>2026-02-03 21:33:21 +0100
committerLudovic Courtès <ludo@gnu.org>2026-02-10 23:46:34 +0100
commit96bd7262777f7f67cdd83c28171425f6bbcf3d50 (patch)
treef345bfe791ee6c9cf00d2a639dee8bdfcc12ffcd
parent7d1b86859b84d8af0ad9a21648be431d169f216f (diff)
gexp: Add 'delayed-object'.
* guix/gexp.scm (<delayed-object>): New record type. (delayed-object): New macro. (delayed-object-compiler): New gexp compiler. * tests/gexp.scm ("delayed-object"): New test. * doc/guix.texi (G-Expressions): Document it. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
-rw-r--r--doc/guix.texi10
-rw-r--r--guix/gexp.scm20
-rw-r--r--tests/gexp.scm15
3 files changed, 45 insertions, 0 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index ce67ea9c827..a3b17578a8f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -148,6 +148,7 @@ Copyright @copyright{} 2025 Edouard Klein@*
148Copyright @copyright{} 2025 Rodion Goritskov@* 148Copyright @copyright{} 2025 Rodion Goritskov@*
149Copyright @copyright{} 2025 dan@* 149Copyright @copyright{} 2025 dan@*
150Copyright @copyright{} 2025 Noé Lopez@* 150Copyright @copyright{} 2025 Noé Lopez@*
151Copyright @copyright{} 2026 David Elsing@*
151 152
152Permission is granted to copy, distribute and/or modify this document 153Permission is granted to copy, distribute and/or modify this document
153under the terms of the GNU Free Documentation License, Version 1.3 or 154under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -12982,6 +12983,15 @@ The example above returns an object that corresponds to the i686 build
12982of Coreutils, regardless of the current value of @code{%current-system}. 12983of Coreutils, regardless of the current value of @code{%current-system}.
12983@end defmac 12984@end defmac
12984 12985
12986@defmac delayed object exp
12987This macro delays the evaluation of @var{exp} until the returned object
12988is lowered to a derivation or store item.
12989
12990Its intended use case is to prevent the use of a non-delayed top-level
12991variable of another module, e.g. when using a gexp in the @code{source}
12992field of a @var{package}.
12993@end defmac
12994
12985@anchor{gexp-input} 12995@anchor{gexp-input}
12986@deffn {Procedure} gexp-input @var{obj} [@var{output}] [#:native? #f] 12996@deffn {Procedure} gexp-input @var{obj} [@var{output}] [#:native? #f]
12987Return a @dfn{gexp input} record for the given @var{output} of file-like 12997Return a @dfn{gexp input} record for the given @var{output} of file-like
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 030092843a3..5305678b342 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -6,6 +6,7 @@
6;;; Copyright © 2020 Maxim Cournoyer <maxim@guixotic.coop> 6;;; Copyright © 2020 Maxim Cournoyer <maxim@guixotic.coop>
7;;; Copyright © 2021, 2022 Maxime Devos <maximedevos@telenet.be> 7;;; Copyright © 2021, 2022 Maxime Devos <maximedevos@telenet.be>
8;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz> 8;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz>
9;;; Copyright © 2026 David Elsing <david.elsing@posteo.net>
9;;; 10;;;
10;;; This file is part of GNU Guix. 11;;; This file is part of GNU Guix.
11;;; 12;;;
@@ -96,6 +97,10 @@
96 with-parameters 97 with-parameters
97 parameterized? 98 parameterized?
98 99
100 delayed-object
101 delayed-object?
102 delayed-object-promise
103
99 load-path-expression 104 load-path-expression
100 gexp-modules 105 gexp-modules
101 106
@@ -778,6 +783,21 @@ x86_64-linux when COREUTILS is lowered."
778 (obj ;store item 783 (obj ;store item
779 obj))))))))) 784 obj)))))))))
780 785
786;; Object which evaluates its promise when it is lowered.
787(define-record-type <delayed-object>
788 (%delayed-object promise)
789 delayed-object?
790 (promise delayed-object-promise))
791
792(define-syntax-rule (delayed-object body ...)
793 "Delays the evaluation of BODY to lowering time of the return object."
794 (%delayed-object (delay (begin body ...))))
795
796(define-gexp-compiler (delayed-object-compiler (object <delayed-object>)
797 system target)
798 (with-monad %store-monad
799 (return (force (delayed-object-promise object)))))
800
781 801
782;;; 802;;;
783;;; Inputs & outputs. 803;;; Inputs & outputs.
diff --git a/tests/gexp.scm b/tests/gexp.scm
index 3622324a153..bba8c141f63 100644
--- a/tests/gexp.scm
+++ b/tests/gexp.scm
@@ -1,6 +1,7 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014-2025 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2014-2025 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2021-2022 Maxime Devos <maximedevos@telenet.be> 3;;; Copyright © 2021-2022 Maxime Devos <maximedevos@telenet.be>
4;;; Copyright © 2026 David Elsing <david.elsing@posteo.net>
4;;; 5;;;
5;;; This file is part of GNU Guix. 6;;; This file is part of GNU Guix.
6;;; 7;;;
@@ -518,6 +519,20 @@
518 (return (and (eq? drv0 result0) 519 (return (and (eq? drv0 result0)
519 (eq? drv1 result1))))) 520 (eq? drv1 result1)))))
520 521
522(test-assertm "delayed-object"
523 (let ((evaluated #f))
524 (mlet* %store-monad ((drv (package->derivation coreutils))
525 (obj -> (delayed-object
526 (begin
527 (set! evaluated #t)
528 coreutils)))
529 (first-evaluated -> evaluated)
530 (result (lower-object obj)))
531 (return (and (string=? (derivation-file-name drv)
532 (derivation-file-name result))
533 (not first-evaluated)
534 evaluated)))))
535
521(test-assert "with-parameters + file-append" 536(test-assert "with-parameters + file-append"
522 (let* ((system (match (%current-system) 537 (let* ((system (match (%current-system)
523 ("aarch64-linux" "x86_64-linux") 538 ("aarch64-linux" "x86_64-linux")