unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Functional package interface
@ 2024-04-14  7:02 spacecadet
  2024-04-15 21:31 ` Nicolas Graves via Development of GNU Guix and the GNU System distribution.
  0 siblings, 1 reply; 5+ messages in thread
From: spacecadet @ 2024-04-14  7:02 UTC (permalink / raw)
  To: guix-devel

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


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

end of thread, other threads:[~2024-04-16 18:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-14  7:02 Functional package interface spacecadet
2024-04-15 21:31 ` 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

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