unofficial mirror of bug-guix@gnu.org 
 help / color / mirror / code / Atom feed
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: 56799@debbugs.gnu.org, attila@lendvai.name
Subject: bug#56799: (gnu services configuration) usage of *unspecified* is problematic
Date: Tue, 09 Aug 2022 20:43:06 -0400	[thread overview]
Message-ID: <87bkstnd2d.fsf@gmail.com> (raw)
In-Reply-To: <877d3omc9c.fsf@gnu.org> ("Ludovic Courtès"'s message of "Thu, 04 Aug 2022 14:19:59 +0200")

[-- Attachment #1: Type: text/plain, Size: 3331 bytes --]

Hi,

Ludovic Courtès <ludo@gnu.org> writes:

> Howdy,
>
> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

[...]

>> I think mostly because few services make use of define-configuration.
>> While attempting to write a new VNC service, it quickly became a visible
>> annoyance:
>>
>> (define-configuration/no-serialization xvnc-configuration
>
> [...]
>
>>   (port
>>    maybe-port
>>    "The port on which to listen for connections from viewers.  When left
>> unspecified, it defaults to 5900 plus the display number.")
>
> [...]
>
>> (define (xvnc-shepherd-service config)
>>   "Return a <shepherd-service> for Xvnc with CONFIG."
>>   ;; XXX: Ensure all the *unspecified* values are handled outside of gexps, as
>>   ;; they are not valid gexp input (they are not self-quoting/serializable).
>>   ;; This would otherwise cause problem during 'guix deploy'.
>>   (let* ((display-number (xvnc-configuration-display-number config))
>>          (port (if (unspecified? (xvnc-configuration-port config))
>>                    #f
>>                    (xvnc-configuration-port config)))
>
> OK, I see.  I guess most of the time, we just call
> ‘serialize-xyz-configuration’, which automatically handles *unspecified*
> values.  In this case, ‘port’ is treated specially and instead passed as
> a command-line argument.

Yes, and that provides much welcome flexibility, as records are
serializable (as vectors) so long as the values they contain also are.

> Other ways to address that come to mind include: adding ‘port’ to the
> config file instead of on the command line (if possible), or doing:
>
>   (serialize-configuration config
>                            (find (lambda (field)
>                                    (eq? (configuration-field-name field)
>                                         'port))
>                                  xvnc-configuration-fields))
>
> That’s a mouthful but maybe it could be abstracted.  It does sound less
> convenient though.

Xvnc takes no config switch, and I agree the above is not
intuitive/great.  It also wouldn't fix the use case of places it is more
convenient to have the maybe value expanded into the gexp and dealt with
there, such as used in the jami-service-type and in my previous example
making use of a inetd style service, where shepherd-side only bindings
such as endpoint makes it convenient to place the ports logic inside the
service gexp.

> That said, whether it’s ‘unspecified?’ or something else, you have to
> have a check in place, right?  With the new interface it becomes:
>
>  (if (eq? port 'unset) #f port)
>
> Or you can provide an actual default value (an integer in this case),
> but that’s possible whether or not *unspecified* is the default value.

To me, the main use of maybe values is to allow for the daemon to use
its own default when no value is specified.  A maybe value with a
default value makes little sense to me, so we should move toward
eliminating that style and support for it from define-configuration, in
my opinion.  Things would be a bit easier to reason with then.

As a baby step toward making 'unset a properly hidden implementation
detail, I'd suggest the attached patch, which adds a means to check if a
value was set.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-services-configuration-Add-a-maybe-value-set-procedu.patch --]
[-- Type: text/x-patch, Size: 2435 bytes --]

From ac84f836a5a6c451465a879521a306b6fbcbed50 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Date: Fri, 5 Aug 2022 15:03:55 -0400
Subject: [PATCH] services: configuration: Add a 'maybe-value-set?' procedure.

* gnu/services/configuration.scm (maybe-value-set?): New procedure.
* doc/guix.texi (Complex Configurations): Document it.  Remove comment showing
usage of 'maybe-string' with a default value, which doesn't make sense.
---
 doc/guix.texi                  | 7 ++++++-
 gnu/services/configuration.scm | 5 +++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index eb3a1a4eb5..ccdd01f321 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -38998,7 +38998,7 @@ to be a string, or left unspecified.
   (name
    ;; If set to a string, the `serialize-string' procedure will be used
    ;; to serialize the string.  Otherwise this field is not serialized.
-   maybe-string    ; equivalent to (maybe-string *unspecified*)
+   maybe-string
    "The name of this module."))
 @end lisp
 
@@ -39029,6 +39029,11 @@ whether its value is set or not.
 @end lisp
 @end deffn
 
+@deffn (Scheme Procedure) maybe-value-set? @var{value}
+Predicate to check whether a user explicitly specified the value of a
+maybe field.
+@end deffn
+
 @deffn {Scheme Procedure} serialize-configuration @var{configuration} @
 @var{fields}
 Return a G-expression that contains the values corresponding to the
diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm
index 3007e8de35..b41b4d2e62 100644
--- a/gnu/services/configuration.scm
+++ b/gnu/services/configuration.scm
@@ -57,6 +57,7 @@ (define-module (gnu services configuration)
             serialize-configuration
             define-maybe
             define-maybe/no-serialization
+            maybe-value-set?
             generate-documentation
             configuration->documentation
             empty-serializer
@@ -300,6 +301,10 @@ (define-configuration stem (field field-type+def
 (define (empty-serializer field-name val) "")
 (define serialize-package empty-serializer)
 
+(define (maybe-value-set? value)
+  "Predicate to check whether a 'maybe' value was explicitly provided."
+  (not (eq? 'unset value)))
+
 ;; A little helper to make it easier to document all those fields.
 (define (generate-documentation documentation documentation-name)
   (define (str x) (object->string x))
-- 
2.36.1


[-- Attachment #3: Type: text/plain, Size: 642 bytes --]


[...]

> With the xvnc example, I better understand the kind of situation where
> a field value might end up directly in a gexp, though I’m still unsure
> whether use of *unspecified* really makes things worse.  At least,
> because it lacks a read syntax, the problem is caught early on; whereas
> with 'unset, you might end up stuffing 'unset in your config file
> without noticing.

I've been experimenting a lot with define-configuration recently and it
gives you little chance to shoot yourself in the foot; it knows maybe
values are not to be serialized, and won't wrote such values to config
files.

Thanks,

Maxim

  parent reply	other threads:[~2022-08-10  0:44 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-27 16:23 bug#56799: (gnu services configuration) usage of *unspecified* is problematic Maxim Cournoyer
2022-07-27 16:43 ` Tobias Geerinckx-Rice via Bug reports for GNU Guix
2022-07-27 18:27   ` Attila Lendvai
2022-07-28 15:15     ` Maxim Cournoyer
2022-07-27 18:31   ` Maxim Cournoyer
2022-07-27 18:45     ` Tobias Geerinckx-Rice via Bug reports for GNU Guix
2022-07-27 19:09       ` Maxim Cournoyer
2022-07-27 19:45         ` bug#56799: [PATCH] services: configuration: Step back from *unspecified* Maxim Cournoyer
2022-07-27 19:46         ` bug#56799: (gnu services configuration) usage of *unspecified* is problematic Maxim Cournoyer
2022-07-27 20:20           ` bug#56799: [PATCH v2] gexp: Handle *unspecified* as a gexp input Maxim Cournoyer
2022-07-27 21:43             ` Maxime Devos
2022-07-28 14:58               ` Maxim Cournoyer
2022-07-28  4:41           ` bug#56799: [PATCH v3] " Maxim Cournoyer
2022-08-01  5:08             ` bug#56799: (gnu services configuration) usage of *unspecified* is problematic Maxim Cournoyer
2022-08-01 10:00               ` Maxime Devos
2022-08-01 12:46                 ` Maxim Cournoyer
2022-08-01 13:44             ` Ludovic Courtès
2022-08-01 16:55       ` Maxim Cournoyer
2022-07-28  4:55     ` bokr
2022-07-28 10:26       ` Maxime Devos
2022-07-28 15:09         ` Maxim Cournoyer
2022-08-01 13:49 ` Ludovic Courtès
2022-08-01 15:55   ` Maxim Cournoyer
2022-08-02  7:31     ` Ludovic Courtès
2022-08-02  8:45       ` bokr
2022-08-02 15:06       ` Maxim Cournoyer
2022-08-04 12:19         ` Ludovic Courtès
2022-08-07 22:44           ` Ludovic Courtès
2022-08-08 22:27           ` Attila Lendvai
2022-08-08 23:35             ` Attila Lendvai
2022-08-10  2:17               ` Maxim Cournoyer
2022-08-10  3:26             ` Maxim Cournoyer
2022-08-11 10:15               ` Attila Lendvai
2022-08-13  6:31                 ` Maxim Cournoyer
2022-08-13 16:47                   ` Attila Lendvai
2022-08-14  2:57                     ` Maxim Cournoyer
2022-08-16 14:00                       ` Attila Lendvai
2022-08-17 13:16                         ` Maxim Cournoyer
2022-08-17 16:00                           ` paren--- via Bug reports for GNU Guix
2022-08-10  0:43           ` Maxim Cournoyer [this message]
2022-08-24 12:40 ` bug#56799: [PATCH 1/5] services: configuration: Add a 'maybe-value-set?' procedure Attila Lendvai
2022-08-24 12:40   ` bug#56799: [PATCH 2/5] services: configuration: Add %unset-value exported variable Attila Lendvai
2022-08-24 12:40   ` bug#56799: [PATCH 3/5] services: configuration: Add maybe-value exported procedure Attila Lendvai
2022-08-24 12:40   ` bug#56799: [PATCH 4/5] services: Use the new maybe/unset API Attila Lendvai
2022-08-25  4:18     ` bug#56799: (gnu services configuration) usage of *unspecified* is problematic Maxim Cournoyer
2022-08-24 12:40   ` bug#56799: [PATCH 5/5] services: configuration: Change the value of the unset marker Attila Lendvai
2022-08-25  4:14     ` bug#56799: (gnu services configuration) usage of *unspecified* is problematic Maxim Cournoyer

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=87bkstnd2d.fsf@gmail.com \
    --to=maxim.cournoyer@gmail.com \
    --cc=56799@debbugs.gnu.org \
    --cc=attila@lendvai.name \
    --cc=ludo@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.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

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