Re: Layout of ‘define-configuration’ records

2022-11-25 Thread Maxim Cournoyer
Hi Simon,

zimoun  writes:

> Hi Maxim,
>
> On Mon, 21 Nov 2022 at 16:00, Maxim Cournoyer  
> wrote:
>
>> That sounds very appropriate indeed.  I guess we could send
>> announcements on API breaking changes to both places.  I suppose not
>> many people are registered to 'info-guix' (I wasn't myself until
>> recently ^^').
>
> Well, more is better here, no? :-)
>
>
>> I guess that's a question of how disruptive the API change is, but it'd
>> be convenient if it was 2 weeks to match the time the change might
>> appear on guix-patches un-reviewed.
>
> Well, the process for API change could be:
>
>  1. + submit to guix-patches,
> + in the same time, announce to guix-devel; so people not subscribed to
>   guix-patches can chime.
>  2. + after 2 weeks, or consensus, merge the change,
> + in the same time, announce to guix-devel, info-guix and --news.
>
> There is no extra burden and it smooths the change for many users, IMHO.
>
> WDYT?

This sounds reasonable to me, with the addition that the "core" team
members should be added as CC when submitting the API changing patch(es)
(etc/teams.scm cc core).

-- 
Thanks,
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-25 Thread Maxim Cournoyer
Hi Ludovic,

Ludovic Courtès  writes:

> Hi,
>
> Maxim Cournoyer  skribis:
>
>> Ludovic Courtès  writes:

[...]

>> Ah!  Thanks for pointing my silly mistake.  Then the argument would
>> become... if it's good for define-configuration, it should have been
>> good for define-record-type* the same (why the discrepancy?).
>
> ‘define-record-type*’ is generic; there’s no reason for it to add a
> ‘location’ field.
>
>> After your new documentation in place to guide users to DTRT with
>> regards to matching records, if you think %location should be the first
>> field, then we should make it so in both instances, perhaps?
>
> ‘%location’ only appears in ‘define-configuration’; what did you mean by
> “both instances”?

Hmm, that's right.  Nevermind, I thought the later had a %location
"special" field too.

>> Oops!  Another point to add to our future coding style guidelines :-).
>
> In the end, I guess the lesson is that, indeed, not all the design
> choices and rationales are properly documented.  That’ll always be the
> case to a large extent though, so changes “close to the core” require
> more careful review and discussion to fully understand the implications
> of the change—it might look innocuous but have broader implications than
> expected.

Agreed.  I'll try to make better use of the etc/teams.scm script in the
future to ping the right people for such changes.

-- 
Thanks,
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-23 Thread Ludovic Courtès
Hi,

Maxim Cournoyer  skribis:

> Ludovic Courtès  writes:

[...]

 One last thing: placing ‘%location’ first can let us implement:

   (define (configuration-location config)
 (struct-ref config 0))
>>>
>>> Would this have worked?
>>>
>>> scheme@(gnu services mcron)> (define config (mcron-configuration))
>>> scheme@(gnu services mcron)> (struct-ref 0 config)
>>
>> You got the order wrong.  :-)
>
> Ah!  Thanks for pointing my silly mistake.  Then the argument would
> become... if it's good for define-configuration, it should have been
> good for define-record-type* the same (why the discrepancy?).

‘define-record-type*’ is generic; there’s no reason for it to add a
‘location’ field.

> After your new documentation in place to guide users to DTRT with
> regards to matching records, if you think %location should be the first
> field, then we should make it so in both instances, perhaps?

‘%location’ only appears in ‘define-configuration’; what did you mean by
“both instances”?

> Oops!  Another point to add to our future coding style guidelines :-).

In the end, I guess the lesson is that, indeed, not all the design
choices and rationales are properly documented.  That’ll always be the
case to a large extent though, so changes “close to the core” require
more careful review and discussion to fully understand the implications
of the change—it might look innocuous but have broader implications than
expected.

Thanks,
Ludo’.



Re: Layout of ‘define-configuration’ records

2022-11-22 Thread zimoun
Hi Maxim,

On Mon, 21 Nov 2022 at 16:00, Maxim Cournoyer  wrote:

> That sounds very appropriate indeed.  I guess we could send
> announcements on API breaking changes to both places.  I suppose not
> many people are registered to 'info-guix' (I wasn't myself until
> recently ^^').

Well, more is better here, no? :-)


> I guess that's a question of how disruptive the API change is, but it'd
> be convenient if it was 2 weeks to match the time the change might
> appear on guix-patches un-reviewed.

Well, the process for API change could be:

 1. + submit to guix-patches,
+ in the same time, announce to guix-devel; so people not subscribed to
  guix-patches can chime.
 2. + after 2 weeks, or consensus, merge the change,
+ in the same time, announce to guix-devel, info-guix and --news.

There is no extra burden and it smooths the change for many users, IMHO.

WDYT?

Cheers,
simon



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Maxim Cournoyer
Hi,

Ludovic Courtès  writes:

> Hi Maxim,
>
> Maxim Cournoyer  skribis:
>
>> Ludovic Courtès  writes:
>
> [...]
>
 +   (%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.
>
> [...]
>
>> 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.
>
> That had the opposite effect: it introduced breakage precisely because
> existing uses of ‘match’ on records need to be verified manually, one by
> one.

Yes.  C.f. "I missed a few occurrences" above :-).

> That led me to improve ‘match-record’, to recommend it in the manual,
> and do “convert” some uses of ‘match’ to ‘match-record’:
>
>   https://issues.guix.gnu.org/59390
>
> That’s a good outcome, but I’d prefer not feeling this kind of pressure.

Neat (not the under pressure part)!  Perhaps srfi-worthy?

>> 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.
>
> I see.  However, this is a wide-ranging change, so I think this should
> have been discussed separately from the mcron changes.  I find it
> important to take time for review and discussion for such changes.
>
>>> One last thing: placing ‘%location’ first can let us implement:
>>>
>>>   (define (configuration-location config)
>>> (struct-ref config 0))
>>
>> Would this have worked?
>>
>> scheme@(gnu services mcron)> (define config (mcron-configuration))
>> scheme@(gnu services mcron)> (struct-ref 0 config)
>
> You got the order wrong.  :-)

Ah!  Thanks for pointing my silly mistake.  Then the argument would
become... if it's good for define-configuration, it should have been
good for define-record-type* the same (why the discrepancy?).

After your new documentation in place to guide users to DTRT with
regards to matching records, if you think %location should be the first
field, then we should make it so in both instances, perhaps?

>> 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.
>
> Fundamentally, the layout of record types should not be visible to
> users.  That it is visible via ‘match’ is the problem, and the solution
> is not to tweak record type layout but instead tp make sure ‘match’ uses
> on records vanish.
>
> I hope that makes sense!

Yes, and I agree.

>> scheme@(gnu services mcron)> ,use (oop goops)
>
> Speaking of which: there was a conscious decision to not use GOOPS in
> Guix from day one.  Perhaps some day we’ll want to collectively question
> that, but let’s make sure we don’t add that dependency on a whim.
>
> For example:
>
>   class-of -> struct-vtable
>   class-name -> record-type-name
>
> See commit 50c17ddd9e2983d71c125d89b422fd20fca476e1 for an example.

Oops!  Another point to add to our future coding style guidelines :-).
Thanks for showing the simple workaround to goops.

-- 
Thanks,
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Maxim Cournoyer
Hi Katherine,

Katherine Cox-Buday  writes:

> Maxim Cournoyer  writes:
>
>> Apologies for causing grief!
>
> No worries at all, Maxim! The good you do far outweighs any grief, and
> even if that weren't the case, we're only human :)
>
>> I'm taking yours and Ludovic's feedback into account for the future
>> and will reach out to guix-devel with heads-up when introducing
>> breaking changes to Guix APIs.
>
> This seems like the logical place to me, but it's also a bit busy for
> announcements! I'm sure I'm not alone, but sometimes I'm very busy and
> distracted and I need a very loud signal to let me know I need to take
> action :) That's why I suggested info-guix. Its description reads:
>
> #+begin_quote
> Subscribe to the info-guix low-traffic mailing list to receive important
> announcements sent by the project maintainers (in English).
> #+end_quote

That sounds very appropriate indeed.  I guess we could send
announcements on API breaking changes to both places.  I suppose not
many people are registered to 'info-guix' (I wasn't myself until
recently ^^').

> Would it make sense to publish there? I don't think we break APIs very often?
>
> Also, do we need any kind of formalization around lead-time for these
> announcements?

I guess that's a question of how disruptive the API change is, but it'd
be convenient if it was 2 weeks to match the time the change might
appear on guix-patches un-reviewed.

I'll try to do this in the future (better yet, try to not affect APIs at
all); if it works well for everybody, we could formalize that in our
contributing section.

-- 
Thanks,
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Maxim Cournoyer
Hi,

Ludovic Courtès  writes:

> Maxim Cournoyer  skribis:
>
>> A side-note, it seems that Ludovic has been
>> working toward eliminating the use of match patterns matching the fields
>> directly, instead encouraging the use of 'match-record', see
>> https://issues.guix.gnu.org/59390.  I haven't checked if this is
>> compatible with define-configuration records though.
>
> It is: ‘define-configuration’ builds on ‘define-record-type*’, which
> builds on SRFI-9, which builds on Guile “records”, which builds on Guile
> “structs”.  :-)

Excellent!  Thanks for having confirmed that.

-- 
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Katherine Cox-Buday
Maxim Cournoyer  writes:

> Apologies for causing grief!

No worries at all, Maxim! The good you do far outweighs any grief, and
even if that weren't the case, we're only human :)

> I'm taking yours and Ludovic's feedback into account for the future
> and will reach out to guix-devel with heads-up when introducing
> breaking changes to Guix APIs.

This seems like the logical place to me, but it's also a bit busy for
announcements! I'm sure I'm not alone, but sometimes I'm very busy and
distracted and I need a very loud signal to let me know I need to take
action :) That's why I suggested info-guix. Its description reads:

#+begin_quote
Subscribe to the info-guix low-traffic mailing list to receive important
announcements sent by the project maintainers (in English).
#+end_quote

Would it make sense to publish there? I don't think we break APIs very often?

Also, do we need any kind of formalization around lead-time for these
announcements?

> A side-note, it seems that Ludovic has been working toward eliminating
> the use of match patterns matching the fields directly, instead
> encouraging the use of 'match-record', see
> https://issues.guix.gnu.org/59390. I haven't checked if this is
> compatible with define-configuration records though.

Thanks, I'll have a look!

-- 
Katherine



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Ludovic Courtès
Maxim Cournoyer  skribis:

> A side-note, it seems that Ludovic has been
> working toward eliminating the use of match patterns matching the fields
> directly, instead encouraging the use of 'match-record', see
> https://issues.guix.gnu.org/59390.  I haven't checked if this is
> compatible with define-configuration records though.

It is: ‘define-configuration’ builds on ‘define-record-type*’, which
builds on SRFI-9, which builds on Guile “records”, which builds on Guile
“structs”.  :-)

--8<---cut here---start->8---
scheme@(guile-user)> ,m (gnu home services desktop)
scheme@(gnu home services desktop)> (home-redshift-configuration)
$1 = #< redshift: # location-provider: geoclue2 
adjustment-method: randr daytime-temperature: 6500 nighttime-temperature: 4500 
daytime-brightness: %unset-marker% nighttime-brightness: %unset-marker% 
latitude: %unset-marker% longitude: %unset-marker% dawn-time: %unset-marker% 
dusk-time: %unset-marker% extra-content: "" %location: #f>
scheme@(gnu home services desktop)> (match-record $1 
 (adjustment-method nighttime-temperature)
... (list nighttime-temperature adjustment-method))
$2 = (4500 randr)
--8<---cut here---end--->8---

Ludo’.



Re: Layout of ‘define-configuration’ records

2022-11-21 Thread Ludovic Courtès
Hi Maxim,

Maxim Cournoyer  skribis:

> Ludovic Courtès  writes:

[...]

>>> +   (%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.

[...]

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

That had the opposite effect: it introduced breakage precisely because
existing uses of ‘match’ on records need to be verified manually, one by
one.

That led me to improve ‘match-record’, to recommend it in the manual,
and do “convert” some uses of ‘match’ to ‘match-record’:

  https://issues.guix.gnu.org/59390

That’s a good outcome, but I’d prefer not feeling this kind of pressure.

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

I see.  However, this is a wide-ranging change, so I think this should
have been discussed separately from the mcron changes.  I find it
important to take time for review and discussion for such changes.

>> One last thing: placing ‘%location’ first can let us implement:
>>
>>   (define (configuration-location config)
>> (struct-ref config 0))
>
> Would this have worked?
>
> scheme@(gnu services mcron)> (define config (mcron-configuration))
> scheme@(gnu services mcron)> (struct-ref 0 config)

You got the order wrong.  :-)

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

Fundamentally, the layout of record types should not be visible to
users.  That it is visible via ‘match’ is the problem, and the solution
is not to tweak record type layout but instead tp make sure ‘match’ uses
on records vanish.

I hope that makes sense!

> scheme@(gnu services mcron)> ,use (oop goops)

Speaking of which: there was a conscious decision to not use GOOPS in
Guix from day one.  Perhaps some day we’ll want to collectively question
that, but let’s make sure we don’t add that dependency on a whim.

For example:

  class-of -> struct-vtable
  class-name -> record-type-name

See commit 50c17ddd9e2983d71c125d89b422fd20fca476e1 for an example.

Thanks,
Ludo’.



Re: Layout of ‘define-configuration’ records

2022-11-20 Thread Maxim Cournoyer
Hi Katherine,

Katherine Cox-Buday  writes:

> Maxim Cournoyer  writes:
>
>>> 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.
>
> Some feedback I hope is useful:
>
> I'm one such newbie, and had to stumble my way into discovering why some
> of my services suddenly broke. All I had to go on was with "invalid
> G-expression input" at a location in an `operating-system` declaration.
>
> Initially, because of the reference to gexps, I thought something had
> changed with `local-file` which I am using to deploy source code off of
> a local branch. Through trial and error and reading git logs, I
> discovered this was not the case, and saw that `define-configuration`
> had changed. From there I was able to discover the problem.
>
>> Yep. I had that on mind when I made the change, though I still missed
>> a few occurrences.
>
> I came looking for an announcement of this change somewhere on a mailing
> list (info-guix maybe?) or the Guix blog but couldn't find anything. I
> understand the focus is on in-repo code, but could we consider
> announcing changes which might affect channels and such? I don't always
> have time to stay up to date with the changes to the project :(

Apologies for causing grief!  Ironically, the change was motivated by
going through such pain myself when attempting to migrate the
mcron-configuration from a define-record-type* to a define-configuration
produced record, that's why I wanted to standardize their layout.

I'm taking yours and Ludovic's feedback into account for the future and
will reach out to guix-devel with heads-up when introducing breaking
changes to Guix APIs.  A side-note, it seems that Ludovic has been
working toward eliminating the use of match patterns matching the fields
directly, instead encouraging the use of 'match-record', see
https://issues.guix.gnu.org/59390.  I haven't checked if this is
compatible with define-configuration records though.

-- 
Thanks,
Maxim



Re: Layout of ‘define-configuration’ records

2022-11-19 Thread Katherine Cox-Buday
Maxim Cournoyer  writes:

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

Some feedback I hope is useful:

I'm one such newbie, and had to stumble my way into discovering why some
of my services suddenly broke. All I had to go on was with "invalid
G-expression input" at a location in an `operating-system` declaration.

Initially, because of the reference to gexps, I thought something had
changed with `local-file` which I am using to deploy source code off of
a local branch. Through trial and error and reading git logs, I
discovered this was not the case, and saw that `define-configuration`
had changed. From there I was able to discover the problem.

> Yep. I had that on mind when I made the change, though I still missed
> a few occurrences.

I came looking for an announcement of this change somewhere on a mailing
list (info-guix maybe?) or the Guix blog but couldn't find anything. I
understand the focus is on in-repo code, but could we consider
announcing changes which might affect channels and such? I don't always
have time to stay up to date with the changes to the project :(

-- 
Katherine



Re: Layout of ‘define-configuration’ records

2022-11-18 Thread Maxim Cournoyer
Hi Ludo,

Ludovic Courtès  writes:

> Hi,
>
> Maxim Cournoyer  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 
>> -(%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 = #< <> 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