From: spacecadet <spacecadet@purge.sh>
To: guix-devel@gnu.org
Subject: Functional package interface
Date: Sun, 14 Apr 2024 07:02:25 +0000 [thread overview]
Message-ID: <0076d418-547a-1de2-6977-afe10d1a4222@purge.sh> (raw)
Hi guix
I started working on a "functional interface" to guix packages, as an
approach to globally modifying packages in an environment, similar to
nix overlays or the parameterization project.
Right now it's just a syntax rule that you can wrap a bunch of package
definitions in with some inputs in the style of a let.
(define-syntax define-public-package-set
(syntax-rules ()
((define-public-package-set pkgset
((input ...)
...)
(package-name package-def)
...)
(begin
(define-public pkgset
(lambda* (#:optional packages
#:key (input ...)
...
#:allow-other-keys)
(define package-name package-def)
...
(cond ((and packages (list? packages))
(map (lambda (package)
(cond ((eq? package 'package-name)
`(package-name . ,package-name))
...))
packages))
(packages
(cond ((eq? packages 'package-name)
package-name)
...))
(else
`((package-name . ,package-name)
...)))))
(set-procedure-property! pkgset 'package-set? #t)
(define-public package-name
(pkgset 'package-name))
...))))
Tried rewriting the guile packages module with it, link to the full
code further down but here's a snip:
;; existing module
(define-module (gnu packages guile)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (gnu packages)
...
;; package-set definition
(define-public-package-set gnu-packages-guile
((bash-minimal bash-minimal) ;; inputs
(gawk gawk)
(gmp gmp)
...
(url-fetch url-fetch))
;; packages
(guile-1.8
(package
(name "guile")
...
You end up with a public "gnu-packages-guile" function that takes
keyword-argument inputs like:
(gnu-packages-guile #:gawk (@ (gnu packages bioinformatics) bioawk))
;; => all the packages in gnu/packages/guile.scm, but every instance
;; of awk is replaced with bioawk
Then returns an alist of all the packages in the set with the inputs
appropriately "modified". For the keys in the alist I'm using the
variable names as symbols instead of the package names like in inputs,
because I feel that's more generally appropriate in the case where a
package-set might contain something that's not a package record.
Will probably write a helper function that spits out input pairs.
It can also take a single symbol or list of symbols as an optional
argument to produce either a single package or list of requested
packages:
(gnu-packages-guile 'guile-3.0)
;; => #<package guile@3.0.9 ... )
(gnu-packages-guile '(guile-2.2 guile2.2-json))
;; => (#<package guile@2.2.7 ... #<package guile2.2-json@4.7.3 ...)
Packages still get define-public'd, I assume in a way that would
preserve the existing working condition of the repository (although
there is one issue right now, more below) so this could hopefully turn
into a drop-in addition after some more work. I tried to make very few
changes necessary to the existing code to for the same reason.
Eventually, the goal is to be able to create an operating system
definition (or manifest, or anything else) using this, with a
hypothetical case like:
(use-package-modules base network etc.)
(define my-package-set
(packaget-set-append gnu-packages-base
gnu-packages-network ...))
(with-package-set
(my-package-set #:mesa something-else)
(operating-system
(...)))
Adapting more complicated package modules would probably be a task, but
I'm invested enough to keep working on it.
There are also a few problems with the current implementation, and I
think they all boil down to one issue:
If packages A and B are both in the same module, and B is an input to
A, I can't replace B.
There may be a solution, it might be as simple as providing a dummy
input for each package in the module, I don't know, open to ideas.
Another more minor problem is that it won't pull:
In ice-9/boot-9.scm:
222:29 19 (map1 _)
222:29 18 (map1 _)
222:29 17 (map1 _)
222:29 16 (map1 _)
222:29 15 (map1 _)
222:17 14 (map1 (((gnu packages guile))))
3327:17 13 (resolve-interface (gnu packages guile) #:select _ #:hid
In ice-9/threads.scm:
390:8 12 (_ _)
In ice-9/boot-9.scm:
3253:13 11 (_)
In ice-9/threads.scm:
390:8 10 (_ _)
In ice-9/boot-9.scm:
3544:20 9 (_)
2836:4 8 (save-module-excursion _)
3564:26 7 (_)
In unknown file:
6 (primitive-load-path "gnu/packages/guile" #<procedure 7f
In ice-9/eval.scm:
619:8 5 (_ #f)
626:19 4 (_ #<directory (gnu packages guile) 7fffec4d2dc0>)
619:8 3 (_ #(#(#<directory (gnu packages guile) 7fffec4d2dc0>) #
632:34 2 (_ #(#(#<directory (gnu packages guile) 7fffec4d2dc0>) #
223:20 1 (proc #(#(#<directory (gnu packages guile) 7fffec4d2dc0>
In unknown file:
0 (%resolve-variable (5 (gnu packages bash) bash-minimal .
ERROR: In procedure %resolve-variable:
error: bash-minimal: unbound variable
So I'm probably doing something bad.
Seems like the first variable in the "inputs" fails to resolve
somewhere? I don't even have a guess what's going wrong.
My code is available at https://gitlab.vulnix.sh/spacecadet/guix
Open to comments or ideas, and if anyone can give me a hand figuring out
the pull issue I'd be grateful.
- sc
next reply other threads:[~2024-04-14 13:35 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-14 7:02 spacecadet [this message]
2024-04-15 21:31 ` Functional package interface Nicolas Graves via Development of GNU Guix and the GNU System distribution.
2024-04-16 1:17 ` spacecadet
2024-04-16 8:26 ` Nicolas Graves via Development of GNU Guix and the GNU System distribution.
2024-04-16 15:31 ` spacecadet
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=0076d418-547a-1de2-6977-afe10d1a4222@purge.sh \
--to=spacecadet@purge.sh \
--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.