|Think about Loose Coupling|
Thankfully, AutoLoader and similar modules have been becoming less widely-used. Having repeatedly seen code that takes way too long to load all of the tons of modules that eventually get used, my experience is that the slow loading is always due to a bunch of initialization that is being done too soon, not due to the time required to read and compile the code for subroutines. Though I've often seen people making the assumption that it was the time to read and compile the modules' code that was to blame. (See Devel::Init for my suggestion for how to avoid doing even slightly costly initialization too soon, or too late.)
So I suspect that the creation of modules for delaying the loading of module code may have been significantly motivated by flawed assumptions.
The worse problem with AutoLoader is that it is applied to a module via inheritance, which was just a horrible idea. Autoloading is not a property that should be inherited. If class X autoloads and class Y inherits from class X, it is simply a mistake for class Y to get impacted by class X's decision to use autoloading.
This is made even worse by AutoLoader giving a particularly bad error message for the case of a mispelt method name. Now calling Y->foo() when I meant to call Y->food() tells me that I installed the Y module incorrectly because I clearly left out the Y/foo.al file (when all that I left out was the letter 'd' in my code).
And this is made even worse by the twin design mistakes of having DynaLoader 1) use AutoLoader, and 2) be used via inheritance.
And aspects of this are also made worse by the fact that Perl has great support for using a module that makes changes that have to be made at compile-time (because they impact the syntax of the following code) but has awkward support for using modules that don't need to make changes at compile time.
It would be very nice for require to be enhanced so that it can be used more like use and also be more useful for loading OO modules. That is, require should be extended so that it can be used both of these ways:
And then it should be a decision based on the environment as to whether 'require' actually loads the module code at run-time or at compile-time. I'd default to loading at run-time and then having a "test dependencies" step that happens relatively frequently (at least before deploying and after deploying) that specifies "load all dependencies at compile-time" and then pretty much just exits.
I plan to make a proof of concept of "better 'require'" under a different name ('load'?) but also to push for Perl's own 'require' to get better in parallel (in my "copious free time").