Hi, Ludovic Courtès writes: > Howdy, > > Maxim Cournoyer 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 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.