Subject: [bug#52600] (No Subject)

From: Attila Lendvai <[email-masked]>
Date: Wed, 22 Dec 2021 10:50:06 +0000

typos:

> +A clause can have one the following forms

'of' missing.

> to generate documentation for and configuration records

extra 'and'.

---------------

as for some higher level feedback:

i have just finished my first Guix service, a rather complex one. based on the examples, and on the config codebase itself, i had used define-configuration, and i had encountered a surprise WRT undefined values and maybe- types (only after that have i found this documentation).

> default-value is the default value corresponding to the field; if
> none is specified, the user is forced to provide a value when creating
> an object of the record type.

i was expecting it to be possible to have a field like:

(foo
(maybe-integer?))

and its behavior would be to hold an undocumented value by default, that the service implementations need to check for using a public predicate function. (well, short of reimplementing a full-fledged object system with field accessor abstractions, i.e. something like BOUNDP in common lisp).

some of the config values in my service can conditionally derive its default value based on the value of other fields. i need to be able to differentiate between undefined or user provided field values (i.e. completely independent of anything related to serialization).

the reason i don't recommend the use of 'undefined is fields like this that would wrongly be considered valid when no value is provided:

(foo
(symbol?))

> Sometimes a field should not be serialized if the user doesn’t specify a
> value. To achieve this, you can use the @code{define-maybe} macro to
> define a ``maybe type''; if the value of a maybe type is set to the
> @code{disabled}, it will not be serialized.

the use of 'disabled here was very confusing because configuration objects are typically full of boolean fields... is 'disabled a valid app value, or part of the guix API? confusing to the point that i have confidently reported it as a "bug" on #guix in the maybe- implementation to use 'disabled instead of 'undefined.

maybe we should use guile's *undefined*, and undefined? predicate (which is sadly a macro). or reexport an undefined? function, and shadow guile's macro? it's messy, and guile specific.

or maybe we could use a heap object of an unusual/private type in a global private variable to represent undefined field values, and add a public predicate to test for it. using a cons cell for this is tempting, but it would leak implementation details for fields of type cons?. i'm new to scheme, but the best candidate is maybe a private dummy record instance?

i'd add a configuration-undefined-value? predicate, and also add a configuration-defined-value? whose semantics is to return the value itself, or #false when undefined. it comes handy in (or (defined-value? foo) 42) patterns for non-boolean fields.

in fact, i had these two in my service impl, before reading/writing any of this:

(define (defined-value? x)
(if (eq? x 'undefined) #false x))

(define (undefined-value? x)
(eq? x 'undefined))

then the question arises: do we want to differentiate between the cases when the field value comes from a default form, and when it is set by the user (e.g. at object construction time)? if so, then one well-known value as a marker is not enough, but i don't think it's worth the additional complexity. people with rare, complex use-cases can always resort to define-record*.

------------------

another thing that has initially misled me was the word 'serialize': i don't have a better suggestion, but i have associated it to a more formal serialize/deserialize protocol, as opposed to turning scheme objects into various different configuration file formats that are native for the target binary.

maybe it's worth hinting at in the documentation where serialization is first mentioned.

------------------

if the API of validate-configuration is to raise errors, then maybe it could return the config object if everything is fine. that can simplify the code at the call site.

HTH,

- attila
PGP: 5D5F 45C7 DFCD 0A39