I've found that it really varies based on the language and the tooling it offers. I code Erlang and Elixir on a daily basis, and I've never used such a full-featured debugging environment before. I can trace messages across a distributed system, connect to production nodes to set breakpoints or tracepoints, and I can render a live visualization of all the supervision trees in my application and watch as processes spawn and are killed. And of all that is just scratching the surface of what you can do.
I also remember Racket having pretty powerful debugging capabilities, including the ability to step through programs and see how each expression is evaluated.
Some languages have worse tooling than others, but I don't think it's a problem endemic to functional programming.
I also remember Racket having pretty powerful debugging capabilities, including the ability to step through programs and see how each expression is evaluated.
Some languages have worse tooling than others, but I don't think it's a problem endemic to functional programming.