Subject: Re: bug#49597: [PATCH core-updates 00/15] Ajust packages to label-less input style

From: Ludovic Courtès <[email-masked]>
Date: Tue, 20 Jul 2021 23:14:50 +0200

Hi,

Maxime Devos <[email-masked]> skribis:

> Ludovic Courtès schreef op ma 19-07-2021 om 16:50 [+0200]:
>> [...]
>> 
>> > In the example you gave, both search-input-file and the original 'string-append'
>> > and 'assoc-ref' look convenient to me, though the latter more so than the other,
>> > and a third variant could be
>> > 
>> >   #$(file-append (this-package-native-input "openmpi") "/lib/libmpi.so")
>> > 
>> > which avoids 'string-append' and 'assoc-ref'.
>> 
>> Yes, but you’re still relying on the name, “openmpi”.
>> 
>> If I do:
>> 
>>   (package
>>     (inherit thing)
>>     (inputs `(("mpich" ,mpich)
>>               ,@(delete "openmpi" (package-inputs thing)))))
>> 
>> … then you have a problem: ‘this-package-input’ won’t find “openmpi”.
>> It’s a real, common use case.  That’s why we need to be careful about
>> the idioms we promote.
>> 
>> WDYT?
>
> Then you could do:
>
>   (package
>      (inherit thing)
>      (inputs `(("openmpi" ,mpich) ; use "openmpi" label
>                ,@(delete "openmpi" (package-inputs thing)))))
>
> or just use "mpi" in the original and new package as input label,
> but that doesn't mesh well with eventually removing input labels.

Yes, but the goal is to remove input labels.  :-)

> Myself, I don't mind input labels much. They look like arguments to
> a procedure to me, albeit with an unusual syntax for referring to
> them.

Well, we can deal with labels, but removing them lowers the barrier to
entry and reduces boilerplate, which most of us enjoy.

>> > (I prefer explicitely writing in the package definition in which input a file
>> > will be found, as a kind of documentation, though in this case it probably
>> > doesn't really matter.)
>> 
>> Yeah, I like that too.  OTOH, ‘search-input-file’ has the advantage that
>> it errors out if the file is not found, whereas
>> 
>>   (string-append (assoc-ref inputs "foo") "bar")
>> 
>> always “works” and problems occur possibly much later, at run time.
>
> I'd suggest using #+/#$(file-append (this-package-[native]-input "foo") "/bar"
> instead of (string-append (assoc-ref ...) ...).

That’s what I had in mind initially, but that means you’re still relying
on labels or package names¹.  Sometimes that’s OK, sometimes not.

> I think I have a method for explicitely choosing which input to use,
> using package names instead of labels, that still works nicely with
> "--with-input":
>
> (define* (lookup-libmpi-library package)
>   ;; open-coding could be avoided by adding a 'is-mpi-library?'
>   ;; package property and using that instead of hard-coding a list
>   ;; of package names 
>   (file-append (or (lookup-package-input package "openmpi")
>                    (lookup-package-input package "mpich")
>                    ...)
>                "/lib/libmpi.so"))

Yes, an ‘mpi-library?’ property could do the job, together with a
variant of ‘lookup-package-input’ that accepts a predicate rather than a
name.

Yet, that would only work for cases that packagers have explicitly
prepared.  For example, the example above won’t work with:

  --with-input=emacs=emacs-next

unless you actually to the same kind of enumeration or property.  This
approach just doesn’t scale.

But look, in the majority of cases, we don’t do (assoc-ref inputs …) at
all; we just use things that happen to be in $PATH, $PYTHONPATH, and so
on.

In a sense, this whole ‘search-input-file’ strategy follows that
approach.  ‘search-input-file’ is just a generalized version of ‘which’,
as you know.

WDYT?

Ludo’.

¹ Nix doesn’t have this particular problem: “packages” are actually
  functions, so one can refer to their inputs by value, as in:

    { stdenv, openmpi, … }: {     # <- formal parameters of the function
      configureFlags = [ "--with-mpi=${openmpi}" ];
      # …
    }

  I thought about using advanced macrology so that, say, ‘openmpi’ is
  the lexical scope of ‘arguments’ would be bound to the same ‘openmpi’
  referred to in ‘inputs’, such that you could write:

    (package
      ;; …
      (arguments
       (list #:configure-flags
             #~(list (string-append "--with-mpi=" #$openmpi))))
      (inputs (list openmpi)))

  I couldn’t think of a reliable way to do that, though.

  I also think it’s a good idea, performance-wise, to move as much as
  possible from the host side to the build side for packages.