unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Some macros to make package definitions prettier
@ 2015-02-25 16:42 Taylan Ulrich Bayırlı/Kammer
  2015-02-25 17:04 ` Thompson, David
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Taylan Ulrich Bayırlı/Kammer @ 2015-02-25 16:42 UTC (permalink / raw)
  To: guix-devel

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

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-03-04  9:53 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-25 16:42 Some macros to make package definitions prettier Taylan Ulrich Bayırlı/Kammer
2015-02-25 17:04 ` 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

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