[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fancy records in Guix

From: Ludovic Courtès
Subject: Fancy records in Guix
Date: Sun, 04 Nov 2012 00:13:56 +0100
User-agent: Gnus/5.130005 (Ma Gnus v0.5) Emacs/24.2 (gnu/linux)

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

      (name "hello")
      (version "2.8")
      (source (origin
               (method http-fetch)
               (uri (string-append "";
                                   version  ; refers to the “2.8” above
      (build-system gnu-build-system)
      (description "GNU Hello")
      (long-description "Yeah...")
      (home-page "";)
      (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

    (name   package-name)
    (version package-version)
    (source package-source)

    ;; ...

    (location package-location
              (default (and=> (current-source-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)
          "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

Happy hacking!



reply via email to

[Prev in Thread] Current Thread [Next in Thread]