Background: the x/tools/go/packages.Load function returns a set of packages that are nodes in a DAG, the import graph over packages. To enumerate them, one calls Visit, passing a pair of (pre, post) functions to be called before and after the node is visited in dependencies-first order. The pre feature is almost unused: only one of the two dozen calls to Visit in x/tools uses it; I suspect the ratio is even lower in the broader ecosystem.

Proposal: As a convenience, we propose to add a Postorder function that returns a go1.23 iterator over the sequence of packages in the import graph, in dependencies first order.

package packages // golang.org/x/tools/go/packages

// Postorder returns an iterator over the the packages in
// the import graph whose roots are pkg.
// Packages are enumerated in dependencies-first order.
func Postorder(pkgs []*Package) iter.Seq[*Package]

Example before:

    pkgs, err := packages.Load(...)
    if err != nil { ... }
    packages.Visit(pkgs, nil, func(pkg *Package) {
        log.Println(pkg)
    })

Example after:

    for pkg := range packages.Postorder(pkgs) {
        log.Println(pkg)
    }