> If you get a circular dependency something is wrong with your design
Packages not being able import from each other circularly is purely a compiler limitation. It says nothing about the realities of software development.
This notion stems from the idea that software design is inherently hierarchical, and that there is always a clear "higher level" and "lower level" between every possible software module.
What I've found in practice is that this is a fictional concept. Circularity between modules is very common and natural (especially as business requirements change over time). The workarounds people invent to avoid circularity literally always result in a codebase that is harder to understand and maintain, rather than easier.
> It forces you to separate your concerns properly.
Nah. It's not separation of concerns, it's separation of implementation. Two functions that in every other way shape and form deal directly with the same concepts, end up needing to be in separate modules purely because they differ in the functionality they import. And if later their imports change, they may need to be moved again. Which means implementation details are leaking into your design, which makes code less discoverable (since you now need to know implementation details in order to reasonably predict where a given function might be defined).
Packages not being able import from each other circularly is purely a compiler limitation. It says nothing about the realities of software development.
This notion stems from the idea that software design is inherently hierarchical, and that there is always a clear "higher level" and "lower level" between every possible software module.
What I've found in practice is that this is a fictional concept. Circularity between modules is very common and natural (especially as business requirements change over time). The workarounds people invent to avoid circularity literally always result in a codebase that is harder to understand and maintain, rather than easier.
> It forces you to separate your concerns properly.
Nah. It's not separation of concerns, it's separation of implementation. Two functions that in every other way shape and form deal directly with the same concepts, end up needing to be in separate modules purely because they differ in the functionality they import. And if later their imports change, they may need to be moved again. Which means implementation details are leaking into your design, which makes code less discoverable (since you now need to know implementation details in order to reasonably predict where a given function might be defined).