From: taylanbayirli@gmail.com (Taylan Ulrich Bayırlı/Kammer)
To: guix-devel@gnu.org
Subject: Some macros to make package definitions prettier
Date: Wed, 25 Feb 2015 17:42:23 +0100 [thread overview]
Message-ID: <874mqa6iz4.fsf@taylan.uni.cx> (raw)
I would propose the following macros to make package definitions
somewhat nicer:
;;; 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...
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.
WDYT?
Taylan
next reply other threads:[~2015-02-25 16:42 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-25 16:42 Taylan Ulrich Bayırlı/Kammer [this message]
2015-02-25 17:04 ` Some macros to make package definitions prettier Thompson, David
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=874mqa6iz4.fsf@taylan.uni.cx \
--to=taylanbayirli@gmail.com \
--cc=guix-devel@gnu.org \
/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.