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