unofficial mirror of help-guix@gnu.org 
 help / color / mirror / Atom feed
From: Joshua Branson <jbranso@dismail.de>
To: help-guix@gnu.org
Subject: When and how should one use "(thunked)" from (guix records)?
Date: Tue, 19 Oct 2021 04:38:12 -0400	[thread overview]
Message-ID: <87bl3lxvd7.fsf@dismail.de> (raw)

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:

https://notabug.org/jbranso/linode-guix-system-configuration/src/master/opensmtpd-records.scm

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?).

#+BEGIN_EXAMPLE
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.
#+END_EXAMPLE

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
      opensmtpd-action?
      this-record
      (name opensmtpd-action-name
            (default "local"))
      (relay opensmtpd-action-relay
             (default "#f")
      (local-delivery opensmtpd-action-local-delivery ;;type <opensmtpd-local-delivery-configuration>
                      ;; local-delivery has a default value so (service opensmtpd-service) will just work for
                      ;; local email delivery
                      (default (opensmtpd-local-delivery-configuration))
                      (thunked)
                      (sanitize (lambda (value)
                                  (cond
                                   ;; 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)
                                       #f] 
                                   [(opensmtpd-local-delivery-configuration? value)
                                       value] 
                                   [else
                                    (display (string-append "<opensmtpd-action> fieldname 'local-delivery' "
                                                            "needs to be of type <opensmtpd-local-delivery-configuration>.\n"))
                                    (throw 'bad! value)])))))
#+END_SRC

* 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
    opensmtpd-table?
    this-record
    ;; string
    ;; is a list of values or key values
    ;; eg: (list "mysite.me" "your-site.com")
    ;; eg: (list ("joshua" . "joshua@gnu.org") ("james" . "james@gnu.org"))
    (values opensmtpd-table-values
            (default #f)
            (sanitize (lambda (value)
                        (if (or (list-of-strings? value)
                                (assoc-list? value))
                            value
                            (begin
                              (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)
          (thunked)
          (sanitize (lambda (value)
                      (if (list-of-strings? (opensmtpd-table-values this-record))
                          (quote list-of-strings)
                          (quote assoc-list))))))
#+END_SRC

* I found this is the guix source code...I'm not sure what the (thunked) offers...
#+BEGIN_SRC scheme
;; Configuration of an Xorg server.
(define-record-type* <xorg-configuration>
  xorg-configuration make-xorg-configuration
  xorg-configuration?
  (modules          xorg-configuration-modules    ;list of packages
                    (thunked)
                    ; filter out modules not supported on current system
                    (default (filter
                              (lambda (p)
                                (member (%current-system)
                                        (package-supported-systems p)))
                              %default-xorg-modules)))
  (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)))

#+END_SRC



                 reply	other threads:[~2021-10-19  8:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87bl3lxvd7.fsf@dismail.de \
    --to=jbranso@dismail.de \
    --cc=help-guix@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).