[PATCH] packages: Add 'define-package' syntax.

  • Open
  • quality assurance status badge
Details
5 participants
  • Sarah Morgensen
  • Maxime Devos
  • Tobias Geerinckx-Rice
  • Taylan Kammer
  • zimoun
Owner
unassigned
Submitted by
Sarah Morgensen
Severity
wishlist
Merged with
S
S
Sarah Morgensen wrote on 3 Sep 2021 06:06
(address . guix-patches@gnu.org)
15d01b32313f5f2f291b120597719ae92bd26acd.1630639896.git.iskarian@mgsn.dev
* guix/packages.scm (define-package): New syntax.
* .dir-locals.el: Add indent rule for 'define-package'.
* etc/indent-code.el (main): Adjust package search regex accordingly.
* etc/snippets/text-mode/guix-commit-message-add-cl-package: Likewise.
* etc/snippets/text-mode/guix-commit-message-add-package: Likewise.
* etc/snippets/text-mode/guix-commit-message-rename-package: Likewise.
* etc/snippets/text-mode/guix-commit-message-update-package: Likewise.
---
Hello Guix,

This patch adds a shorthand for "(define-public name (package ...))":

(define-package my-favorite-package
(name "my-favorite-package")
...)

The purpose is primarily to save the horizontal indent, but IMO it looks
better, and is marginally more clear for newcomers. I think ideally we could
eventually transition to using this syntax as the primary syntax and only use
'define-public' when necessary.

There are some downsides... it's one more form to keep track of, and 'let'
forms can't easily be used with it.

Since it's a syntax rule, it doesn't cause packages to rebuild (tested). I've
also tested the indentation rules, indent-code.el, and the snippets.

This probably deserves a documentation addition, but I wasn't sure where to
add it without confusing newcomers. Suggestions welcome!

(If this is accepted, we'll also want to make a few changes to
emacs-guix/elisp/guix-devel.el, adding 'define-package' to
'guix-devel-keywords' and to 'guix-devel-scheme-indent' with level 1.)

What do you all think?
--
Sarah

.dir-locals.el | 1 +
etc/indent-code.el | 2 +-
etc/snippets/text-mode/guix-commit-message-add-cl-package | 2 +-
etc/snippets/text-mode/guix-commit-message-add-package | 2 +-
etc/snippets/text-mode/guix-commit-message-rename-package | 4 ++--
etc/snippets/text-mode/guix-commit-message-update-package | 2 +-
guix/packages.scm | 8 ++++++++
7 files changed, 15 insertions(+), 6 deletions(-)

Toggle diff (121 lines)
diff --git a/.dir-locals.el b/.dir-locals.el
index aaa48ab552..8141cf4fc2 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -71,6 +71,7 @@
(eval . (put 'with-writable-file 'scheme-indent-function 2))
(eval . (put 'package 'scheme-indent-function 0))
+ (eval . (put 'define-package 'scheme-indent-function 1))
(eval . (put 'package/inherit 'scheme-indent-function 1))
(eval . (put 'origin 'scheme-indent-function 0))
(eval . (put 'build-system 'scheme-indent-function 0))
diff --git a/etc/indent-code.el b/etc/indent-code.el
index bdea8ee8bf..b83659f2f9 100755
--- a/etc/indent-code.el
+++ b/etc/indent-code.el
@@ -94,7 +94,7 @@
;; Indent the definition of PACKAGE-NAME in FILE-NAME.
(find-file file-name)
(goto-char (point-min))
- (if (re-search-forward (concat "^(define\\(\\|-public\\) +"
+ (if (re-search-forward (concat "^(define\\(\\|-public\\|-package\\) +"
package-name)
nil t)
(let ((indent-tabs-mode nil))
diff --git a/etc/snippets/text-mode/guix-commit-message-add-cl-package b/etc/snippets/text-mode/guix-commit-message-add-cl-package
index e255736b05..eb0de677e7 100644
--- a/etc/snippets/text-mode/guix-commit-message-add-cl-package
+++ b/etc/snippets/text-mode/guix-commit-message-add-cl-package
@@ -7,7 +7,7 @@ gnu: Add ${1:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
(beginning-of-buffer)
- (when (search-forward "+(define-public " nil 'noerror)
+ (when (re-search-forward "+(define-\\(public\\|package\\) " nil 'noerror)
(replace-regexp-in-string
"^sbcl-" ""
(thing-at-point 'sexp 'no-properties))))`}.
diff --git a/etc/snippets/text-mode/guix-commit-message-add-package b/etc/snippets/text-mode/guix-commit-message-add-package
index 7cebd4023a..11aeceb129 100644
--- a/etc/snippets/text-mode/guix-commit-message-add-package
+++ b/etc/snippets/text-mode/guix-commit-message-add-package
@@ -7,7 +7,7 @@ gnu: Add ${1:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
(goto-char (point-min))
- (when (re-search-forward "\\+(define-public \\(\\S-+\\)" nil 'noerror)
+ (when (re-search-forward "\\+(define-\\(?:public\\|package\\) \\(\\S-+\\)" nil 'noerror)
(match-string-no-properties 1)))`}.
* `(car (magit-staged-files))` ($1): New variable.
\ No newline at end of file
diff --git a/etc/snippets/text-mode/guix-commit-message-rename-package b/etc/snippets/text-mode/guix-commit-message-rename-package
index 9695ca1b3d..2315443573 100644
--- a/etc/snippets/text-mode/guix-commit-message-rename-package
+++ b/etc/snippets/text-mode/guix-commit-message-rename-package
@@ -7,12 +7,12 @@ gnu: ${1:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
(beginning-of-buffer)
- (when (search-forward "-(define-public " nil 'noerror)
+ (when (re-search-forward "-(define-\\(public\\|package\\) " nil 'noerror)
(thing-at-point 'sexp 'no-properties)))`}: Rename package to ${2:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
(beginning-of-buffer)
- (when (search-forward "+(define-public " nil 'noerror)
+ (when (re-search-forward "+(define-\\(public\\|package\\) " nil 'noerror)
(thing-at-point 'sexp 'no-properties)))`}.
* `(car (magit-staged-files))` ($1): Define in terms of
diff --git a/etc/snippets/text-mode/guix-commit-message-update-package b/etc/snippets/text-mode/guix-commit-message-update-package
index f187419aa2..1d39e28b77 100644
--- a/etc/snippets/text-mode/guix-commit-message-update-package
+++ b/etc/snippets/text-mode/guix-commit-message-update-package
@@ -8,7 +8,7 @@ gnu: ${1:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
(goto-char (point-min))
- (when (re-search-forward "(define-public \\(\\S-+\\)" nil 'noerror)
+ (when (re-search-forward "(define-\\(?:public\\|package\\) \\(\\S-+\\)" nil 'noerror)
(match-string-no-properties 1)))`}: Update to ${2:`(with-temp-buffer
(magit-git-wash #'magit-diff-wash-diffs
"diff" "--staged")
diff --git a/guix/packages.scm b/guix/packages.scm
index c825f427d8..ecd0b7e47d 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -6,6 +6,7 @@
;;; Copyright © 2017, 2019, 2020 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2019 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
+;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -99,6 +100,7 @@ (define-module (guix packages)
package-supported-systems
package-properties
package-location
+ define-package
hidden-package
hidden-package?
package-superseded
@@ -425,6 +427,12 @@ (define-record-type* <package>
package)
16)))))
+(define-syntax-rule (define-package name body ...)
+ "Equivalent to (define-public name (package body ...))."
+ (define-public name
+ (package
+ body ...)))
+
(define-syntax-rule (package/inherit p overrides ...)
"Like (package (inherit P) OVERRIDES ...), except that the same
transformation is done to the package P's replacement, if any. P must be a bare

base-commit: 95c29d2746943733cbe8df7013854d45bb0df413
--
2.31.1
Z
Z
zimoun wrote on 3 Sep 2021 07:41
86h7f21aip.fsf@gmail.com
Hi Sarah,

On Thu, 02 Sep 2021 at 21:06, Sarah Morgensen <iskarian@mgsn.dev> wrote:

Toggle quote (9 lines)
> (define-package my-favorite-package
> (name "my-favorite-package")
> ...)
>
> The purpose is primarily to save the horizontal indent, but IMO it looks
> better, and is marginally more clear for newcomers. I think ideally we could
> eventually transition to using this syntax as the primary syntax and only use
> 'define-public' when necessary.

On one hand, I think it is a good idea; especially for newcomers. On
the other hand, it will break ’git-blame’, isn’t it?

Therefore, I am not convinced such change is worth for ’gnu/packages/’.
Instead it seems worth only for teaching custom packages. Explaining to
people in my labs, they are often confused between ’define’ and
’define-public’. But then, there is two “styles” and people could be
more confused.

Well, my feelings are mixed. Thanks for opening the discussion. :-)


Cheers,
simon
S
S
Sarah Morgensen wrote on 3 Sep 2021 23:56
(name . zimoun)(address . zimon.toutoune@gmail.com)(address . 50349@debbugs.gnu.org)
86k0jxxqzv.fsf@mgsn.dev
Hi,

zimoun <zimon.toutoune@gmail.com> writes:

Toggle quote (16 lines)
> Hi Sarah,
>
> On Thu, 02 Sep 2021 at 21:06, Sarah Morgensen <iskarian@mgsn.dev> wrote:
>
>> (define-package my-favorite-package
>> (name "my-favorite-package")
>> ...)
>>
>> The purpose is primarily to save the horizontal indent, but IMO it looks
>> better, and is marginally more clear for newcomers. I think ideally we could
>> eventually transition to using this syntax as the primary syntax and only use
>> 'define-public' when necessary.
>
> On one hand, I think it is a good idea; especially for newcomers. On
> the other hand, it will break ’git-blame’, isn’t it?

Yes, there would be a one-time discontinuity. Reformats like this can
be ignored with the `--ignore-ref' option, or with a file and a config
option:

.git-blame-ignore-revs:
Toggle snippet (4 lines)
# Convert 'define-public' forms to 'define-package' forms
15d01b32313f5f2f291b120597719ae92bd26acd

.git/config:
Toggle snippet (4 lines)
[blame]
ignoreRevsFile = .git-blame-ignore-revs

We could include the latter in e.g. a `.gitconfig' file committed to the
repo, but in order to use config settings from the file, users would
have to first run

git config --local include.path ../.gitconfig

Thankfully, this only has to be done once per clone. If you really
wanted to make sure it got run, I suppose you could add it to a 'make'
target.

--
Sarah
M
M
Maxime Devos wrote on 4 Sep 2021 10:42
757b7543b931335c3725264edfbc79c012aa10fc.camel@telenet.be
Sarah Morgensen schreef op do 02-09-2021 om 21:06 [-0700]:
Toggle quote (8 lines)
> Hello Guix,
>
> This patch adds a shorthand for "(define-public name (package ...))":
>
> (define-package my-favorite-package
> (name "my-favorite-package")
> ...)

This could be even shorter in the special case that the variable name
and package name are the same (modulo types):

(define-package "my-favorite-package"
(version ...)
...)

'datum->syntax' and 'string->symbol' can be used to turn "my-favorite-package"
into an identifier.

A 'define-unexported-package' might be required in some places.

Toggle quote (14 lines)
> The purpose is primarily to save the horizontal indent, but IMO it looks
> better, and is marginally more clear for newcomers. I think ideally we could
> eventually transition to using this syntax as the primary syntax and only use
> 'define-public' when necessary.
>
> There are some downsides... it's one more form to keep track of, and 'let'
> forms can't easily be used with it.
>
> Since it's a syntax rule, it doesn't cause packages to rebuild (tested). I've
> also tested the indentation rules, indent-code.el, and the snippets.
>
> This probably deserves a documentation addition, but I wasn't sure where to
> add it without confusing newcomers. Suggestions welcome!

‘Defining Packages’ would be a good place I think.

Toggle quote (2 lines)
> What do you all think?

This looks nice to me. IIUC, the define-package is intended to be clearer
to newcomers, so you might want to ask for feedback on the new syntax on
help-guix@gnu.org.

Greetings,
Maxime.
-----BEGIN PGP SIGNATURE-----

iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYTMxWhccbWF4aW1lZGV2
b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7sKYAP9w+XTSzxWZhmUnqm6b2HrJBnke
pSydXdNSCWBe9TK8qgD/VHtoAU9jniP90C59rVH8baidLxFnPW7dJ7wctbyXeg4=
=+pGj
-----END PGP SIGNATURE-----


T
T
Tobias Geerinckx-Rice wrote on 4 Sep 2021 12:19
(no subject)
(name . GNU Debbugs)(address . control@debbugs.gnu.org)
871r64bq0t.fsf@nckx
severity 50349 wishlist
reassign 50349 guix
merge 15284 50349
T
T
Tobias Geerinckx-Rice wrote on 4 Sep 2021 12:09
Re: [bug#50349] [PATCH] packages: Add 'define-package' syntax.
(name . Maxime Devos)(address . maximedevos@telenet.be)
87y28caazy.fsf@nckx
All,

To keep a link with previous ‘define-package’ discussion, I've
merged this bug with #15284. It was never resolved IMO and things
have changed since 2013 with the label-less input style.

Maxime Devos ???
Toggle quote (8 lines)
> This could be even shorter in the special case that the variable
> name
> and package name are the same (modulo types):
>
> (define-package "my-favorite-package"
> (version ...)
> ...)

(define-anything STRING ...) is just too weird to ack. Are there
any package names that aren't currently valid symbols? Is there a
good reason for them?

Kind regards,

T G-R
-----BEGIN PGP SIGNATURE-----

iIMEARYKACsWIQT12iAyS4c9C3o4dnINsP+IT1VteQUCYTNK0Q0cbWVAdG9iaWFz
LmdyAAoJEA2w/4hPVW15/+AA/2KDGdPwCf27KyEllAKu87PGffRIUv4hutkxnCW9
i5gSAQCuuf5NC9Fxhj/d+lejfiRjfYNNUPJaqrD/2zrR2co2CA==
=NCTi
-----END PGP SIGNATURE-----

T
T
Taylan Kammer wrote on 4 Sep 2021 16:29
Re: bug#50349: [PATCH] packages: Add 'define-package' syntax.
95c92fc5-1fcf-b347-370e-d1943f22c2c3@gmail.com
On 04.09.2021 12:09, Tobias Geerinckx-Rice via Bug reports for GNU Guix wrote:
Toggle quote (18 lines)
> All,
>
> To keep a link with previous ‘define-package’ discussion, I've merged this bug with #15284.  It was never resolved IMO and things have changed since 2013 with the label-less input style.
>
> Maxime Devos ???
>> This could be even shorter in the special case that the variable name
>> and package name are the same (modulo types):
>>
>> (define-package "my-favorite-package"
>>   (version ...)
>>   ...)
>
> (define-anything STRING ...) is just too weird to ack.  Are there any package names that aren't currently valid symbols?  Is there a good reason for them?
>
> Kind regards,
>
> T G-R

To me the most obvious thing to do seems

(define-package foo ...) ;no explicit name needed

to bind the variable 'foo' and use symbol->string for the name of the
package, with the possibility to override the name like

(define-package foo (name "foobar") ...)

which would bind the variable 'foo' to a package named "foobar".

Here's a syntax-case definition:

(define-syntax define-package
(lambda (stx)
(syntax-case stx ()
((_ <name>
(<field> <value> ...)
...)
(if (memq 'name (map syntax->datum #'(<field> ...)))
#'(define-public <name>
(package
(<field> <value> ...)
...))
#`(define-public <name>
(package
(name #,(symbol->string (syntax->datum #'<name>)))
(<field> <value> ...)
...)))))))

--
Taylan
T
T
Tobias Geerinckx-Rice wrote on 4 Sep 2021 16:44
(name . Taylan Kammer)(address . taylan.kammer@gmail.com)
87bl58wfk7.fsf@nckx
Taylan Kammer ???
Toggle quote (12 lines)
> To me the most obvious thing to do seems
>
> (define-package foo ...) ;no explicit name needed
>
> to bind the variable 'foo' and use symbol->string for the name
> of the
> package, with the possibility to override the name like
>
> (define-package foo (name "foobar") ...)
>
> which would bind the variable 'foo' to a package named "foobar".

Right, that's what I meant, and it's how I read bug #15284, and it
looks remarkably like the form I use in my personal channels (and
I'm sure I'm not the first! :-).

You're much better at the language/implementation side of things
than I am, Taylan. Would this negatively affect performance
(including ‘guix pull’ compilation)?

Kind regards,

T G-R
-----BEGIN PGP SIGNATURE-----

iIMEARYKACsWIQT12iAyS4c9C3o4dnINsP+IT1VteQUCYTOKOQ0cbWVAdG9iaWFz
LmdyAAoJEA2w/4hPVW153NAA/REHwe3zGjottM6pjEg6RnF9/Fb6r7m4Ruv8liXc
rkmIAQDOwXDxmTgkvU9XDyiLCd9i4BZPb4Qpq8v40uevQpDaBw==
=gupr
-----END PGP SIGNATURE-----

T
T
Taylan Kammer wrote on 4 Sep 2021 19:23
(name . Tobias Geerinckx-Rice)(address . me@tobias.gr)
a93161dd-4425-f722-fa43-273ff9561916@gmail.com
On 04.09.2021 16:44, Tobias Geerinckx-Rice wrote:
Toggle quote (20 lines)
> Taylan Kammer ???
>> To me the most obvious thing to do seems
>>
>>   (define-package foo ...)  ;no explicit name needed
>>
>> to bind the variable 'foo' and use symbol->string for the name of the
>> package, with the possibility to override the name like
>>
>>   (define-package foo (name "foobar") ...)
>>
>> which would bind the variable 'foo' to a package named "foobar".
>
> Right, that's what I meant, and it's how I read bug #15284, and it looks remarkably like the form I use in my personal channels (and I'm sure I'm not the first! :-).
>
> You're much better at the language/implementation side of things than I am, Taylan.  Would this negatively affect performance (including ‘guix pull’ compilation)?
>
> Kind regards,
>
> T G-R

I'm flattered, but don't really know the answer, so I decided to attempt
some sort of benchmark. :-P

test1.scm uses the syntax-case macro, test2.scm just define-public.

I don't actually import the Guix modules, so the (package ...) form isn't
macro-expanded, regardless of whether it's used directly or results from
expanding define-package.

This way, the impact of define-package should dominate the time difference.

The results are... interesting. I started out with 256 definitions in the
files, and the define-package one would take about 4.2s to compile while
the regular one about 3.9s. There was some jitter in the results though
after running it several times so I thought, let's increase the number of
packages to reduce noise.

With 512 packages, the one using regular define-public takes a whole
minute to compile, whereas the define-package one just ~14 seconds!

So no idea what's going on there, and how the use of this macro in the
actual (gnu packages ...) modules would affect performance. :-)

--
Taylan
Attachment: test1.scm
Attachment: test2.scm
S
S
Sarah Morgensen wrote on 4 Sep 2021 20:53
(name . Taylan Kammer)(address . taylan.kammer@gmail.com)
86v93gjhps.fsf@mgsn.dev
Hi Taylan,

Taylan Kammer <taylan.kammer@gmail.com> writes:

Toggle quote (21 lines)
> On 04.09.2021 16:44, Tobias Geerinckx-Rice wrote:
>> Taylan Kammer ???
>>> To me the most obvious thing to do seems
>>>
>>>   (define-package foo ...)  ;no explicit name needed
>>>
>>> to bind the variable 'foo' and use symbol->string for the name of the
>>> package, with the possibility to override the name like
>>>
>>>   (define-package foo (name "foobar") ...)
>>>
>>> which would bind the variable 'foo' to a package named "foobar".
>>
>> Right, that's what I meant, and it's how I read bug #15284, and it looks remarkably like the form I use in my personal channels (and I'm sure I'm not the first! :-).
>>
>> You're much better at the language/implementation side of things than I am, Taylan.  Would this negatively affect performance (including ‘guix pull’ compilation)?
>>
>> Kind regards,
>>
>> T G-R

I agree; if we added that magic, that's definitely how it should be.

Toggle quote (24 lines)
>
> I'm flattered, but don't really know the answer, so I decided to attempt
> some sort of benchmark. :-P
>
> test1.scm uses the syntax-case macro, test2.scm just define-public.
>
> I don't actually import the Guix modules, so the (package ...) form isn't
> macro-expanded, regardless of whether it's used directly or results from
> expanding define-package.
>
> This way, the impact of define-package should dominate the time difference.
>
> The results are... interesting. I started out with 256 definitions in the
> files, and the define-package one would take about 4.2s to compile while
> the regular one about 3.9s. There was some jitter in the results though
> after running it several times so I thought, let's increase the number of
> packages to reduce noise.
>
> With 512 packages, the one using regular define-public takes a whole
> minute to compile, whereas the define-package one just ~14 seconds!
>
> So no idea what's going on there, and how the use of this macro in the
> actual (gnu packages ...) modules would affect performance. :-)

Thanks for running some benchmarks. Were both those latter runs with a
warm cache?

If so, is it possible that due to a compilation optimization, many of
the global symbol lookups only happen once with the define-package
macro?

If you were really interested, I suppose you could test with compilation
optimization off, but I'd be more interested in the performance impact
with (guix packages) imported.

--
Sarah
T
T
Taylan Kammer wrote on 4 Sep 2021 23:01
(name . Sarah Morgensen)(address . iskarian@mgsn.dev)
5e71792b-ac49-65db-13f0-e06fbcbdec1f@gmail.com
On 04.09.2021 20:53, Sarah Morgensen wrote:

Toggle quote (9 lines)
>
> If you were really interested, I suppose you could test with compilation
> optimization off, but I'd be more interested in the performance impact
> with (guix packages) imported.
>
> --
> Sarah
>

Good questions. Let's see. Caching shouldn't be an issue by the way since
I always time a command several times and make sure it's consistent.

With -O0 and -O1, both files take a negligible amount of time to compile,
approximately 0.25s and 0.3s. A difference of 0.5s for 512 packages means
about 0.001s per package, which at 100K packages would be 100s.

That's without importing (guix packages) though. When I import it, then
at -O0 and -O1 (I think these are equivalent), the define-packages one
takes about 3.8s and the regular one about 3.5s. So the difference has
actually shrunk down to about 0.3s now.

With (guix packages) and no special optimization flag, the define-packages
one takes about 26s, and the regular one still shows the strange behavior
where the time explodes to over a minute.

If I remember correctly though, Guix uses -O1 to compile packages anyway.

So all in all I *think* we can say that the macro induces no important
performance hit. (And could for some reason significantly improve it if
we compile a large chunk of packages on -O2...)

One thing I should note though is that I'm using a top-of-the-line typical
consumer CPU (Ryzen 9 3900X) so on an older machine, or a CPU brand that
puts more value into freedom and security than performance, the results
may be different. I still doubt that the impact would be big.

Attached are new scm files since I had to add some fields to make sure
the package macro from (guix packages) doesn't abort the compilation.

--
Taylan
Attachment: test1.scm
Attachment: test2.scm
S
S
Sarah Morgensen wrote on 5 Sep 2021 01:17
Re: [bug#50349] [PATCH] packages: Add 'define-package' syntax.
(name . Maxime Devos)(address . maximedevos@telenet.be)
86sfykj5hf.fsf@mgsn.dev
Hi all,

Thanks for your comments. I'm replying specifically to this message but
these thoughts apply to the issue as a whole.

Maxime Devos <maximedevos@telenet.be> writes:

Toggle quote (21 lines)
> Sarah Morgensen schreef op do 02-09-2021 om 21:06 [-0700]:
>> Hello Guix,
>>
>> This patch adds a shorthand for "(define-public name (package ...))":
>>
>> (define-package my-favorite-package
>> (name "my-favorite-package")
>> ...)
>
> This could be even shorter in the special case that the variable name
> and package name are the same (modulo types):
>
> (define-package "my-favorite-package"
> (version ...)
> ...)
>
> 'datum->syntax' and 'string->symbol' can be used to turn "my-favorite-package"
> into an identifier.
>
> A 'define-unexported-package' might be required in some places.

Sure, or perhaps 'define-private-package'. I think this is pretty rare,
though? And often in those cases other forms are used which may be
incompatible with the macro, so they'll have to use the original syntax
anyway. Either way is fine IMO.

There are also about 150 packages which use 'package/inherit'. Should
we introduce special syntax for them? What about 'hidden-package'
(about 60 packages)? (And 11 use both!)

About the only form I can think of that wouldn't break the composability
of these kinds of things is something like

(define-package* hello (hidden)
(name "hello")
...)

or

(define-package* hello (hidden inherit-replacements)
(name "hello")
...)

Where 'hidden', 'inherit-replacements', and so on would be procs to
apply (in the same order as compose?) that each transform the package.
Or we could even have them transform the package syntax directly.

But that's even more magic; it would take a fair amount of work, and be
hard to get right. (How well would it hold up to syntax errors?)

Toggle quote (6 lines)
>
> [...]
> This looks nice to me. IIUC, the define-package is intended to be clearer
> to newcomers, so you might want to ask for feedback on the new syntax on
> help-guix@gnu.org.

Thanks for the suggestion, I definitely will.

With an eye toward newcomers, I think one "gotcha" of the "optional
name" version is inheritance. If I have

(define-package rust-actix-0.10
(name "rust-actix")
...)

and then I write

(define-package rust-actix-0.20
(inherit rust-actix-0.10)
...)

At best, I would be unsure about whether this package would inherit the
name. At worst, I would assume the name is inherited, and I would be
wrong. If I have to write the name, there is no ambiguity.

For the automatic naming (because of gotchas like that), and for
possible extensions discussed above, I think right now I'm tempted to
agree with Ludo's comment when this last came around (thanks to Tobias
for pointing out the conversation)[0]:

ludo@gnu.org (Ludovic Courtès) writes:

Toggle quote (3 lines)
> However, I prefer treating packages just like any other Scheme object,
> and to avoid introducing “magic” with macros like this.

I could be convinced with an elegant enough implementation though! ;)

--
Sarah
?