In the past I enjoyed the concept and practice of programming because it provided an opportunity to explore a way of thinking about a problem without the usual constraints that one may face in the real world. The greater challenge (hence satisfaction) is in defining a model that will account for any potential failures and still be able to accomplish its intended purpose. As time passed, I have come to focused specifically on design and the resulting architecture. Designing anything is a process of creating a model that can account for the solutions to aspects of the problem specified. That is reductive in and of itself but there are much more insightful aspects of problem solving that need to be taken into account in designing and developing a solution.
In any design effort, the ability to abstract from the problem remains imperative while the generally accepted adage of too much of [take-your-pick] is a poison applies, abstraction done right can provide a practical solution to a multitude of problems. Programming paradigms have always been about creating models that either provide a way for us to give instructions to computers or a way for us to describe the world in a manner that a computer can comprehend and hence process. Programming languages remain a way for humans (programmers, software engineers, etc) to interact with a computer – giving it instructions on what to do and how to handle the particulars of our reality. The models that are implicitly encoded into programming languages represent our thinking as far as the machine-like view of the world or bringing the machine closer to the way we appreciate the world.
What are generally referred to as low level programming languages were essentially intended to enable us to communicate with computers and as such they bare close relationship to the way in which computers operate. Think of the assembly language and how you program in it.
With time, additional abstractions were added that allows us to focus more on giving computers instructions as opposed to prescribing the manner in which the computer carries out our instructions. This focus on instructions gave raise to what are generally referred to as procedural programming languages in which the emphasis was on results of the operations that need to be accomplished. The ability to focus on what you want done and how it is achieved in steps, obviously led to a greater interest in using computers to carry out what are essentially repetitive tasks that could easily be encoded in a number of functions which can then be executed and produce the desired result (or report errors, if any).
This focus on the procedures that are needed to accomplish a task leads to a huge codebase that is both hard to maintain and/or evolve to meet new and/or changing circumstances. This great problem would apparently seem to come from the fact that the procedural way of software development, does not adequately account for how the real world operates. In the real world, things exist and operate as a single unit – there is no difference between what something is and what it does.
Personally, I get the impression that this is the time when programming became a bit more philosophical in a sense that there is a deliberate effort to model the world in terms of its nature and its essence. The nature of the world, describes what the world is: in OOP, this is simply described as the state of the an object which is typically denoted by properties/attributes/fields, depending on the terminology of your platform of choice. You may notice that the nature of objects so defined does not need to change in order to make things happen because OOP relies on message passing to get Objects with the appropriate nature to carry out the intention of their essence as defined by their nature (what you do is defined by your nature and your nature defines what you do).
While OOP allows for a better abstraction from the real world, the manner in which it has been implemented thus far has a serious short coming. All the OOP languages that I have come across are rather verbose as the design process need to describe any application elements of the problem space in code. With increasingly large programs, it comes much more challenging to maintain large programs or ensure that they are tested to the satisfaction of end users. So, testing frameworks have mushroomed around OOP languages such as Java with JUnit (among so many others).
For all intends and purposes, OOP still bears some lingering association with how a machine would go about processing instructions. The so-called Fourth Generation Languages (4GL) like the Structured Query Language (SQL) has shown us to go about expressing our intention to the machine and have the machine figure out the means of getting to our intentions or at the very least least as close to it as possible. The oft-referenced Moore’s law continues its march into ever more powerful machines albeit in a slightly different way. With powerful processors, driving our computers we do not have to be chained to the vagaries of machine type thinking.
Another more poignant point to consider is the increased use of computers for entertainment (gaming etc), business and socializing. The nature of the problems that face social networking applications are markedly different from what have faced businesses at the advent and development of the current mainstream programming language. A business environment invariably has some kind of structure around it which is encoded in policies, procedures, organization structure and the processes that the organization run. Starting from such a foundation, it is then possible to formulate a few procedures which can be executed at regular or ad hoc basis to great effect. However, consider the way in which social networking sites are used – a single person would have a Facebook account, a Twitter account, YouTube account in addition to web mail accounts. These applications have become people centric and the number of people involved an quickly become a challenge for social networking sites that have managed to garner a big enough following.
The social network craze reveals an interesting dimension of how programming languages have evolved over time. At the outside, a few academicians used computers to help with research and then the business world caught on and now we have to face the reality that perhaps programming languages need to be less rigid. Often when discussing IT related subjects, less rigid may easily lead to less secure though in this context less rigid but more robust would be the best outcome in the evolution of programming languages. Objects are good as way to model the world but they lack a certain degree of expressiveness in effectively illustrating and modeling the state of the world as a seen a person who cares more about getting things done and less about the steps taken to get to the end.