An Ontological Critique of Object Oriented Programming
Had a very interesting conversation with a work colleague Rudy yesterday, which started off about linguistics, philosophy and mathematics [yes, we're geeky software developers!], which ignited a observation I had a while back ago on the similarity of Wittgenstein's later philosophy to object oriented programming. But thinking a little more deeply about this and referring back to some philosophical literature, I think Wittgenstein philosophy is actually critical of the basic tenets of OOP and would incorporate a methodology that may actually better map to the real world.
There's no doubt that the complexity of software construction has increased at an almost exponential level in the past decade or so, especially with the explosion of the internet and our societies increasing reliance of computer software to manage this. This has lead a push to create more higher levels of abstraction in programming languages so that developers can think in more natural metaphorical manner with respect to things in code that do things or map to things in the real world. Therefore, let's say we are building software to automate the manufacturing of automobiles in a plant, using an object oriented language we could model the notion of a car with a car object and the action to which this car object interacts with methods associated with this object. A pseudo-Java like implementation would look like the following:
This fulfills one of the three basic tenets of OOP, namely encapsulation since the data structures and the algorithms that act on those data in fully encapsulated in the object. The others would be inheritance, whereby you could derive a particular type of car from a base car type, such as a SportsCar object which would share the same characteristics as all cars, but have distinguishing features such as a bigger engine, sporty chassis, etc., and the need to be able to start in order to run like its base car type. And last would be polymorphisms, since the Start() method could be used in a derived object as if it were the base object.
In the older procedural programming method, you would typically have to define a lot of separate functions and a long series of select case statements to achieve the same results. This proved to be more time consuming and error prone, hence the need to create better levels of abstractions.
But the above is actually quite grounded in the notion of classical categorization. As Booch states in "Object Oriented Analysis and Design" that classical categorization "comes to us first from Plato, and then from Aristotle... the classical approach uses related properties as the criteria for sameness among objects. Specifically, one can divide objects into disjoint sets depending upon the presence or absence of a particular property".
This would agree with the basic outlines of OOP just articulated, for the car class would define in an abstract manner what all possible object of that class would be like. There is a set of necessary and sufficient properties to distinguish if an object belongs to a certain category. It either does or does not; there are no graded boundaries. It is a matter of two-valued logic: a statement of type "object x belongs to the category X" is either true or false. In Aristotle's terms this is the essence of a category.
The implications of this view, are that objects are entities that are suppose to correspond to the external world, are in fact internal representations of the external realities. In other words, real world objects are mere shadows of the classes, and we are seeing only the shadows, and mistakingly taking them to be real, to put it in Plato's "Allegory of the Cave" theme. Maybe this is why despite progresses in software engineering such as OOP, we are still delivering buggy software over budget, and not on time is because our notions of real world objects and their interactions are mere "shadows" of classes!
This is where Wittgenstein comes in, as he was one of the notable figures in Western philosophy that reacted strongly against this ideology (Nietzsche was another). According to Wittgenstein, objects would not be some outcomes or mere "shadows" of Platonic classes, but rather that they are entities that come in "families". A family is a set of real objects that would "resemble" each other from various points of view. For example, a "sports car" is a set of all the objects that we call by that name. But we group together these objects in one single family, not because they share some common essence, but out of historic or contextual perspectives.
In OOP terms, buttons and windows on a web page are not derived from some predetermined class that force you to modify it in very specific ways, but would belong to a "family" of buttons and windows that resemble the function or features we seek. We know this because historically we empirically witnessed what a family of buttons and windows could do [for example, buttons and windows behave quite differently on a web form then they do on a client/server form] and our particular context would determine what kinds of methods to utilize for these dynamic objects to interact [e.g., I have a Flash form on a web page that have buttons and windows that resemble the family of client/server applications, but will interact through a web page. Thus, I will have buttons and windows incorporating aspects of both].
It's interesting to note that recent developments in software design such as Aspect Oriented Programming seem to be gravitating towards this Wittgensteinian mindset. AOP for example, has the notion of breaking units of code down such as they overlap in functionality as little as possible. As such, a typical OOP system provides the packages, classes and methods to support the separation of encapsulation and concerns into single focus. But as anyone who has designed and programmed OOP knows that not all "concerns" can be so neatly encapsulated. This is where AOP proposes the notion of "cross cutting" concerns. A Wikipedia example uses the notion of a logging module that would be a cross-cutting concern since "a logging strategy necessarily affects every single logged part of the system. Logging thereby crosscuts all logged classes and methods".
There's no doubt that the complexity of software construction has increased at an almost exponential level in the past decade or so, especially with the explosion of the internet and our societies increasing reliance of computer software to manage this. This has lead a push to create more higher levels of abstraction in programming languages so that developers can think in more natural metaphorical manner with respect to things in code that do things or map to things in the real world. Therefore, let's say we are building software to automate the manufacturing of automobiles in a plant, using an object oriented language we could model the notion of a car with a car object and the action to which this car object interacts with methods associated with this object. A pseudo-Java like implementation would look like the following:
public class Car
{
void Start()
}
This fulfills one of the three basic tenets of OOP, namely encapsulation since the data structures and the algorithms that act on those data in fully encapsulated in the object. The others would be inheritance, whereby you could derive a particular type of car from a base car type, such as a SportsCar object which would share the same characteristics as all cars, but have distinguishing features such as a bigger engine, sporty chassis, etc., and the need to be able to start in order to run like its base car type. And last would be polymorphisms, since the Start() method could be used in a derived object as if it were the base object.
In the older procedural programming method, you would typically have to define a lot of separate functions and a long series of select case statements to achieve the same results. This proved to be more time consuming and error prone, hence the need to create better levels of abstractions.
But the above is actually quite grounded in the notion of classical categorization. As Booch states in "Object Oriented Analysis and Design" that classical categorization "comes to us first from Plato, and then from Aristotle... the classical approach uses related properties as the criteria for sameness among objects. Specifically, one can divide objects into disjoint sets depending upon the presence or absence of a particular property".
This would agree with the basic outlines of OOP just articulated, for the car class would define in an abstract manner what all possible object of that class would be like. There is a set of necessary and sufficient properties to distinguish if an object belongs to a certain category. It either does or does not; there are no graded boundaries. It is a matter of two-valued logic: a statement of type "object x belongs to the category X" is either true or false. In Aristotle's terms this is the essence of a category.
The implications of this view, are that objects are entities that are suppose to correspond to the external world, are in fact internal representations of the external realities. In other words, real world objects are mere shadows of the classes, and we are seeing only the shadows, and mistakingly taking them to be real, to put it in Plato's "Allegory of the Cave" theme. Maybe this is why despite progresses in software engineering such as OOP, we are still delivering buggy software over budget, and not on time is because our notions of real world objects and their interactions are mere "shadows" of classes!
This is where Wittgenstein comes in, as he was one of the notable figures in Western philosophy that reacted strongly against this ideology (Nietzsche was another). According to Wittgenstein, objects would not be some outcomes or mere "shadows" of Platonic classes, but rather that they are entities that come in "families". A family is a set of real objects that would "resemble" each other from various points of view. For example, a "sports car" is a set of all the objects that we call by that name. But we group together these objects in one single family, not because they share some common essence, but out of historic or contextual perspectives.
In OOP terms, buttons and windows on a web page are not derived from some predetermined class that force you to modify it in very specific ways, but would belong to a "family" of buttons and windows that resemble the function or features we seek. We know this because historically we empirically witnessed what a family of buttons and windows could do [for example, buttons and windows behave quite differently on a web form then they do on a client/server form] and our particular context would determine what kinds of methods to utilize for these dynamic objects to interact [e.g., I have a Flash form on a web page that have buttons and windows that resemble the family of client/server applications, but will interact through a web page. Thus, I will have buttons and windows incorporating aspects of both].
It's interesting to note that recent developments in software design such as Aspect Oriented Programming seem to be gravitating towards this Wittgensteinian mindset. AOP for example, has the notion of breaking units of code down such as they overlap in functionality as little as possible. As such, a typical OOP system provides the packages, classes and methods to support the separation of encapsulation and concerns into single focus. But as anyone who has designed and programmed OOP knows that not all "concerns" can be so neatly encapsulated. This is where AOP proposes the notion of "cross cutting" concerns. A Wikipedia example uses the notion of a logging module that would be a cross-cutting concern since "a logging strategy necessarily affects every single logged part of the system. Logging thereby crosscuts all logged classes and methods".
With this in mind, one can see how this very much maps to Wittgenstein's notion of family resemblances, as each cross-cutting concern "resemble" each concern from various points of view, and that view is how well it maps to the historical and contextual perspective of the person(s) building the software system.
I have only reached the tip of the iceberg with regard to this, and is interesting to see how my studies in philosophy actually map to something I do for a living. :-)
Labels: Computer Science, Philosophy
0 Comments:
Post a Comment
<< Home