From: raid5atemyhomework <raid5atemyhomework@protonmail.com>
To: Taylan Kammer <taylan.kammer@gmail.com>
Cc: "guix-devel@gnu.org" <guix-devel@gnu.org>
Subject: Re: A new paradigm for modifying operating system declarations
Date: Tue, 05 Jan 2021 00:32:37 +0000 [thread overview]
Message-ID: <wEn0P9ApnHneT6FM9S5lzaf_-Xsdf_x1CCVJJTSW5g4nqI9sflDyZuRJOWdCNYFq6DL26lDSTlQy5cwulmkfDQF1i_b4jM6gqhVzTMKQzKs=@protonmail.com> (raw)
In-Reply-To: <87b59430-b53e-47ec-32d5-abbd3be42ce7@gmail.com>
Good morning Taylan,
> First, let me point out a more conventional alternative to what your
> 'decorate' macro does:
>
> (define (compose proc . rest)
> "Functional composition; e.g. ((compose x y) a) = (x (y a))."
> (if (null? rest)
> proc
> (let ((rest-proc (apply compose rest)))
> (lambda x
> (let-values ((x (apply rest-proc x)))
> (apply proc x))))))
>
> This allows for something like:
>
> ((compose install-foo install-bar install-zfs)
> (operating-system ...))
>
> Or perhaps cleaner:
>
> (define my-os-modifier (compose install-foo install-bar install-zfs))
>
> (my-os-modifier
> (operating-system ...))
>
> If you need custom modifications within, you can do:
>
> (define my-os-modifier
> (compose install-foo
> (lambda (os) ...)
> install-bar))
>
> It's more verbose, but doesn't "break" standard Scheme syntax as much.
> Function composition is conceptually pretty easy and probably more
> well-known than "decorators" (which I had never heard of, personally).
Yes, except function composition does not work on syntactic forms, which is why, with `compose`, you have to separate the `operating-system` form instead of being able to compose `operating-system` with the rest of the os modifications.
The intent is that you have already an existing `operating-system` form with a single layer of parenthesis. With `compose`, if you want to install ZFS and a bunch of other complex OS modifications, you have to add a layer of parenthesis. With `decorate`, you don't:
```scheme
((compose install-zfs install-foo)
(operating-system
(name "my-system") #;...))
;vs
(decorate (install-zfs
install-foo
operating-system)
(nmae "my-system") #;...)
```
>
> Fewer macros means the reader needs to keep fewer special rules in mind.
Fine, I'm doubling down then.
```scheme
(define-syntax compose-syntax
(syntax-rules ()
((compose-syntax (x ...))
(syntax-rules ::: ()
((form args :::)
(x ... args :::))))
((compose-syntax x)
(syntax-rules ::: ()
((form args :::)
(x args :::))))
((compose-syntax (x ...) y ...)
(syntax-rules ::: ()
((form args :::)
(let-syntax ((sub-syntax (compose-syntax y ...)))
(x ... (sub-syntax args :::))))))
((compose-syntax x y ...)
(syntax-rules ::: ()
((form args :::)
(let-syntax ((sub-syntax (compose-syntax y ...))
(x (sub-syntax args :::)))))))))
```
Then use it as follows:
```
(define-syntax my-operating-system
(compose-syntax
(install-zfs #:options '(("zfs_arc_max" 5000000000)) #:os)
operating-system))
(my-operating-system
(name "my-system") #;...)
```
Again, the goal here is to keep the nestedness of your existing, very long `operating-system` form, which your simple `compose` function fails to do, because you can't compose syntax with `compose` and `operating-system` is a syntax form.
>
> Secondly, I wonder if passing an OS declaration through various
> procedures that modify it is really the best approach in the first place.
>
> For build phases, we have the 'modify-phases' syntax. For services,
> there is 'modify-services'. Maybe there should be a 'modify-os' kind of
> syntax. (In other words, if we're going to invent new syntax, why not
> go all-out and create the most convenient syntax for the use-case.)
Because a *generic* form to modify the operating system is worthless --- you can just define the operating-system directly.
What `install-zfs` does is that it installs the same kernel-specific package in three different points:
* `kernel-loadable-modules`, because ZFS needs to get into the kernel somehow.
* `packages`, because the kernel module is useless if you don't have the userland tools to interact with the kernel module.
* `services`, because ZFS is well-documented outside of Guix as automatically mounting its filesystems at bootup, but that actually requires a bit of magic in the `init` system, specifically you need to actually **load** the module, then execute `zpool import -a -l` to have it scan for all filesystems and mount those that need automounting.
Thus, an `install-zfs`, that is a *single* form that inserts the correct bits in the correct ***three*** places, makes the experience of adding ZFS to your `operating-system` easier because there's less scope for error in actually adding the package. You just add a single `install-zfs`, not add three things (plus an extra `(define my-zfs (make-zfs-package linux-libre-5.4))` before your form).
Now, if this kind of simplifying form is useful for ZFS, I imagine that this kind of simplifying form would also exist for other things you could install into your operating system in the future. Thus, we need some way to take an existing `<operating-system>` and pass it through a number of single simplifying operating system transformations, which I don't think something like `modify-os` would work well with.
Thanks
raid5atemyhomework
next prev parent reply other threads:[~2021-01-05 0:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-04 15:38 A new paradigm for modifying operating system declarations raid5atemyhomework
2021-01-04 20:21 ` Taylan Kammer
2021-01-05 0:32 ` raid5atemyhomework [this message]
2021-01-05 6:12 ` Carlo Zancanaro
2021-01-05 10:01 ` raid5atemyhomework
2021-01-04 23:26 ` Jan Wielkiewicz
2021-01-05 0:46 ` raid5atemyhomework
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='wEn0P9ApnHneT6FM9S5lzaf_-Xsdf_x1CCVJJTSW5g4nqI9sflDyZuRJOWdCNYFq6DL26lDSTlQy5cwulmkfDQF1i_b4jM6gqhVzTMKQzKs=@protonmail.com' \
--to=raid5atemyhomework@protonmail.com \
--cc=guix-devel@gnu.org \
--cc=taylan.kammer@gmail.com \
/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).