I really feel like this is an underappreciated aspect of some of the more complained-about constraints that these newer languages place on programmers.
Like an i32, the default allocator will do a reasonable thing most of the time, but having to think about each allocation (is this short-lived or long-lived? is it actually necessary to do a heap allocation at all here? do you actually want GC?) makes code better and pushes the programmer to improve their ability to rationalise about what they’re actually doing in ways that provide tangible benefits.
By way of comparison, when I started writing Rust I was very frustrated by all the explicit conversions, but eventually realised that it (a) forces me to actually stop and think about what the most natural type is for a given value, and (b) also makes it clearer where the natural boundaries are between components. In my experience, if there’s a lot of conversion going on within a function or module, it’s usually not because the language is ‘too verbose’. Instead, it’s because the API boundaries are in the wrong places, and the language has helped to reveal this by making doing the wrong thing harder.