You are trying to solve the wrong problem.
Obviously,I disagree. As I indicated, my own experience that acheiving maturity in software is the key to reliability, hence the (now old) adage that you should never use a x.0 release of anything for production purposes. And the key to maturity comes from the ability to re-use components. Decoupling of components through clearly defined and enforced interface contracts removes many of the barriers to code re-use.
We now have a way to rewrite software to be able to crash it immediately if a function is called incorrectly.
Put that way it doesn't sound so useful, but it is.
By "crashing immediately", it becomes painfully obvious that the program in incorrect. Its when coding errors are not detected that they make it out the door into production systems that cause most harm.
Failing reliably and early is the main benefit of using strict.
We can't guarantee that the function works as documented
That guarentee comes from maturity. The more often and the more widely a function is used, the more likely that any errors in the functionality will be detected and corrected. The maturity comes from reuse. I think this is the key to open-source developments success.
or that the caller understood the documentation and is calling the right function.
Clearly defined interfaces and enforcement result in early failure forcing the developer to discover his error sooner rather than later.
We can't guarantee that caller or callee is writing to a spec that remotely resembles what the user thought would happen.And we don't have a solution for the problem where you get half of your code written and then find out that you need to change the spec.
That's a mixed metaphor (without the metaphor:), and a different problem. This is more a bespoke software than a packaged software problem.
You can't fixed a bad specification at the code level. You either code to the spec and hope the spec is right, or you throw away the spec and the analysis (and the analyst while your at it) and use RAD to get the user to direct and approve the code step by step.
That doesn't rule out the practice of code re-use, nor the benefits derived from it. In fact, using RAD in conjunction with a readily available set of components is far and away the cheapest and quickest way of doing bespoke development. Enabling the developer to concentrate on picking and gluing the components together rather than needing to design and code the infrastructure from scratch each time.
This is exactly what HLL's are all about and Perl + CPAN in particular. The only fly in this ointment is that lack of consistancy in the quality of the documentation and code... (I'd also add a lack of coherence in overall design at the CPAN level, but that's a personal windmill).
The fact is that software development is all about management of complexity.
No argument there. And the key to managing complexity is "divide and conquor", "decomposition", "de-coupling", "objectifying", "componentisation". Call it what you will. The solution to complexity is to break it into smaller, soluble pieces.
The problem is, the more complex the problem, the more pieces are required. The more pieces, the more interfaces there are. These interfaces then become a part of the problem. Take a box of tried a trusted components and try to slot them together to make a complex entity and it's the connections that are the key. In the physical world, trying to screw a 3/4" bolt into a 5/8" nut makes getting it wrong pretty hard.
Every electrical connector these days is designed such that it will only connect one way. Do electricians, electronics engineers and technicians feel slighted by this idiot-proofing? No. They are grateful that another source of potential errors is removed from their daily lives.
Telling developers to accept a level of complexity across the board that may or may not help them much is more likely to compound the problem than to assist it.
I do not understand this assertion at all? I don't know where you are coming from or how you got there.
What I am advocating is the software equivalent of the one-way-only, keyed connector.
I doesn't alleviate the need for proper design, nor reduce the complexity of complex systems, nor free the developer from due care.
What it does do is enable complexity management through decomposition, and reliability through code re-use, by fool-proofing the connections between components, thus removing one of the perpetual problems of software development by moving it into the hardware.
Examine what is said, not who speaks.
1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
3) Any sufficiently advanced technology is indistinguishable from magic.
Arthur C. Clarke.