Hello Guilers, I thought I’d share a bit about the “fancy” record constructs in Guix [0], which provide syntactic constructors, default field values, and “functional” setters.
Guix is about manipulating packages, which are essentially records with many fields. Thus, I wanted the ability to create new record instances using field names (à la SRFI-35), and to have field name checks and name-to-offset mappings happen at compile-time, so one could type things like: (package (name "hello") (version "2.8") (source (origin (method http-fetch) (uri (string-append "http://ftp.gnu.org/gnu/hello/hello-" version ; refers to the “2.8” above ".tar.gz")) (sha256 (base32 "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6")))) (build-system gnu-build-system) (description "GNU Hello") (long-description "Yeah...") (home-page "http://www.gnu.org/software/hello/") (license "GPLv3+")) and have it directly expand to a single ‘make-struct’ call, with missing or unknown fields reported at compile-time. In addition, there may be default field values. For instance, the ‘location’ field should default to (current-source-location). So I ended up with a ‘define-record-type*’ macro, based on SRFI-9, which is used like this: (define-record-type* <package> package ; the “syntactic” constructor used above make-package ; the procedural constructor package? (name package-name) (version package-version) (source package-source) ;; ... (location package-location (default (and=> (current-source-location) source-properties->location)))) Finally, these syntactic record constructors support “functional setters”, where a new record instance is created with some fields copied from an existing instance, and others set to a new value: (package (inherit coreutils) (arguments `(#:configure-flags '("--disable-nls" "--disable-silent-rules" "--enable-no-install-program=stdbuf,libstdbuf.so" "LDFLAGS=-static -pthread") ,@(package-arguments coreutils)))) Here field values are those of the ‘coreutils’ variable, except for the ‘arguments’ field. The code for this macro magic is at <https://gitorious.org/guix/guix/blobs/master/guix/utils.scm#line484>. Happy hacking! Ludo’. [0] https://gitorious.org/guix