1. 3

    A few off the top of my head (I mostly have experience with Make, Nix and Cabal):

    • Tools which assume they’re interacting with a user, making scripting harder. This is actually an umbrella problem for some of the others below.
    • Special snowflake languages (config or script). The problem isn’t whether or not it’s hard for a person to learn the syntax; it’s that any new language is automatically incompatible with all existing tooling (parsers, pretty-printers, formatters, editor shortcuts, etc.). Just use JSON/XML/s-expressions unless there’s a very compelling reason not to (and “too many parens” isn’t a compelling reason; see e.g. sweet expressions, etc.). Guix seems to be the least offensive in this regard ;)
    • Closed ecosystems. For example, Cabal (by default) looks up package names from Hackage. If I want to use e.g. a git repo, I need to add it using command invocation.
    • Language-specific assumptions. If a Haskell package depends on other Haskell packages, Cabal can build it. If it depends on some non-Haskell package, then it can’t. Except for special snowflakes like zlib.
    • Hard-coded special cases. For example, looking up some particular tools (e.g. happy) but not allowing users to specify their own tools to be looked up.
    • Implicit changes in behaviour due to the environment, e.g. whether or not certain directories exist, or their contents, when those directories aren’t explicitly defined on the commandline or some env var. Cabal was notorious for this, prior to the “sandbox” feature.
    1. 1

      Closed ecosystems. For example, Cabal (by default) looks up package names from Hackage. If I want to use e.g. a git repo, I need to add it using command invocation.

      Cabal is fixing this

      Hard-coded special cases. For example, looking up some particular tools (e.g. happy) but not allowing users to specify their own tools to be looked up.

      This too I think, with build-tool-depends