I want to believe that it's possible. When you start introducing even the most basic complexities of a web app (authentication, access control, database connections, reusable CRUD functionality - all the things that make up a non-trivial application) I find it really hard to stay organized in a procedural style.
I'm not being snarky; I'd love to see a good example of this.
Some would definitely argue that Drupal results in spaghetti code, due to a large amount of module functionality being written in hooks that are invoked to change behavior at runtime. It also has an elaborate theming process that yields many opportunities for module or theme code to modify data as it passes through the layers of data generation, processing, theming, etc.
My personal experience on some large Drupal projects is that with an experienced team that knows "the Drupal way" of doing things, you can write some very well organised code that is easy to maintain and extend. However, I doubt this is the norm with Drupal projects.
I also think that Drupal 8 and beyond will move more and more towards an OO-based methodology, as the learning curve for the current system is very high.
In the past 2 years we have developed a Mobile Companion Platform for TV which scaled to many hundred thousand users, a scalable appstore for TV, a Middleware Platform for HTML/Android Set Tops, a mobile Live TV platform and a Campaign Management System for TV. I find it exceedingly difficult to manage and scale containers and would not use them for anything other than strict enterprise stuff.
Our platforms typically have 80-100 CRUD APIs and finish within 10000 lines of PHP with heavy lifting delegated to cloud APIs and Java based crons/long lived processes.
1:
The trick to this has been to have minimal code in the MVC layer, and keep most of the logic in functions which are organized in into per topic files.
So when my application wants to find out the price of something, I'll call price($product, $user) from pricing.php, which will then handle all the voodoo business rules about pricing (does the user get a member discount? what kind of discount do they get? do they own a related product? is it Friday the 13th?) price() depends on other functions like has_active_membership() defined in the file about subscriptions, and on membership_discount_pct() in the pricing file.
This function oriented breakdown applies not just to business logic, but authentication, charging credit cards through stripe, sending emails, course status, editing rights, etc.
I deliberately do not use any hooks or other meta chicanery. It's plain functions calling plain functions all the way down.