unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
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


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