unofficial mirror of 
 help / color / mirror / Atom feed
* When and how should one use "(thunked)" from (guix records)?
@ 2021-10-19  8:38 Joshua Branson
  0 siblings, 0 replies; only message in thread
From: Joshua Branson @ 2021-10-19  8:38 UTC (permalink / raw)
  To: help-guix

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 <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))
                      (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)
                                   [(opensmtpd-local-delivery-configuration? value)
                                    (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 this-record))
                          (quote list-of-strings)
                          (quote assoc-list))))))

* 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
  (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)))


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-10-19  8:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-19  8:38 When and how should one use "(thunked)" from (guix records)? Joshua Branson

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