A constraint is an invariant that must be true before and after the change.
It doesn't matter if they are 'hidden' or 'visible'; if you must maintain the existing behavior, then you have to prove that no constraints are violated by the change you make.
The effort you have to expend is proportional to the number of places where you have invariant that must be maintained.
However.
If you isolate constraints in groups (call them crates, modules, whatever you want), then you can create a region which has no constraints except at the boundary where you interact with a defined API.
Since the volume is always >= the surface, you can prove that having the boundary is strictly <= effort to maintain than not having it.
Concretely:
If you can prove (because it is impossible due to the compiler rules or whatever manual process) that you have no dependencies on the internal functions inside a particular namespace / module / etc. because the only way it is ever possible to call those functions is via a specific public API.
...then you are not constrained in changing / refactoring / removing / whatever you want.
The internal workings have no external dependencies, no callers.
It is therefore less effort to maintain that code; because any change does not require you to go hunting around for someone calling helpers.internal.finance.convertCurrency for it's view model in a completely different domain.
If you want to call that 'hidden' then sure.
I'd probably say 'different view', but if basically yes, the point is that of the entire set of constraints for the system, you can say, today, our work is in this area of the code and we have a much much smaller set of things we have to worry about while we make changes here.
It's not rocket science; you see people doing this all the time; 'It's just a few tests, it can't break the database'.
Correct. The tests are a separate package that strictly the database schema has no dependencies on.
Therefore it is quick and easy and safe to make changes to them.
...
If your project only has two domains; 'tests' and 'non-tests', you literally doing the same thing the OP is suggesting, just at a slightly reduced scale.
In bigger, more sophisticated projects, the number of mini-domains inside a single project is usually > 2; but for exactly the same reasons.
You'll find out that analogies to Euclidean geometry do not hold for software structure in general.
That's a nice heuristic though. Just be wary that if you follow it blindly, you will inevitable optimize things into a counterexample where everything breaks down while your proof still finds it's the optimal.
Static analysis is good, in moderation; dynamic validation is good, in moderation; accepting errors and dealing with them is goo, again, in moderation. All of those things turn bad if you do them out of dogma.
Care to point out your best example on when static code analysis ceases to be good?
I don't think there is possibly any copout to justify away the benefits of static code analysis. Either your code works by complying to the interface, or it doesn't and violates interfaces. The only thing static code analysis does is force you to acknowledge the real interfaces.
Hum... You mean you've never encountered complex interfaces dictated by their types?
I was about to make a Haskell joke, but it's actually Java that is most famous for this. There are lots of "enterprise Hello-Word" published on the internet if you want some done on purpose.
> Hum... You mean you've never encountered complex interfaces dictated by their types?
I asked you what you personally believe is your best example on when static code analysis ceases to be good. I fail to see how anyone's opinion or personal experiences determine your own personal opinion on a subject.
Can you provide any example on how static code analysis can be anything other than a good thing?
> There are lots of "enterprise Hello-Word" published on the internet if you want some done on purpose.
I'm sorry, what does this have to do with static code analysis?
Sure, maybe the metaphor doesn't make perfect sense.
...but, strictly, if you have a module with K public functions and P private functions the maximum possible number of unique external dependencies you have to track on the module is K.
If P > 0, then the 'api surface' of the module is smaller than the total set of functions.
If K = 0, the module has no external dependencies and you can do whatever you want.
I'm going to say with complete confidence that creating 'boxes' in your software where you minimize K creates maintainable software.
Abstractly:
A constraint is an invariant that must be true before and after the change.
It doesn't matter if they are 'hidden' or 'visible'; if you must maintain the existing behavior, then you have to prove that no constraints are violated by the change you make.
The effort you have to expend is proportional to the number of places where you have invariant that must be maintained.
However.
If you isolate constraints in groups (call them crates, modules, whatever you want), then you can create a region which has no constraints except at the boundary where you interact with a defined API.
Since the volume is always >= the surface, you can prove that having the boundary is strictly <= effort to maintain than not having it.
Concretely:
If you can prove (because it is impossible due to the compiler rules or whatever manual process) that you have no dependencies on the internal functions inside a particular namespace / module / etc. because the only way it is ever possible to call those functions is via a specific public API.
...then you are not constrained in changing / refactoring / removing / whatever you want.
The internal workings have no external dependencies, no callers.
It is therefore less effort to maintain that code; because any change does not require you to go hunting around for someone calling helpers.internal.finance.convertCurrency for it's view model in a completely different domain.
If you want to call that 'hidden' then sure.
I'd probably say 'different view', but if basically yes, the point is that of the entire set of constraints for the system, you can say, today, our work is in this area of the code and we have a much much smaller set of things we have to worry about while we make changes here.
It's not rocket science; you see people doing this all the time; 'It's just a few tests, it can't break the database'.
Correct. The tests are a separate package that strictly the database schema has no dependencies on.
Therefore it is quick and easy and safe to make changes to them.
...
If your project only has two domains; 'tests' and 'non-tests', you literally doing the same thing the OP is suggesting, just at a slightly reduced scale.
In bigger, more sophisticated projects, the number of mini-domains inside a single project is usually > 2; but for exactly the same reasons.