all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Thompson, David" <dthompson2@worcester.edu>
To: "Taylan Ulrich Bayırlı/Kammer" <taylanbayirli@gmail.com>
Cc: guix-devel <guix-devel@gnu.org>
Subject: Re: Some macros to make package definitions prettier
Date: Wed, 25 Feb 2015 12:04:31 -0500	[thread overview]
Message-ID: <CAJ=RwfaVe-7Q5gV-487NeWD_TBhiWZA8jrUaeyhoo12yXZV8ZA@mail.gmail.com> (raw)
In-Reply-To: <874mqa6iz4.fsf@taylan.uni.cx>

On Wed, Feb 25, 2015 at 11:42 AM, Taylan Ulrich Bayırlı/Kammer
<taylanbayirli@gmail.com> wrote:
> I would propose the following macros to make package definitions
> somewhat nicer:

I've been thinking that we need some macros for this for awhile!
Thanks for getting the conversation started.

>
> ;;; modify-phases
>
> (define-syntax modify-phases
>   (syntax-rules ()
>     ((modify-phases phases mod-spec ...)
>      (let* ((phases* phases)
>             (phases* (%modify-phases phases* mod-spec))
>             ...)
>        phases*))))
>
> (define-syntax %modify-phases
>   (syntax-rules (delete replace add-before add-after)
>     ((_ phases (delete old-phase-name))
>      (alist-delete 'old-phase-name phases))
>     ((_ phases (replace old-phase-name new-phase))
>      (alist-replace 'old-phase-name new-phase phases))
>     ((_ phases (add-before old-phase-name new-phase-name new-phase))
>      (alist-cons-before 'old-phase-name 'new-phase-name new-phase phases))
>     ((_ phases (add-after old-phase-name new-phase-name new-phase))
>      (alist-cons-after 'old-phase-name 'new-phase-name new-phase phases))))
>
> ;;; Usage example:
>
> (modify-phases '((foo . 0) (bar . 1) (baz . 2))
>   (delete foo)
>   (replace bar 'x)
>   (add-before baz pre-baz 'y)) ;=> ((bar . x) (pre-baz . y) (baz . 2))
>
>
> This has the following advantages:
>
> - The order in which the phases are modified is top-down, where in our
>   current style it's bottom-up which both distracts (IMO), and one may
>   forget, as the chain grows and one forgets that it's indeed just a
>   chain of function calls like (foo (bar (baz x))).
>
> - Indentation doesn't keep growing as one adds more modifications.
>
> - It's easier for Scheme-newcomers, though one might say alists are
>   pretty simple and fundamental and should be learned immediately...

I like the top-down ordering and the linear structure rather than a
nested structure like we have currently.

I understand the temptation to name it 'modify-phases', but since this
macro applies to any alist, I think 'modify-alist' or something with
"alist" in the name would be more appropriate.

>
> And secondly:
>
> ;;; phase-lambda
>
> (define-syntax phase-lambda
>   (syntax-rules ()
>     ((phase-lambda ((arg (alist-entry ...))
>                     ...)
>        body ...)
>      (lambda* (#:key arg ... #:allow-other-keys)
>        (let-values (((alist-entry ...)
>                      (let ((arg* arg))
>                        (values
>                         (assoc-ref arg* (symbol->string 'alist-entry))
>                         ...)))
>                     ...)
>          body ...)))))
>
> ;;; Usage example:
>
> (phase-lambda ((inputs (libx liby))
>                (outputs (out)))
>   ...)
>
> ;;; effectively equivalent to:
>
> (lambda* (#:key inputs outputs #:allow-other-keys)
>   (let ((libx (assoc-ref inputs "libx"))
>         (liby (assoc-ref inputs "liby"))
>         (out (assoc-ref outputs "out")))
>     ...))
>
>
> This saves the usual boilerplate of '(#:key inputs outputs
> #:allow-other-keys)' and the subsequent `assoc-ref' uses.  One might say
> it's too specific because the phase procedures also receive non-alist
> arguments (although one can add an argument clause like '(foo ())' and
> it will work because no `assoc-ref' call will happen on `foo', though
> that's a hack), but I looked at all occurrences of "#:key" in
> gnu/packages/*.scm, and pure uses of `input' and/or `output' are
> extremely dominant, such that it should be fine to fall back to a plain
> `lambda*' in the remaining cases.

I'm not sure I like combining the alist destructuring part of this
macro.  IMO, 'phase-lambda' could just take care of the 'lambda*'
boilerplate, and maybe another macro ('alist-let'?) to reduce the
'assoc-ref' usage.

Implementation details aside, I think macros like these are very much
needed to reduce boilerplate and improve the readability of our
package recipes.

Thanks for sharing!

  reply	other threads:[~2015-02-25 17:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-25 16:42 Some macros to make package definitions prettier Taylan Ulrich Bayırlı/Kammer
2015-02-25 17:04 ` Thompson, David [this message]
2015-02-25 17:06   ` Thompson, David
2015-02-25 19:27     ` Taylan Ulrich Bayırlı/Kammer
2015-02-25 20:54   ` Taylan Ulrich Bayırlı/Kammer
2015-02-25 18:12 ` Andreas Enge
2015-02-25 19:46   ` Taylan Ulrich Bayırlı/Kammer
2015-02-25 20:24   ` Thompson, David
2015-02-25 23:32 ` Ludovic Courtès
2015-02-26 11:07   ` Taylan Ulrich Bayırlı/Kammer
2015-02-26 21:39     ` Ludovic Courtès
2015-03-03 16:49       ` Taylan Ulrich Bayırlı/Kammer
2015-03-03 20:44         ` Ludovic Courtès
2015-03-03 22:47           ` Taylan Ulrich Bayırlı/Kammer
2015-03-04  9:52             ` Ludovic Courtès
2015-02-26 21:41     ` Ludovic Courtès

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJ=RwfaVe-7Q5gV-487NeWD_TBhiWZA8jrUaeyhoo12yXZV8ZA@mail.gmail.com' \
    --to=dthompson2@worcester.edu \
    --cc=guix-devel@gnu.org \
    --cc=taylanbayirli@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 external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.