With that definition all programming languages are frameworks.
The first part of the article defines what the author means by a framework, which is different from libraries, and programming languages in general.
It's similar to the difference between function and algorithm. The former is literally code, and the latter is conceptual.
Many programming languages are distributed with a cohesive framework. For example, Rust is distributed not only with rustc to compile binaries, but also with cargo to manage library dependencies. That doesn't prevent you from using rustc without cargo, though, or even making another rust compiler for GCC, and using GCC's framework.
What is a class definition in an OO language but a way for you to implement some state and some functions in a particular pattern that, when plugged in the framework of the compiled application runtime, will take care of the lifecycle and marshalling of calls to your code?
That meets all the definitions of framework provided by the author.
Which is exactly what I am talking about.
If adding a new commandline parameter to your application involves adding a piece of validation logic that gets called on startup, putting an extra line of code into the help text initializer, and writing a handler to be called when the parameter is supplied... then the flow of control is already dictated by the application, and you are adding new functionality over the top of an abstraction. You are using a framework, not a 'function'.
All a framework means is that there is a coherent, repeatable model for implementing the building blocks out of which the application is built.
Even a simple command line program with hardly any functionality soon runs into the issue of having more than one command-line argument or environment-variable based configs. And a sensible, maintainable approach to this involves someone spotting ‘hey! We can abstract the bits that all our command-line parameters have in common so processing them all is consistent’. And then you have a framework. Because now ‘adding a new command line parameter’ has to be done in the standard way - you register a validator here and you add a help string there.
Building something without a framework is a rejection of patterns, or of the value of establishing repeatable structure.
Software that facilitates encapsulating chunks of functionality as standard building blocks is more maintainable over time. It’s much easier to work on a system where you can take a user story and interpret it as ‘okay, so we can implement that as a new Task type and then add a Tool to the Tool Library that lets users who have the right Role create a Schedule to run the task’. any time a system is sufficiently structured that you can think that way, it’s essentially become a framework.
Frameworks can be lightweight or heavyweight, sure, and they can be open to being overstepped or closed - and choosing when to prefer to structure your framework to make it easier or harder for someone to step outside the lines is just an engineering choice like any other.