unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: Attila Lendvai <attila@lendvai.name>
To: Xinglu Chen <public@yoctocell.xyz>
Cc: "Ludovic Courtès" <ludo@gnu.org>,
	52600@debbugs.gnu.org,
	"Maxim Cournoyer" <maxim.cournoyer@gmail.com>,
	"Andrew Tropin" <andrew@trop.in>
Subject: [bug#52600] [PATCH] doc: Document (gnu services configuration).
Date: Thu, 23 Dec 2021 15:21:10 +0000	[thread overview]
Message-ID: <hOdMN_9g5xix81tudVqVNNwnm78sINdTsV2WiUWnrmWPB6iksv0buLJP8dB6GV7c8I2WxXMk1kWGzLLTOb5bwlTTOV8QVHPFQV3rEUV9T1s=@lendvai.name> (raw)
In-Reply-To: <87a6grcwh7.fsf@yoctocell.xyz>

> > i was expecting it to be possible to have a field like:
> >
> > (foo
> > (maybe-integer?))
>
> A ‘maybe-’ type doesn’t necessarily have to have a default value set to
> ‘disabled’. The default value of the ‘foo’ field could just as well be
> ‘3’ or something.


i know. but what i want is a field that is not initialized to any
value, and a way to identify that fact in the service code (e.g. to
derive a default value from another field).

example: my service has a swarm-name field, and the service's unix
user name is derived from it as "swarm-${swarm-name}" -- unless it is
set by the user and overrides it, that is.

in this case i can't set the field using the default value mechanism
of define-configuration (i.e. at construction-time), because the
default value is not a constant. the derivation of the default value
must be done by the service's code, and it must be able to detect
fields that were not set (i'm deliberately staying away from the word
'undefined' here, because the current codebase uses it, together with
"disabled", in a strange way).


> > 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.
>
> What do you mean by “undocumented value”?


a value that is opaque to the user, and can only be detected by a
predicate (and possibly constructed by another function or through an
exported global variable).


> > some of the config values in my service can conditionally derive its
> > default value based on the value of other fields.
>
> I don’t think this is possible with ‘define-configuration’ yet. But it
> would be a nice feature to have.


i don't think it belongs to the define-configuration macro, because it
would greatly increase the complexity of its DSL/implementation for
little in return; one can always cover the few complex cases from the
scheme code of the service.


> > i need to be able to differentiate between undefined or user provided
> > field values (i.e. completely independent of anything related to
> > serialization).
>
> Maybe we could change ‘undefined’ to instead be an exception, which will
> raised when the user doesn’t provide anything.


that would make the above example/scenario impossible.
although... you're probably using 'undefined' in the strange way that
it is currently used in the code.

i think the nomenclature should be clarified (regardless of what's in
the current codebase). here's my proposal:

1) undefined: no value was provided, neither at construction time, nor
  as a default value in define-configuration.

2) missing: a value must be provided at construction time, but it wasn't.

signalling an error at construction time in case of 'missing' is
probably a good idea. but then 2) is mostly covered by the type
predicates already, no? if i define the type as INTEGER? (i.e. not
MAYBE-INTEGER?), then it'll already signal an error in that case.


> > 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.
>
> I am not familiar with Guile internals, but I think that
> ‘#<unspecified>’ is just a thing that the pretty-printer prints. Maybe


it's also a special type/value (to the point that it has its own heap
object tag in Guile for which Guile's UNDEFINED? macro checks for; see
https://www.gnu.org/software/guile/manual/guile.html#index-undefined_003f).


> we could use “proper” Maybe types, like in SRFI-189[1]?
> [1]: Using https://srfi.schemers.org/srfi-189/srfi-189.html


i don't immediately see its benefits here, but i'll need to
get more familiar with this srfi. thanks for the pointer!


> > 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?
>
> But what if a user wants to set a field to ‘disabled’ (because they
> don’t want anything to get serialized), then that record would have to
> be public.


yes, but preferably through a global variable or a function. my point
is that the object's type/content should be opaque for the users.


> > 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.
>
> But what if the value itself is #f? You wouldn’t be able to distinguish
> between the cases where the value is undefined and when the value is #f.


it's a user error when it is used on fields that may legitimately hold
the #false value.


> I don’t really see a use of having that functionality; do you have any
> examples when this would be useful to have?


an example: the unix-user field of a service.

1) not specified by the admin => generate a default user name

2) admin sets it to a string => use that as user name

3) admin sets it to undefined (whichever value/API we use to mark the
   undefined value) => don't create a unix user for the service, run
   it as root instead.

but again, i'm not advocating for define-configuration to support this
use-case.

this example can easily modelled by e.g. using 'run-as-root as the
default value in define-configuration, and the service code checking
for it.


> The second paragraph explains this, no? Or do you think it can be
> improved?


true, that should be enough.

i'm also realizing that i'm talking about 1) how to change the code in
(guix service configuration) under a ticket that discusses 2) the
documentation of the current codebase.

i'll cook up a patch that implements what i'm trying to describe
above, and which is flexible enough to cover my use-cases. and then 1)
can be continued under that ticket.

- attila





  reply	other threads:[~2021-12-23 15:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-18 15:12 [bug#52600] [PATCH] doc: Document (gnu services configuration) Xinglu Chen
2021-12-22 22:14 ` Ludovic Courtès
2021-12-23 10:42   ` Xinglu Chen
     [not found]     ` <IxmgfjO9lp2ladC6D9lHKww0c_r1R0JsnoPJbKD9vg1StRq5QIaZyf3If6Jc16dYnqBdbM0VAjy2PDpZBWxwhHHvgJj_lL8sE4SJ8AsG3po=@lendvai.name>
2021-12-23 12:54       ` Xinglu Chen
2021-12-23 15:21         ` Attila Lendvai [this message]
2022-01-18  9:24         ` Attila Lendvai
2022-01-06 14:20     ` 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='hOdMN_9g5xix81tudVqVNNwnm78sINdTsV2WiUWnrmWPB6iksv0buLJP8dB6GV7c8I2WxXMk1kWGzLLTOb5bwlTTOV8QVHPFQV3rEUV9T1s=@lendvai.name' \
    --to=attila@lendvai.name \
    --cc=52600@debbugs.gnu.org \
    --cc=andrew@trop.in \
    --cc=ludo@gnu.org \
    --cc=maxim.cournoyer@gmail.com \
    --cc=public@yoctocell.xyz \
    /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).