summaryrefslogtreecommitdiff
path: root/guix/records.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-06-11 22:57:33 +0200
committerLudovic Courtès <ludo@gnu.org>2015-06-11 23:33:32 +0200
commit8a16d064fa265c449d136ff6c3d3267e314cde8d (patch)
treeb564649d1a1e3fd704a5a9efe0cfa5f421252df6 /guix/records.scm
parent792798f48647ef664cfe6fdd7ff313901e383f6c (diff)
downloadgnu-guix-8a16d064fa265c449d136ff6c3d3267e314cde8d.tar
gnu-guix-8a16d064fa265c449d136ff6c3d3267e314cde8d.tar.gz
records: Add support for 'innate' fields.
* guix/records.scm (make-syntactic-constructor): Add #:innate parameter. [record-inheritance]: Honor it. [innate-field?]: New procedure. (define-record-type*)[innate-field?]: New procedure. Pass #:innate to 'make-syntactic-constructor'. * tests/records.scm ("define-record-type* & inherit & innate", "define-record-type* & thunked & innate"): New tests.
Diffstat (limited to 'guix/records.scm')
-rw-r--r--guix/records.scm20
1 files changed, 16 insertions, 4 deletions
diff --git a/guix/records.scm b/guix/records.scm
index 816e9f6f01..b68aaae1c4 100644
--- a/guix/records.scm
+++ b/guix/records.scm
@@ -51,6 +51,7 @@ fields, and DELAYED is the list of identifiers of delayed fields."
((_ type name ctor (expected ...)
#:thunked thunked
#:delayed delayed
+ #:innate innate
#:defaults defaults)
(define-syntax name
(lambda (s)
@@ -73,8 +74,11 @@ fields, and DELAYED is the list of identifiers of delayed fields."
#`(make-struct type 0
#,@(map (lambda (field index)
(or (field-inherited-value field)
- #`(struct-ref #,orig-record
- #,index)))
+ (if (innate-field? field)
+ (wrap-field-value
+ field (field-default-value field))
+ #`(struct-ref #,orig-record
+ #,index))))
'(expected ...)
(iota (length '(expected ...))))))
@@ -84,6 +88,9 @@ fields, and DELAYED is the list of identifiers of delayed fields."
(define (delayed-field? f)
(memq (syntax->datum f) 'delayed))
+ (define (innate-field? f)
+ (memq (syntax->datum f) 'innate))
+
(define (wrap-field-value f value)
(cond ((thunked-field? f)
#`(lambda () #,value))
@@ -164,7 +171,8 @@ may look like this:
thing?
(name thing-name (default \"chbouib\"))
(port thing-port
- (default (current-output-port)) (thunked)))
+ (default (current-output-port)) (thunked))
+ (loc thing-location (innate) (default (current-source-location))))
This example defines a macro 'thing' that can be used to instantiate records
of this type:
@@ -190,7 +198,8 @@ It is possible to copy an object 'x' created with 'thing' like this:
(thing (inherit x) (name \"bar\"))
This expression returns a new object equal to 'x' except for its 'name'
-field."
+field and its 'loc' field---the latter is marked as \"innate\", so it is not
+inherited."
(define (field-default-value s)
(syntax-case s (default)
@@ -202,6 +211,7 @@ field."
(define-field-property-predicate delayed-field? delayed)
(define-field-property-predicate thunked-field? thunked)
+ (define-field-property-predicate innate-field? innate)
(define (wrapped-field? s)
(or (thunked-field? s) (delayed-field? s)))
@@ -251,6 +261,7 @@ field."
(let* ((field-spec #'((field get properties ...) ...))
(thunked (filter-map thunked-field? field-spec))
(delayed (filter-map delayed-field? field-spec))
+ (innate (filter-map innate-field? field-spec))
(defaults (filter-map field-default-value
#'((field properties ...) ...))))
(with-syntax (((field-spec* ...)
@@ -278,6 +289,7 @@ field."
(field ...)
#:thunked #,thunked
#:delayed #,delayed
+ #:innate #,innate
#:defaults #,defaults))))))))
(define* (alist->record alist make keys