[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Layout of ‘define-configuration’ records
From: |
Maxim Cournoyer |
Subject: |
Re: Layout of ‘define-configuration’ records |
Date: |
Fri, 18 Nov 2022 11:44:53 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) |
Hi Ludo,
Ludovic Courtès <ludo@gnu.org> writes:
> Hi,
>
> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
>
>> This is so that the first field of the generated record matches the first one
>> declared, which makes 'define-configuration' record API compatible with
>> define-record-type* ones.
>>
>> * gnu/services/configuration.scm (define-configuration-helper): Move the
>> %location field below the ones declared by the user.
>> * gnu/services/monitoring.scm (zabbix-front-end-config): Adjust match pattern
>> accordingly.
>
> [...]
>
>> +++ b/gnu/services/configuration.scm
>> @@ -242,17 +242,17 @@ (define-record-type* #,(id #'stem #'< #'stem #'>)
>> stem
>> #,(id #'stem #'make- #'stem)
>> #,(id #'stem #'stem #'?)
>> - (%location #,(id #'stem #'stem #'-location)
>> - (default (and=> (current-source-location)
>> - source-properties->location))
>> - (innate))
>> #,@(map (lambda (name getter def)
>> #`(#,name #,getter (default #,def)
>> (sanitize
>> #,(id #'stem #'validate- #'stem #'-
>> name))))
>> #'(field ...)
>> #'(field-getter ...)
>> - #'(field-default ...)))
>> + #'(field-default ...))
>> + (%location #,(id #'stem #'stem #'-location)
>> + (default (and=> (current-source-location)
>> + source-properties->location))
>> + (innate)))
>
> Moving the field last is problematic as we’ve seen for any user that
> uses ‘match’ on records—something that’s not recommended but still used
> a lot.
Yep. I had that on mind when I made the change, though I still missed a
few occurrences.
>> (define (zabbix-front-end-config config)
>> (match-record config <zabbix-front-end-configuration>
>> - (%location db-host db-port db-name db-user db-password db-secret-file
>> - zabbix-host zabbix-port)
>> + (db-host db-port db-name db-user db-password db-secret-file
>> + zabbix-host zabbix-port %location)
>
> This change has no effect because ‘match-record’ matches fields by name,
> precisely to avoid problems when changing the layout of record types.
Good catch; I got confused there, although my confusion luckily had no
side effect :-).
> I’m not sure what was meant by “compatible” in the commit log; how
> fields are laid out is something user code should not be aware of.
I wanted match on define-configuration'd fields to be
backward-compatible with fields migrated from define-record-type*, so
that they such change can be made without worrying breakages. It seems
good for consistency that both our define-record-type* and
define-configuration fields share a similar internal layout, at least
until all the old-fashion (ice-9 match) record matching usages are
rewritten to use something like 'match-record'.
I initially got tricked by that discrepancy and it took me quite some
time hunting down a cryptic backtrace when authoring the new mcron
configuration records.
> The only thing to keep in mind is that records must not be matched with
> ‘match’ because then the code silently breaks when the record type
> layout is changed. This is why ‘match-record’ was introduced:
>
> https://issues.guix.gnu.org/28960#4
>
> One last thing: placing ‘%location’ first can let us implement:
>
> (define (configuration-location config)
> (struct-ref config 0))
Would this have worked?
--8<---------------cut here---------------start------------->8---
scheme@(gnu services mcron)> (define config (mcron-configuration))
scheme@(gnu services mcron)> (struct-ref 0 config)
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure struct-ref: Wrong type argument in position 1 (expecting struct): 0
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme@(gnu services mcron) [1]> ,q
scheme@(gnu services mcron)> ,use (oop goops)
scheme@(gnu services mcron)> (class-of config)
$5 = #<<class> <<mcron-configuration>> 7fe20fd83e00>
--8<---------------cut here---------------end--------------->8---
All in all, I think that's a rather small change that got our internal
implementation of both type of records in sync between
define-configuration and define-record-type*, that should pave the way
for migrating more of the later to the former without risking breaking
something, going forward.
Alternatively, if we have a good reason to not to go with this, I think
we should abstract all the internal-implementation dependent code from
our code base (e.g., the match patterns directly matching on field
slots).
What do you think?
--
Thanks,
Maxim
- Layout of ‘define-configuration’ records, Ludovic Courtès, 2022/11/17
- Re: Layout of ‘define-configuration’ records,
Maxim Cournoyer <=
- Re: Layout of ‘define-configuration’ records, Katherine Cox-Buday, 2022/11/19
- Re: Layout of ‘define-configuration’ records, Katherine Cox-Buday, 2022/11/21
- Re: Layout of ‘define-configuration’ records, Maxim Cournoyer, 2022/11/21
- Re: Layout of ‘define-configuration’ records, zimoun, 2022/11/22
- Re: Layout of ‘define-configuration’ records, Maxim Cournoyer, 2022/11/25
Re: Layout of ‘define-configuration’ records, Ludovic Courtès, 2022/11/21