guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A friendlier API for operating-system declarations


From: antlers
Subject: Re: A friendlier API for operating-system declarations
Date: Mon, 19 Feb 2024 19:42:16 -0800
User-agent: Cyrus-JMAP/3.11.0-alpha0-153-g7e3bb84806-fm-20240215.007-g7e3bb848

Oh, thank you! Don't study too closely-- I'm quite the novice myself,
having come upon your work in search of better solutions, and the
drawbacks I described are rather notable; but I appreciate that you
see what I was going for.

(I'd be much happier with it if I could interrogate `(guix record)`
structures for the `plain | thunked | delayed` distinction and hide
that from the user, as that's what really prevents me from
recommending wider use, but understanding of the module eludes me.)

On Mon, Feb 19, 2024, at 5:53 PM, Edouard Klein wrote:
> This is awesome. I need to study your macro to understand how you wrote
> it. I've only written a handful of macro in my life, and came to lisp
> via common lisp, from which I've learned quite a lot apprently bad
> habits, so I'm lost in scheme-land.
>
> I'll study your system, thant _you_ for your reply !
>
> Cheers,
>
> Edouard.
>
>
> antlers <antlers@illucid.net> writes:
>
>> Hi!
>>
>> Just wanted to say that I really admire your take on end-user service 
>> configuration in the Beaver Labs channel.
>>
>> I gravitated towards composing functions over `operating-systems` myself, 
>> though
>> my config is probably only ""notable"" for the moderately-cursed 
>> `modify-record`
>> macro that I use to derive/configure/wrap the services[1]:
>>
>> ```
>> (define (os-with-yubi parent users*)
>>   (modify-record parent
>>     (groups -> (cons (user-group (name "plugdev")) <>))
>>     (users  -> (map (lambda (user)
>>                       (if (member (user-account-name user)
>>                                   users*)
>>                           (modify-record user
>>                             (supplementary-groups -> (cons "plugdev" <>)))
>>                           user))
>>                     <>))
>>     (services => (append <> (list
>>       (service pcscd-service-type)
>>       (simple-service 'u2f-udev-rules udev-service-type
>>                       (list (specification->package "libu2f-host")))
>>       (simple-service 'yubi-udev-rules udev-service-type
>>                       (list (specification->package 
>> "yubikey-personalization"))))))))
>> ```
>>
>>
>> It's like if `modify-services` was generalized over any kind of record, but
>> instead of using pre-defined verbs like `remove`, the `body` component of 
>> each
>> `(field-name -> body)` clause is wrapped in an implicit SRFI-26 `cut`-like[2]
>> form to create an anonymous function that's applied to the field's value. 
>> It's a
>> super leaky abstraction because I use a different symbol for `->` depending 
>> on
>> whether that record-field is a plain value, a thunk, or a `delay`-ed form 
>> (and
>> it could be implemented more efficiently), but it greatly reduces the length 
>> and
>> indentation level of repeatedly nested, inherited record variations.
>>
>> ```
>> ((compose os-with-yubi
>>           [...])
>>    [operative-system])
>> ```
>>
>> I only wrote a handful of top-level `operating-system transformation` 
>> functions,
>> and IIRC I only composed them at that top level; I think the way that you've
>> broken them up into smaller forms and composed them out of each other though
>> deeper, standard-functional composition gives you that same additive benefit
>> over would-be nested forms, with each definition roughly matching up to one 
>> my
>> "anonymous" invocations.
>>
>> What I still dwell on is whether there's a way to further minimize the
>> code-volume of including additional functionality (as was pondered in a prior
>> response, and as `modify-record` does in obsoleting `modify-services`'s 
>> verbs),
>> and how best to avoid order-dependencies and expose inherit
>> inter-service-configuration dependencies and conflicts. Tropin's RDE uses an
>> emacs or systemd-esque `provides`/`requires` system which is satisfying, but
>> introduces implicit standardization on the symbols associated with software
>> roles and builds a significant graph of them, which I feel adds to the 
>> "bulk" of
>> the (still very elegant) solution and embraces the need to wrap every service
>> and transformation into their cohesive system-- that's part of what's kept 
>> me on
>> plain Guix with my bandaid-solutions (in the spirit of learning the standard
>> approach before exploring larger systems built on top of it).
>>
>> Anyway, I like your take, just fount it today and got to thinking-- thanks 
>> for putting it out there~
>>
>> 1: From: 
>> https://github.com/AutumnalAntlers/old-guix-config/blob/main/modules/antlers/systems/transformations/yubi.scm
>> 2: Like `cut`, but deeper: see the `<>` symbol nested deep within in the 
>> `users` clause of the Yubi example.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]