> No.  Look at all the other build systems.  None of them use submodules of (gnu
> packages), for a good reason.

Ok, I see. It would introduce circular dependencies. By "resolve," you
mean something like: ~(resolve-interface '(gnu packages yyy))~. So, in
our case it means:
#+begin_src scheme
(define (default-glibc-utf8-locales)
  (let* ((base (resolve-interface '(gnu packages base)))
         (glibc (module-ref base 'glibc))
         (make-glibc-utf8-locales (module-ref base 'make-glibc-utf8-locales)))
    (make-glibc-utf8-locales glibc #:locales (list "en_US"))))

(define (default-elixir-hex)
  (let ((elixir (resolve-interface '(gnu packages elixir))))
    (module-ref elixir 'elixir-hex)))

(define (default-rebar3)
  (let ((erlang (resolve-interface '(gnu packages erlang))))
    (module-ref erlang 'rebar3)))


#+begin_src scheme
(define* (lower name
                (elixir (default-elixir))
                (elixir-hex (default-elixir-hex))
                (glibc-utf8-locales (default-glibc-utf8-locales))
                (rebar3 (default-rebar3))
                #:allow-other-keys #:rest arguments)


Is this correct?

> Not necessarily, but you want a different way of building $out/lib/elixir/X.Y/
> that doesn't leak through the function signature.

Following ~python-build-system.scm~, it means something like:
#+begin_src scheme
(define (elixir-version elixir)
  (let* ((version     (last (string-split elixir #\-)))
         (components  (string-split version #\.))
         (major+minor (take components 2)))
    (string-join major+minor ".")))

(define (install-dir inputs outputs)
  "Return the path of the current output's Elixir library."
  (let ((out (assoc-ref outputs "out"))
        (elixir (assoc-ref inputs "elixir")))
    (string-append out "/lib/elixir/" (elixir-version elixir) "/site-packages")))


Is this correct?

> Btw. I think that you're resolving transitive inputs twice; once on the build
> system code and once by fattening the outputs.  You probably only need either
> of those, not both.

Ah. Propagated inputs are propagated. Who would have thought? So, this is not necessary:
#+begin_src scheme
(define* (lower …)
  (define all-propagated-inputs
      (cut delete-duplicates <> equal?)
      (cut filter erlang-or-elixir-input? <>)
      (cut append-map package-transitive-propagated-inputs <>)
      (cut map cadr <>))
     (append inputs native-inputs)))

  (define build-inputs

  (bag …
       (build-inputs build-inputs)

I've just removed ~all-propagated-inputs~ and all packages build just fine.

Is this what you meant?

> Yep, that would work.  Note that delete-duplicates is O(n^2), though.  We have
> a little bit of code where it's done in (I assume) O(n*log(n)) with vhashes.

If ~all-propagated-inputs~ is removed, then the discussion of this comment is