[Top][All Lists]

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

When and how should one use "(thunked)" from (guix records)?

From: Joshua Branson
Subject: When and how should one use "(thunked)" from (guix records)?
Date: Tue, 19 Oct 2021 04:38:12 -0400

Hey guix!  I'm trying to flush out the (guix records) for the
=opensmtpd-service=.  It's super fun doing it by the way.  If you've
never messed with (guix records) then you should totally give it a
try.  Thanks for the author of (guix records).  You did a really great
job!  The purpose of this email is to get some suggestions on my
opensmtpd-records.scm file and to use this email as a VERY ROUGH draft
for a (guix records) blog post, if there is interest in it.  :)

The code that I have so far can be seen here:

I'm open to suggestions.  :)

I have a basic procedure that turns a <opensmtpd-configuration> into a string...

(define (opensmtpd-configuration->string record)

I've had a ton of fun using the =(thunked)= bit in records.  The
documentation in the source code says something like this (also does
the guix manual document guix records somewhere?).

The 'port' field is \"thunked\", meaning that calls like '(thing-port x)' will
actually compute the field's value in the current dynamic extent, which is
useful when referring to fluids in a field's value.  Furthermore, that thunk
can access the record it belongs to via the 'this-thing' identifier.

I've found some "too-clever" ways of using (thunked) that people on
irc mentioned may NOT be wise to use.  For example, using (thunked) to
define mutually exclusive fieldnames and a fieldname that returns
another fieldnames value.  I think these are not "good" ways of using
(thunked).  Anyone have any good ideas for using (thunked)?

Below is some obligatory code.

* This bit of guix records shows off the =(thunked)= and =this-record=.
=(thunked)= lets you refer to the record that is being defined.  In
this case, I am defining mutually exclusive fieldnames...If =relay= is
defined, then =local-delivery= returns =#f= as its value, which is
pretty awesome.

*Note*: a simpler way to define a mutually exclusive fieldnames is to
have one fieldname that accepts =<cat-record>= or =<dog-record>=.  

#+BEGIN_SRC scheme
    (define-record-type* <opensmtpd-action>
      opensmtpd-action make-opensmtpd-action
      (name opensmtpd-action-name
            (default "local"))
      (relay opensmtpd-action-relay
             (default "#f")
      (local-delivery opensmtpd-action-local-delivery ;;type 
                      ;; local-delivery has a default value so (service 
opensmtpd-service) will just work for
                      ;; local email delivery
                      (default (opensmtpd-local-delivery-configuration))
                      (sanitize (lambda (value)
                                   ;; if relay has a value, then local-delivery 
should be #f
                                   ;; man (guix records) rocks!
                                   ;; TODO/FIXME, perhaps I should merge 
fieldnames 'relay', 'local-delivery', 'forward-only',
                                   ;; and 'expand-only' into one fildname 
called "method".  Then the user has to use a specific
                                   ;; record type to be mutually exclusive.
                                   [(opensmtpd-action-relay this-record)
                                    (display (string-append "<opensmtpd-action> 
fieldname 'local-delivery' "
                                                            "needs to be of 
type <opensmtpd-local-delivery-configuration>.\n"))
                                    (throw 'bad! value)])))))

* This bit of guix records defines a fieldname which returns the type of 
another fieldname

Fieldname =type= returns the type of values that =values= has either
='list-of-strings= or ='assoc-list=.

*Note*: It is probably better to define a function outside of the
record that returns the type that value is.  That just makes it
conceptually easier for the next hacker.

#+BEGIN_SRC scheme
  (define-record-type* <opensmtpd-table>
    opensmtpd-table make-opensmtpd-table
    ;; string
    ;; is a list of values or key values
    ;; eg: (list "" "")
    ;; eg: (list ("joshua" . "") ("james" . ""))
    (values opensmtpd-table-values
            (default #f)
            (sanitize (lambda (value)
                        (if (or (list-of-strings? value)
                                (assoc-list? value))
                              (display "<opensmtpd-table> fieldname: 'value' 
must be a list of strings or an association list.\n")
                              (throw 'bad! value))))))
    ;; can be of type: (quote list-of-strings) or (quote assoc-list)
    ;; type is discovered during the initialition phase.  The user SHOULD NEVER 
set the type.
    ;; TODO jpoiret: on irc reccomends that I just use an outside function to 
determine fieldname 'values', type.
    ;; it would be "simpler" and possibly easier for the next person working on 
this code to understand what is happening.
    (type opensmtpd-table-type
          (default #f)
          (sanitize (lambda (value)
                      (if (list-of-strings? (opensmtpd-table-values 
                          (quote list-of-strings)
                          (quote assoc-list))))))

* I found this is the guix source code...I'm not sure what the (thunked) 
#+BEGIN_SRC scheme
;; Configuration of an Xorg server.
(define-record-type* <xorg-configuration>
  xorg-configuration make-xorg-configuration
  (modules          xorg-configuration-modules    ;list of packages
                    ; filter out modules not supported on current system
                    (default (filter
                              (lambda (p)
                                (member (%current-system)
                                        (package-supported-systems p)))
  (fonts            xorg-configuration-fonts      ;list of packges
                    (default %default-xorg-fonts))
  (drivers          xorg-configuration-drivers    ;list of strings
                    (default '()))
  (resolutions      xorg-configuration-resolutions ;list of tuples
                    (default '()))
  (keyboard-layout  xorg-configuration-keyboard-layout ;#f | <keyboard-layout>
                    (default #f))
  (extra-config     xorg-configuration-extra-config ;list of strings
                    (default '()))
  (server           xorg-configuration-server     ;package
                    (default xorg-server))
  (server-arguments xorg-configuration-server-arguments ;list of strings
                    (default %default-xorg-server-arguments)))


reply via email to

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