[PATCH] doc: Propose new cookbook section for reproducible research.

  • Open
  • quality assurance status badge
Details
4 participants
  • kyle
  • Ludovic Courtès
  • Ludovic Courtès
  • Simon Tournier
Owner
unassigned
Submitted by
kyle
Severity
normal
K
(address . guix-patches@gnu.org)(name . Kyle Andrews)(address . kyle@posteo.net)
3ffea5b37541a6f3409299f3e8e6200bc1c9aef6.1677043049.git.kyle@posteo.net
From: Kyle Andrews <kyle@posteo.net>

The intent was to cover the most common cases where R and python using
researchers could rapidly achieve the benefits of reproducibility.
---
doc/guix-cookbook.texi | 174 +++++++++++++++++++++++++++++++++++
guix/build-system/python.scm | 1 +
2 files changed, 175 insertions(+)

Toggle diff (209 lines)
diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi
index b9fb916f4a..8a10bcbec7 100644
--- a/doc/guix-cookbook.texi
+++ b/doc/guix-cookbook.texi
@@ -114,6 +114,7 @@ Top
Environment management
+* Reproducible Research in Practice:: Write manifests to create reproducible environments.
* Guix environment via direnv:: Setup Guix environment with direnv
Installing Guix on a Cluster
@@ -3538,9 +3539,182 @@ Environment management
demonstrate such utilities.
@menu
+* Reproducible Research in Practice:: Write manifests to create reproducible environments
* Guix environment via direnv:: Setup Guix environment with direnv
@end menu
+@node Reproducible Research in Practice
+@section Common scientific software environments
+
+Many researchers write applied scientific software supported by a
+mixture of more generic tools developed by teams written within the R
+and Python ecosystems and supporting shell utilities. Even researchers
+who predominantly stick to using just R or just python often have to use
+both R and python at the same time when collaborating with others. This
+tutorial covers strategies for creating manifests to handle such
+situations.
+
+Widely used R packages are hosted on CRAN, which employs a strict test
+suite backed by continuous integration infrastructure for the latest R
+version. A positive result of this rigid discipline is that most R
+packages from the same period of time will interoperate well together
+when used with a particular R version. This means there is a clear
+low-complexity target for achieving a reproducible environment.
+
+Writing a manifest for packaging R code alone requires only minimal
+knowledge of the Guix infrastructure. This stub should work for most
+cases involving the R packages already in Guix.
+
+@example
+(use-modules
+ (gnu packages cran)
+ (gnu packages statistics))
+
+(packages->manifest
+ (list r r-tidyverse))
+
+R packages are defined predominantly inside of gnu/packages/cran.scm and
+gnu/packages/statistics.scm files under a guix source repository.
+
+This manifest can be run with the basic guix shell command:
+
+@example
+guix shell --manifest=manifest.scm --container
+@end example
+
+Please remember at the end to pin your channels so that others in the
+future know how to recover your exact Guix environment.
+
+@example
+guix describe --format=channels > channels.scm
+@end example
+
+This can be done with Guix time machine:
+
+@example
+guix time-machine --channels=channels.scm \
+ -- guix shell --manifest=manifest.scm --container
+@end example
+
+In contrast, the python scientific ecosystem is far less
+standardized. There is no effort made to integrate all python packages
+together. While there is a latest python version, it is less often less
+dominantly used for various reasons such as the fact that python tends
+to be employed with much larger teams than R is. This makes packaging up
+reproducible python environments much more difficult. Adding R together
+with python as a mixture complicates things still further. However, we
+have to be mindful of the goals of reproducible research.
+
+If reproducibility becomes an end in itself and not a catlyst towards
+faster discovery, then Guix will be a non-starter for scientists. Their
+goal is to develop useful understanding about particular aspects of the
+world.
+
+Thankfully, three common scenarios cover the vast majority of
+needs. These are:
+
+@itemize
+@item
+combining standard package definitions with custom package definitions
+@item
+combining package definitions from the current revision with other revisions
+@item
+combining package variants which need a modified build-system
+@end itemize
+
+In the rest of the tutorial we develop a manifest which tackles all
+three of these common issues. The hope is that if you see the hardest
+possible common situation as being readily solvable without writing
+thousands of lines of code, researchers will clearly see it as worth the
+effort which will not pose a significant detour from the main line of
+their research.
+
+@example
+(use-modules
+ (guix packages)
+ (guix download)
+ (guix licenses)
+ (guix profiles)
+ (gnu packages)
+ (gnu packages cran)
+ (guix inferior)
+ (guix channels)
+ (guix build-system python))
+
+;; guix import pypi APTED
+(define python-apted
+ (package
+ (name "python-apted")
+ (version "1.0.3")
+ (source (origin
+ (method url-fetch)
+ (uri (pypi-uri "apted" version))
+ (sha256
+ (base32
+ "1sawf6s5c64fgnliwy5w5yxliq2fc215m6alisl7yiflwa0m3ymy"))))
+ (build-system python-build-system)
+ (home-page "https://github.com/JoaoFelipe/apted")
+ (synopsis "APTED algorithm for the Tree Edit Distance")
+ (description "APTED algorithm for the Tree Edit Distance")
+ (license expat)))
+
+(define last-guix-with-python-3.6
+ (list
+ (channel
+ (name 'guix)
+ (url "https://git.savannah.gnu.org/git/guix.git")
+ (commit
+ "d66146073def03d1a3d61607bc6b77997284904b"))))
+
+(define connection-to-last-guix-with-python-3.6
+ (inferior-for-channels last-guix-with-python-3.6))
+
+(define first car)
+
+(define python-3.6
+ (first
+ (lookup-inferior-packages
+ connection-to-last-guix-with-python-3.6 "python")))
+
+(define python3.6-numpy
+ (first
+ (lookup-inferior-packages
+ connection-to-last-guix-with-python-3.6 "python-numpy")))
+
+(define included-packages
+ (list r r-reticulate))
+
+(define inferior-packages
+ (list python-3.6 python3.6-numpy))
+
+(define package-with-python-3.6
+ (package-with-explicit-python python-3.6
+ "python-" "python3.6-" 'python3-variant))
+
+(define custom-variant-packages
+ (list (package-with-python-3.6 python-apted)))
+
+(concatenate-manifest
+ (map packages->manifest
+ (list
+ included-packages
+ inferior-packages
+ custom-variant-packages)))
+@end example
+
+This should produce a profile with the latest R and an older python
+3.6. These should be able to interoperate with code like:
+
+@example
+library(reticulate)
+use_python("python")
+apted = import("apted")
+t1 = '{a{b}{c}}'
+t2 = '{a{b{d}}}'
+metric = apted$APTED(t1, t2)
+distance = metric$compute_edit_distance()
+@end example
+
@node Guix environment via direnv
@section Guix environment via direnv
diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm
index c8f04b2298..d4aaab906d 100644
--- a/guix/build-system/python.scm
+++ b/guix/build-system/python.scm
@@ -36,6 +36,7 @@ (define-module (guix build-system python)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (%python-build-system-modules
+ package-with-explicit-python
package-with-python2
strip-python2-variant
default-python
--
2.37.2
S
S
Simon Tournier wrote on 22 Feb 2023 11:52
(name . Kyle Andrews)(address . kyle@posteo.net)
86h6vet1j8.fsf@gmail.com
Hi,

Cool! Nice! My suggestions could be dropped, I mean they are just
suggestions. :-)


On Wed, 22 Feb 2023 at 05:17, kyle <kyle@posteo.net> wrote:

Toggle quote (12 lines)
> +Writing a manifest for packaging R code alone requires only minimal
> +knowledge of the Guix infrastructure. This stub should work for most
> +cases involving the R packages already in Guix.
> +
> +@example
> +(use-modules
> + (gnu packages cran)
> + (gnu packages statistics))
> +
> +(packages->manifest
> + (list r r-tidyverse))

Missing @end example, no?

Toggle quote (3 lines)
> +R packages are defined predominantly inside of gnu/packages/cran.scm and
> +gnu/packages/statistics.scm files under a guix source repository.

When presenting Guix, usually I start with:

guix shell r r-tidyverse

then

guix shell r r-tidyverse --export-manifest

Toggle snippet (8 lines)
;; What follows is a "manifest" equivalent to the command line you gave.
;; You can store it in a file that you may then pass to any 'guix' command
;; that accepts a '--manifest' (or '-m') option.

(specifications->manifest
(list "r" "r-tidyverse"))

which demystifies the “manifest”. Then, I go via:

guix show r

to point the location and explains why (gnu packages statistics). So
then, people connect the dots between the command line invocation and
the manifest:

Toggle snippet (8 lines)
(use-modules
(gnu packages cran)
(gnu packages statistics))

(packages->manifest
(list r r-tidyverse))

Based on that, I introduce modules and why (guix licenses) for
examples.

Toggle quote (6 lines)
> +This manifest can be run with the basic guix shell command:
> +
> +@example
> +guix shell --manifest=manifest.scm --container
> +@end example

Do you need ’container’? If yes, I should set the scenario before: We
want to run X and Y inside a container, because we want to be sure that
we described all we need to run the analysis. Well, something like
that.

Toggle quote (14 lines)
> +Please remember at the end to pin your channels so that others in the
> +future know how to recover your exact Guix environment.
> +
> +@example
> +guix describe --format=channels > channels.scm
> +@end example
> +
> +This can be done with Guix time machine:
> +
> +@example
> +guix time-machine --channels=channels.scm \
> + -- guix shell --manifest=manifest.scm --container
> +@end example

No, the correct is:

guix time-machine --channels=channels.scm \
-- shell --manifest=manifest.scm --container

without the extra ’guix’.


Toggle quote (14 lines)
> +In contrast, the python scientific ecosystem is far less
> +standardized. There is no effort made to integrate all python packages
> +together. While there is a latest python version, it is less often less
> +dominantly used for various reasons such as the fact that python tends
> +to be employed with much larger teams than R is. This makes packaging up
> +reproducible python environments much more difficult. Adding R together
> +with python as a mixture complicates things still further. However, we
> +have to be mindful of the goals of reproducible research.
> +
> +If reproducibility becomes an end in itself and not a catlyst towards
> +faster discovery, then Guix will be a non-starter for scientists. Their
> +goal is to develop useful understanding about particular aspects of the
> +world.

Cool paragraph!

Toggle quote (26 lines)
> +Thankfully, three common scenarios cover the vast majority of
> +needs. These are:
> +
> +@itemize
> +@item
> +combining standard package definitions with custom package definitions
> +@item
> +combining package definitions from the current revision with other revisions
> +@item
> +combining package variants which need a modified build-system
> +@end itemize
> +
> +In the rest of the tutorial we develop a manifest which tackles all
> +three of these common issues. The hope is that if you see the hardest
> +possible common situation as being readily solvable without writing
> +thousands of lines of code, researchers will clearly see it as worth the
> +effort which will not pose a significant detour from the main line of
> +their research.
> +
> +@example
> +(use-modules
> + (guix packages)
> + (guix download)
> + (guix licenses)
> + (guix profiles)

Before jumping to that, I would add a paragraph after the first manifest
explaining that other modules can be used, for instance the module (guix
licenses) provides all the licenses known by Guix. Well, something like
that.

Toggle quote (8 lines)
> + (gnu packages)
> + (gnu packages cran)
> + (guix inferior)
> + (guix channels)
> + (guix build-system python))
> +
> +;; guix import pypi APTED

I would add a sentence before this manifest point to the documentation
of “guix import” and explaining with one sentence that it allows to
extract information from PyPI and generates a recipe for Guix.

Toggle quote (27 lines)
> +(define python-apted
> + (package
> + (name "python-apted")
> + (version "1.0.3")
> + (source (origin
> + (method url-fetch)
> + (uri (pypi-uri "apted" version))
> + (sha256
> + (base32
> + "1sawf6s5c64fgnliwy5w5yxliq2fc215m6alisl7yiflwa0m3ymy"))))
> + (build-system python-build-system)
> + (home-page "https://github.com/JoaoFelipe/apted")
> + (synopsis "APTED algorithm for the Tree Edit Distance")
> + (description "APTED algorithm for the Tree Edit Distance")
> + (license expat)))
> +
> +(define last-guix-with-python-3.6
> + (list
> + (channel
> + (name 'guix)
> + (url "https://git.savannah.gnu.org/git/guix.git")
> + (commit
> + "d66146073def03d1a3d61607bc6b77997284904b"))))
> +
> +(define connection-to-last-guix-with-python-3.6
> + (inferior-for-channels last-guix-with-python-3.6))

Why do you need an inferior? Is it to avoid the “guix time-machine”?
Ah, no the answer below. :-)

Toggle quote (32 lines)
> +(define first car)
> +
> +(define python-3.6
> + (first
> + (lookup-inferior-packages
> + connection-to-last-guix-with-python-3.6 "python")))
> +
> +(define python3.6-numpy
> + (first
> + (lookup-inferior-packages
> + connection-to-last-guix-with-python-3.6 "python-numpy")))
> +
> +(define included-packages
> + (list r r-reticulate))
> +
> +(define inferior-packages
> + (list python-3.6 python3.6-numpy))
> +
> +(define package-with-python-3.6
> + (package-with-explicit-python python-3.6
> + "python-" "python3.6-" 'python3-variant))
> +
> +(define custom-variant-packages
> + (list (package-with-python-3.6 python-apted)))
> +
> +(concatenate-manifest
> + (map packages->manifest
> + (list
> + included-packages
> + inferior-packages
> + custom-variant-packages)))

While this is cool, I would not recommend it as some practise. This
kind of mix can lead to various annoyances, IMHO. First, it will scale
poorly if you add more inferiors. Second, the probability that the
resulting computational environment works well decreases.

Anyway, the example is cool! :-)

Toggle quote (15 lines)
> +@end example
> +
> +This should produce a profile with the latest R and an older python
> +3.6. These should be able to interoperate with code like:
> +
> +@example
> +library(reticulate)
> +use_python("python")
> +apted = import("apted")
> +t1 = '{a{b}{c}}'
> +t2 = '{a{b{d}}}'
> +metric = apted$APTED(t1, t2)
> +distance = metric$compute_edit_distance()
> +@end example

This example is cool!


Toggle quote (13 lines)
> diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm
> index c8f04b2298..d4aaab906d 100644
> --- a/guix/build-system/python.scm
> +++ b/guix/build-system/python.scm
> @@ -36,6 +36,7 @@ (define-module (guix build-system python)
> #:use-module (srfi srfi-1)
> #:use-module (srfi srfi-26)
> #:export (%python-build-system-modules
> + package-with-explicit-python
> package-with-python2
> strip-python2-variant
> default-python

Maybe this could be a separated patch.


Cheers,
simon
K
K
Kyle Andrews wrote on 23 Feb 2023 00:21
(name . Simon Tournier)(address . zimon.toutoune@gmail.com)(address . 61701@debbugs.gnu.org)
87a615wa7b.fsf@posteo.net
Simon Tournier <zimon.toutoune@gmail.com> writes:

Toggle quote (67 lines)
>> +(define python-apted
>> + (package
>> + (name "python-apted")
>> + (version "1.0.3")
>> + (source (origin
>> + (method url-fetch)
>> + (uri (pypi-uri "apted" version))
>> + (sha256
>> + (base32
>> + "1sawf6s5c64fgnliwy5w5yxliq2fc215m6alisl7yiflwa0m3ymy"))))
>> + (build-system python-build-system)
>> + (home-page "https://github.com/JoaoFelipe/apted")
>> + (synopsis "APTED algorithm for the Tree Edit Distance")
>> + (description "APTED algorithm for the Tree Edit Distance")
>> + (license expat)))
>> +
>> +(define last-guix-with-python-3.6
>> + (list
>> + (channel
>> + (name 'guix)
>> + (url "https://git.savannah.gnu.org/git/guix.git")
>> + (commit
>> + "d66146073def03d1a3d61607bc6b77997284904b"))))
>> +
>> +(define connection-to-last-guix-with-python-3.6
>> + (inferior-for-channels last-guix-with-python-3.6))
>
> Why do you need an inferior? Is it to avoid the “guix time-machine”?
> Ah, no the answer below. :-)
>
>> +(define first car)
>> +
>> +(define python-3.6
>> + (first
>> + (lookup-inferior-packages
>> + connection-to-last-guix-with-python-3.6 "python")))
>> +
>> +(define python3.6-numpy
>> + (first
>> + (lookup-inferior-packages
>> + connection-to-last-guix-with-python-3.6 "python-numpy")))
>> +
>> +(define included-packages
>> + (list r r-reticulate))
>> +
>> +(define inferior-packages
>> + (list python-3.6 python3.6-numpy))
>> +
>> +(define package-with-python-3.6
>> + (package-with-explicit-python python-3.6
>> + "python-" "python3.6-" 'python3-variant))
>> +
>> +(define custom-variant-packages
>> + (list (package-with-python-3.6 python-apted)))
>> +
>> +(concatenate-manifest
>> + (map packages->manifest
>> + (list
>> + included-packages
>> + inferior-packages
>> + custom-variant-packages)))
>
> While this is cool, I would not recommend it as some practise. This
> kind of mix can lead to various annoyances, IMHO. First, it will scale
> poorly if you add more inferiors. Second, the probability that the
> resulting computational environment works well decreases.

After experiencing the resulting compile time, I agree. I just don't
know the best way to get a working python variant. I experimented today
with:

```
(use-modules
(guix profiles)
(guix packages)
(gnu packages)
(ice-9 regex)
(gnu packages python)
(guix base32))

(define (origin-nix-hash source)
(bytevector->nix-base32-string
(content-hash-value
(origin-hash source))))

(define-public (change-source source new-uri new-hash new-patches)
(origin
(inherit source)
(uri new-uri)
(sha256
(base32 new-hash))
(patches new-patches)))

(define (python-distribution-uri version)
version "/Python-" version ".tar.xz"))

(define-public python-3.6.8
(define v "3.6.8")
(package
(inherit python-3)
(version v)
(source
(change-source
(package-source python-3.9)
(python-distribution-uri v)
"14qi6n5gpcjnwy165wi9hkfcmbadc95ny6bxxldknxwmx50n4i1m"
(filter
(lambda (patch)
(not (string-match "fix-tests|hurd" patch)))
(origin-patches (package-source python-3.9)))))))

(packages->manifest (list python-3.6.8))
```

However, I ran into issues applying patches which I don't yet understand
how to deal with. It would be really cool if Guix had a command which
showed the state at each step in the process of creating a store
object. Whatever the workflow and tacit knowledge you use to debug these
things, I don't grasp it yet.

Toggle quote (15 lines)
>> diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm
>> index c8f04b2298..d4aaab906d 100644
>> --- a/guix/build-system/python.scm
>> +++ b/guix/build-system/python.scm
>> @@ -36,6 +36,7 @@ (define-module (guix build-system python)
>> #:use-module (srfi srfi-1)
>> #:use-module (srfi srfi-26)
>> #:export (%python-build-system-modules
>> + package-with-explicit-python
>> package-with-python2
>> strip-python2-variant
>> default-python
>
> Maybe this could be a separated patch.

That's a good idea. I suppose I could wrap it a bit with
e.g. package-with-python3-variant.
S
S
Simon Tournier wrote on 28 Feb 2023 15:16
(name . Kyle Andrews)(address . kyle@posteo.net)(address . 61701@debbugs.gnu.org)
87k001j2of.fsf@gmail.com
Hi,

On mer., 22 févr. 2023 at 23:21, Kyle Andrews <kyle@posteo.net> wrote:

Toggle quote (6 lines)
> However, I ran into issues applying patches which I don't yet understand
> how to deal with. It would be really cool if Guix had a command which
> showed the state at each step in the process of creating a store
> object. Whatever the workflow and tacit knowledge you use to debug these
> things, I don't grasp it yet.

Well, it appears to me expected that patches from 3.9 does not apply ’as
is’ to 3.6; or even the recipe itself.

For instance, commit a1454169e0 introduces Python 3.7.0 and the last
Python 3.6 series was 3.6.5. The change reads,

Toggle snippet (19 lines)
- `(modify-phases ,phases
- (add-after 'unpack 'patch-timestamp-for-pyc-files

[...] 40 lines

- ;; FIXME: Without this phase we have close to 2000 files that
+ `(modify-phases ,phases
+ ;; Unset SOURCE_DATE_EPOCH while running the test-suite and set it
+ ;; again afterwards. See <https://bugs.python.org/issue34022>.
+ (add-before 'check 'unset-SOURCE_DATE_EPOCH
+ (lambda _ (unsetenv "SOURCE_DATE_EPOCH") #t))
+ (add-after 'check 'reset-SOURCE_DATE_EPOCH
+ (lambda _ (setenv "SOURCE_DATE_EPOCH" "1") #t))
+ ;; FIXME: Without this phase we have close to 400 files that
;; differ across different builds of this package. With this phase
- ;; there are about 500 files left that differ.
+ ;; there are 44 files left that differ.

Then 3.8.0 with commit af6a9fc276 requires these patches,

Toggle snippet (7 lines)
+ (patches (search-patches
+ "python-3.8-search-paths.patch"
+ "python-3-fix-tests.patch"
+ "python-3.8-fix-tests.patch"
+ "python-3-deterministic-build-info.patch"))

and so on.

I understand the issue, on one hand inferior is appealing but expensive
if you have many and on the other hand, a simple switch of origins does
not work out of the box.

That’s why we have the guix-past channel [1]. :-) It maintains older
versions of some packages with the current Guix. I think it is the
place to define the matrix of Python versions; at least the ones you
want. Well, if your aim is to have the matrix of Python versions all
working with Guix, you cannot cut the boring task to define all the
entries of this matrix – package transformation has some limitations. :-)

You could start by extracting the recipe of Python 3.6.5 from commit
d66146073d (father of a1454169e0 updating to 3.7) and add it to the
guix-past channel.

Well, we seem far from a “cookbook section for reproducible research.” :-)


Cheers,
simon
L
L
Ludovic Courtès wrote on 2 Mar 2023 19:30
Re: bug#61701: [PATCH] doc: Propose new cookbook section for reproducible research.
(name . kyle)(address . kyle@posteo.net)
878rgf3t0u.fsf@gnu.org
Hi Kyle,

kyle <kyle@posteo.net> skribis:

Toggle quote (5 lines)
> From: Kyle Andrews <kyle@posteo.net>
>
> The intent was to cover the most common cases where R and python using
> researchers could rapidly achieve the benefits of reproducibility.

That’s a great idea!

Overall it looks nice to me. I would suggest reducing the scope a
little bit by taking inferiors and the Python 3.6 bit out—these things
could be discussed in a separate section.

Inline comments follow:

Toggle quote (3 lines)
> +@node Reproducible Research in Practice
> +@section Common scientific software environments

I’d use the same title for both.

Toggle quote (2 lines)
> +Many researchers write applied scientific software supported by a

Maybe s/researchers/scientists/ to be more inclusive (that would include
research software engineers, for instance; I’m one of them, hence that
comment. ;-))

Toggle quote (3 lines)
> +mixture of more generic tools developed by teams written within the R
> +and Python ecosystems and supporting shell utilities. Even researchers

s/written within … utilities./written in R, Python, and shell./

Toggle quote (3 lines)
> +who predominantly stick to using just R or just python often have to use
> +both R and python at the same time when collaborating with others. This

Make sure to always capitalize “Python” (and similarly for other proper
names).

Toggle quote (9 lines)
> +@example
> +(use-modules
> + (gnu packages cran)
> + (gnu packages statistics))
> +
> +(packages->manifest
> + (list r r-tidyverse))
> +

There’s a missing @end here.

For Scheme code, please use @lisp … @end lisp instead. That enable
syntax highlighting.

Toggle quote (3 lines)
> +R packages are defined predominantly inside of gnu/packages/cran.scm and
> +gnu/packages/statistics.scm files under a guix source repository.

Please use @file for file names…

Toggle quote (2 lines)
> +This manifest can be run with the basic guix shell command:

… and @command{guix shell} here.

Toggle quote (18 lines)
> +@example
> +guix shell --manifest=manifest.scm --container
> +@end example
> +
> +Please remember at the end to pin your channels so that others in the
> +future know how to recover your exact Guix environment.
> +
> +@example
> +guix describe --format=channels > channels.scm
> +@end example
> +
> +This can be done with Guix time machine:
> +
> +@example
> +guix time-machine --channels=channels.scm \
> + -- guix shell --manifest=manifest.scm --container
> +@end example

Remove ‘guix’ after the double dash.

Here I’d recommend including cross-references to the relevant sections
of the manual: “Writing Manifests” and “Replicating Guix”.

Toggle quote (5 lines)
> +If reproducibility becomes an end in itself and not a catlyst towards
> +faster discovery, then Guix will be a non-starter for scientists. Their
> +goal is to develop useful understanding about particular aspects of the
> +world.

I don’t fully understand this paragraph. I tend to think that

Toggle quote (12 lines)
> +Thankfully, three common scenarios cover the vast majority of
> +needs. These are:
>
> +@itemize
> +@item
> +combining standard package definitions with custom package definitions
> +@item
> +combining package definitions from the current revision with other revisions
> +@item
> +combining package variants which need a modified build-system
> +@end itemize

Like Simon, I’d suggest leaving out the second part (inferiors), and also
avoiding the Python 3.6 example, both of which make things immediately
more complicated.

We can keep the rest of the example though, if possible.

WDYT?

Thanks for your work!

Ludo’.
L
L
Ludovic Courtès wrote on 14 Sep 2023 18:24
(name . kyle)(address . kyle@posteo.net)
875y4c90zd.fsf_-_@gnu.org
Hello kyle,

I haven’t heard from you since your submission at
https://issues.guix.gnu.org/61701, but I’d like to propose something
different: turning
into a section of the Cookbook. I think it’s quite generic and matches
the most common use case in research.

If that sounds reasonable to you, I’ll work on converting it to Texinfo.

Ludo’.
?