Updated 2015-04-25 20:14:59 by pooryorick

I have tried to sort OOP's advantages. Enjoy.

Advantages of OOP

Object-Oriented Programming has the following advantages over conventional approaches:

  • OOP provides a clear modular structure for programs which makes it good for defining abstract datatypes where implementation details are hidden and the unit has a clearly defined interface.
  • OOP makes it easy to maintain and modify existing code as new objects can be created with small differences to existing ones.
  • OOP provides a good framework for code libraries where supplied software components can be easily adapted and modified by the programmer. This is particularly useful for developing graphical user interfaces.

Concepts of OOP:

  • Objects
  • Classes
  • Data Abstraction and Encapsulation
  • Inheritance
  • Polymorphism

Objects

Objects are the basic run-time entities in an object-oriented system. Programming problem is analyzed in terms of objects and nature of communication between them. When a program is executed, objects interact with each other by sending messages. Different objects can also interact with each other without knowing the details of their data or code.

Classes

A class is a collection of objects of similar type. Once a class is defined, any number of objects can be created which belong to that class.

Data Abstraction and Encapsulation

Abstraction refers to the act of representing essential features without including the background details or explanations. Classes use the concept of abstraction and are defined as a list of abstract attributes. Storing data and functions in a single unit (class) is encapsulation. Data cannot be accessible to the outside world and only those functions which are stored in the class can access it.

Inheritance

Inheritance is the process by which objects can acquire the properties of objects of other class. In OOP, inheritance provides reusability, like, adding additional features to an existing class without modifying it. This is achieved by deriving a new class from the existing one. The new class will have combined features of both the classes.

Polymorphism

Polymorphism means the ability to take more than one form. An operation may exhibit different behaviors in different instances. The behavior depends on the data types used in the operation. Polymorphism is extensively used in implementing Inheritance.

Discussion

Moritz: I started programming in Perl and then some C. I made heavy use of multi-dimensional arrays to store large amounts of data. Then when I came to Python, PHP and Java I really learned to like the OOP approach to programming, making it more easily to handle data, not having to remember the structure of multidimensional arrays. Now, I just had to think what disadvantages OOP has. What do you think?

Let's distinguish two sorts of disadvantages:

  • OO is often provided through such imperfect vehicles as C++ and Java [discuss their defects]; and
  • OO is inapplicable because [explain many mismatches].

Peter Newman 24 January 2005: To me, the main problem with OO is that some implementations (eg; C++) make it way too complicated and obscure. For example, a description of OO in C++ will be loaded with terms like:-

  • classes
  • instances
  • nodes
  • inheritance
  • operator overloading
  • type safety
  • encapsulation
  • polymorphism
  • dynamic binding
  • constructors/destructors

What the hell is all that crap? And who cares? I just wanna write a program.

But there are simple OO like systems that to me work well:-

  • Tk for example:-
 label .mLabel
 .myLabel -text "Hello, World!"
where .myLabel, once created can be thought of as an object with ID .myLabel and property -text, etc. And:-

  • Javascript, which has a simple, useful and easy to understand syntax.

It seems to me that there are some important and useful things in OO. But exactly what those useful essentials are, I'm not sure. Tk and Javascript are useful (and used by lots of programmers) - because they obviously use the useful bits. Complicated systems like C++ seem to be rejected by many programmers - in my opinion because they drown the useful bits in a sea of what seems to me to be irrelevant fluff.

LV actually, C++ is used by many. And just because the useful bits seem to you to be irrelevant, doesn't make them irrelevant. However, note that I am no C++ fan.

Larry Smith In all honesty and speaking as someone who used C++ professionally for years -- C++ has passed the point of usefulness. I have heard people say that Ada was a language designed by a committee to prove that not all programming languages can be implemented, it is overly complex and difficult to understand, yet it is a model of simplicity and elegance compared to C++, which in its latest incarnation also demonstrates the pristine and readable qualities of APL. Frankly, C++ should have its head cut off and its head and body buried at a crossroad with garlic in its mouth and a stake though its heart. That probably won't kill it, but it should slow it down somewhat. Nowadays I would never start a project in C++ that I ever thought I'd need to finish. I'd rather do it in something simpler and more portable. Like assembler.

But it would be useful to identify exactly what the useful bits of OO were. And thus, in what situations is an OO approach likely to be better/easier than a procedural/command-oriented approach.

Artur Trzewik Tk is not object oriented

Many Tcl-ers think that the main characteristic of object orientation is only the parameter order in commands call. So they show such examples
# procedural
close $filehandle
# object oriented
$filehandle close

Object orientation is much more [missing word?] (see http://en.wikipedia.org/wiki/Object-oriented_programming). At the very least, object oriented languages need inheritance, polymorphism, encapsulation, abstraction and objects.

Larry Smith Tk is object-oriented. Tcl is not, though it could easily have been if JO had thought about it when he defined the core language. He did not, he was writing an interpreter that could be easily bolted into programs to provide extension scriptability, and Tcl is still one of the most useful tools for that ever written. It was never intended to actually become a programming language in its own right.

SYStems I strongly disagree, first learning Tcl helped me understand OOP better, in my opinion the most important aspects of OOP (a paradigm in which I strongly believe) are

  • The abstraction that everything is an Object (1)
  • And that objects serve two purposes; they know things and do things (2)

And Tcl probably beats any language on aspect no. 1 and can do aspect no. 2. You see in Tcl everything is a command, there is not any other statement, OOP suggest that work is done by sending messages to objects, objects that knows things and can do things, parameter to methods are other objects, anyway, in any OOP this is not entirely true, as any OOP have syntax to create objects or do special things, Tcl doesn't even have that, every statement is a command, and all command play by the same rules, no one is special, I believe this make the abstraction stronger

As for the knowing and doing, aspect, well, set knows stuff, and puts do stuff, actually puts also knows many things, so its not really about the knowing, its about learning, as a system executes, some object are able to learn stuff, and modifie it are work gets done on them, so as a principle Tcl have commands like set which learn stuff, the nasty bit is that proc, the most popular command for creating command dynamically doesn't create such command. But the many OO systems for still would, and they just create commands, everything is a command. So it doesn't really matter how many OO systems Tcl have, since the only interface Tcl knows, is the command, you see everything is a command!

LV And Tk's widgets have encapsulation and objects. Polymorphism is not always an accepted OO attribute requirement - the Java folk have argued over that aspect quite some years.

The main difference between procedural and object oriented programming is that the functional programmer try to split function and data (data structures). But object oriented programmers think in objects that hold data and functions (methods) together in one structure.

And, in fact, that's what Tk's widgets do.

Because Tcl is string based it also has a kind of polymorphism. For example Tk:
$button configure -text "Text"
$label configure -text "Text"

It looks like object oriented but indeed Tk does not supports inheritance (anyways Tix - try it). So button and label have no parent class and you can not derive a new widget type directly from button.

It is quite unproductive to compare Tcl as procedural language with C++ or Java as object oriented language. Because actually you will compare dynamic and static typed languages. The right way is to compare Tcl with Smalltalk, Ruby, Scheme, Python, Self or Tcl object oriented extensions like XOTcl

Quite impressive is the effort to compare Tcl's low level API for C and the Java Tcl-Interpreter. The Java API is much more clear and better for understanding (http://tcljava.sourceforge.net/docs/TclJavaLib/contents.htm) . There is for example one polymorph method Interpreter.setResult() that accepts int, String, double and TclObject.

Of course one can write programs without object orientation and you can write bad object oriented programs (Antipattern: Blob, Spagheti Code, Ghost class) especially if one comes from procedural programming background.

Another interesting thing is that many systems written in procedural languages build their own object oriented systems for structure programs; for example Tix in Tcl or GTK in C. So object orientation is not only the languages but the way that one structures programs or thinks about programming (mental work). Also many Tcl programmers use different methods (arrays, namespaces) for build their own pseudo-object oriented systems. I said "pseudo" because they often do not support all the object oriented characteristics and are "ad hoc" solutions for one application (reinvent the wheel). That makes it hard for analysis for another programmer.

Lars H: Two quick remarks. Perhaps someone wants to try refuting them?

  1. A common (but this is biased, as I base this mostly on programs I've encountered as a scientist) reason programmers choose e.g. C++ instead of C seems to be not that they want OOP, but that they want some way of structuring their data. In most cases, they could just as easily have obtained their goal by using Tcl library functions for lists!
  2. OOP (to me as a non-practitioner) seems to work very well for unary operations (methods affect or query the state of one object: their own), but what about binary operations? If some operation requires the data stored in two objects, then it seems the methods for one will need to peek into the other. Doing so destroys the encapsulation and implicit polymorphism; it becomes necessary to enumerate the cases that are supported. Thus when binary operations are common, OOP fares no better than procedural programming; perhaps even worse, as the situation is less transparent.

Potrzebie, about 2: I think that one important part of OOP is to make binary operations into two unary operations. A method should never have to access the variables of another type of object. You hide the data behind methods. When an oven gets a pizza put into it, it shouldn't set the baked variable of the pizza to 1, but rather call the setTemperature method of the pizza, and that method in the pizza class makes the pizza baked. Then you can put other stuff into the oven as long as they have a setTemperature method, and with inheritance, you don't need to write a separate method for all classes. You can inherit e.g. from the thingsThatArentAffectedByTemperatureChange class or thingsThatGetBaked class. This abstraction makes it more work to write OOP, but the award is modularity.

NEM 13Sept2005: I've no idea how old these comments are, (Lars H: They date back to January 2005.) but I thought I'd reply to them anyway. With regards to point 1, I actually think that people use C++ as a way of structuring code rather than data. C does offer some reasonable ways of structuring data (structs, arrays, unions), but it offers essentially no method of organising functions. Point 2 is really dependent on the OO system being used, e.g. CLOS and some other systems use multi-methods that can handle those sorts of operations. Honestly, though, I don't see it as much of a problem.

These discussions about OOP as a whole are less than pointless. "Object oriented programming" is a cluster concept, which means a whole bunch of different things to different people. If we want a productive discussion, let's instead discuss individual features that have been associated with different OO models, and see which ones make sense for Tcl programmers. I think the most important concepts associated with OOP (by no means exclusively) are:

  • Ad-hoc polymorphism: essentially being able to specialise an operation by type.
  • Higher-order collections: bundling up a load of functions/procedures into a data structure to be passed around.
  • Message-passing components: structuring a program as a collection of interpreters that respond to messages.

You can argue about these definitions, but I think these are the core useful properties that OO systems tend to have. Tcl already supports these properties to a greater or lesser degree. Ad-hoc polymorphism is supported reasonably well by namespace ensembles, which are really not too different from objects. Namespaces can also be seen as higher-order data structures, although I'd prefer to use lambda terms and dicts for this. Ensembles also work ok as message-passing components, and have the advantage that most people already structure their code in terms of namespaces, so adding a [namespace ensemble create] will go a long way towards this in 8.5. Structuring code as components that respond to messages is nice in that it scales up -- those same messages can easily be sent over a network, for instance.

Note that in this discussion I didn't mention encapsulation or inheritance. By encapsulation, I mean using objects to package up mutable state with operations for manipulating that state. I personally find that it is better to try and avoid using mutable state at all, if possible, and so encapsulation is less of a concern (although still important at times). Inheritance is a much-abused element of OO, and one that I think I could also live without.

Overall, OO can be a useful way of structuring parts of a program. Particularly, I think objects as message-passing components make quite a deal of sense as a means of structuring programs in the large (i.e., major components/packages). I think higher-order functions and data structures with value semantics make better sense for programming in the small. A lot of good work has gone into improving Tcl's namespace mechanisms in 8.5, and I think this is heading in the right direction. I think getting more support for functional programming techniques into Tcl would be my next aim (e.g. lambdas, maybe more support for tail-recursion and higher-order functions).

CMcC: Advantages: good at representing objects. Disadvantages: not good at representing non-objects. (Next week's topic: advantages and disadvantages of hammers)

KPV: Personally I find oops code can get very hard to read, even well written code. The problem is inheritance and polymorphism.

The problem with inheritance is that if you want to figure out what a given method does, you have to search up the class hierarchy until you find its definition. In a way, inheritance is worse than goto--at least with goto the destination is somewhere in your function but with inheritance it could be in any number of files. The problem with polymorphism means that simply finding a function with the right name is not sufficient, you have to also look at the parameters. Trying to read code without a good class browser is almost impossible. It IS impossible once you get into virtual functions where the decision of which function gets called is only determined at runtime.

For example, suppose you're trying to figure out the following line of code obj.Write(a);. Which function is being called? Well, if you're lucky and you know what type obj is then you probably only have about 10 different versions of Write() to pick from depending upon what a is. If you're unlucky and obj can be of several types, then you got a lot of work cut out for you.

Two other oops features that can get really hard to read are operator overloading (fortunately it's rarely used), and class properties that look like simple variable assignment but are really complex function calls.

My very first exposure to oops programming was as an intern at Sun Labs (just downstairs from the tcl team) where my job was to instrument C++ kernel code to determine where time was being spent. Kernel programming is hard enough, but the real bear was just trying to read the well-written but deeply inherited code.

Artur Trzewik About reading OO code

Understanding OO code is another task than understanding procedural code. I think it is one of the biggest problems for OO beginners.

OO allows one to think abstractly. (to disregard unnecessary details) If you see obj.Write(a) you must only know that the obj is written. How the method works is not interesting in this moment. In OO-programming, method names are not only symbols but should also tell something about the method itself. The best method names are given by Smalltalk programmers. I suppose a Smalltalker will be write "writeToStdout" to be more precise.

You will need also good tools for browsing OO-code. Eclipse, Smalltalk IDEs, and XOTclIDE have special views to figure out the class hierarchy, method callers and senders. They support discovering non-linear program flow.

Understanding OO-Systems means, first of all, to understand the abstractions of classes and their interfaces. At that level you do not have to delve into every method call.

Indeed some facts may be better figured out at the runtime. Therefore debuggers in OO-Systems are normal and important tools not only for debugging but also for discovering the system. Smalltalk programmer will say: "Let Smalltalk tell you".

ET - Finding this page was like discovering that I really did see the naked emperor. With so much evangelical fervor it's difficult to trust your own mind. KPV - well done.

Anyhow, I think that objects, if designed very well, can be very useful to the object's users. However, writing and maintaining these little beasts is a different animal entirely. And code alone is rarely enough to make an object reusable. A good manual entry and tutorial is a must. I would think that a truly reusable object is 10x more costly to write than a stand alone object.

I think the worst aspect is that so much happens indirectly. It's been my experience that indirectness at more than one level deep is almost impossible for a normal mind to follow.

Also, the temptation to use all the tricks in the bag make something like C++ a nightmare. The best example is the standard template library. To be totally orthogonal (meaning works with everything) some of this code is the most obscure stuff I've every seen. And slow as a dog too. I never could create a list of non-primitive objects, and I read a book on the subject. I gave up and crafted my own list code.

WHD -- When it comes to objects, I find that encapsulation is almost always good; abstraction is almost always good; polymorphism is almost always good; inheritance is almost always confusing, and isn't needed nearly as often as people tend to think, except in C++ where it's the only way to get polymorphism.

DKF: Agreed. Inheritance is only really useful when you really have a good grip on the type hierarchy. But Tcl's a typeless language...

SYStems I would like to elaborate something, I do agree that Tcl is typless in the sense that it doesn't check on types, and have no recognition of the concept called types, I think (thanks to NEM) it's important to separate Tcl the language from Tcl the command collection (tcl libraries), Tcl the language only parses scripts and commands, the command do all the work, most commands if not all recognize types, it just that Tcl the language won't help them, as far as Tcl care all input for commands are strings and all output (within the script, i.e returned values) is also a string, it's the command that will get picky about what the strings say or look like, a string may have to look like a number, be a var name recognized by an available set command (is this case I would prefer to call it service not command). But then one could argue that Tcl would complain if the first word (or more, NEM kinda hinted to me that Tcls new feature ensemble allow commands to be more than one Tcl word) is not a command name, which can be argued to be a type!

Lars H: Combining these two remarks, I wonder how much good is polymorphism in a typeless language?

WHD: Polymorphism is usually very very good. It's just that in a language like Tcl it's trivial to get, so you don't think of it as polymorphism.

Lars H: Hmm... So polymorphism is not an advantage of OOP over procedural programming in Tcl, then. Nice to have that sorted out.

NEM: Yes and no. Depends on what you think polymorphism is. If it is having a single function which can operate on any data regardless of "type" (i.e. the function makes no assumptions about the format of what it is passed) then Tcl is good at this (for instance, it is trivial to define a polymorphic map or filter in Tcl). However, what OO allows is what is sometimes referred to as ad-hoc polymorphism -- having different versions of an identically named function to operate on different types of arguments. As Tcl has no notion of type that could be used to choose the appropriate function, then OO mechanisms provide a means of achieving this via dynamic dispatch. i.e. you ask one of the arguments (usually the first) which version to go with. The argument(s) must of course "know" which version to choose, and this is often done by making them into commands (+namespace). (Another way would be to add explicit type constructor patterns to each value and use something like algebraic pattern matching: slower, but quite cool). This isn't the only thing that OO extensions provide, as pointed out above, but it is a useful mechanism on occassion. Ad-hoc polymorphism is also related to sub-typing, and there is a connection with ensembles, as TOOT demonstrates.

VK I once saw quite interesting and funny related message from Steve Fink on p5p: ... But it is one of the things that bothers me the most about OO code. A "real OO programmer", when given the task of implementing a heart, would take a real heart and coat a meter thick layer of plaster around it, then drill holes down to the aorta and stick tubes in them. He would tell you how great it is that you can replace the buried heart with a vacuum cleaner or a rooster without changing anything else. When you complain about the tubes sticking out of your chest and the wheelbarrow you need to push your new heart around in, he'd quickly point out that the wheelbarrow is really an advantage because you can haul around all kinds of other great things at almost no added burden.

CL holds the prejudice that Aspect Oriented Programming, rather than being an advance, is best viewed merely as a remedy to some of OO's faults.

Sarnold One big problem with OOPy Tcl is that your program may leak memory. Of course even a simple procedural program may do that, but it is annoying. What tool could help OO programs not to leak memory?

Unfortunately, making objects local variables (i.e. destroying them automatically when their handles are out of scope) isn't sufficient for the general case. (see BOOP for an example of local handles)

2005-09-12 I have worked on a project in which I first failed to operate without OO. I couldn't handle some of my data into arrays and with namespaces. So I decided to move to snit my buggy bad-designed app. But after having done quite the job with snit, I decided that I had to come back to non-OO style and did the job. I feel now comfortable with lists and arrays. I don't know if I will have to do OO with Tcl in the future, but I would prefer not to do so, even if I admit snit, Xotcl and [megawidgets] are powerful!

[Satish V Itagi, RWF India] Objects are of reference type and occupy only 4 bytes space in stack that points to huge data referred from memory heap and thus contribute to stop stack overflow. Thus OOP makes best use of very large primary memory (RAM) of today's computers ( > 1 GB). Execution of objects will be faster as they make best use multitasking and multiprogramming capabilities of Operating Systems like Windows. Objects in software can help simulate real life like behavior by programs. It makes your conceptualise business logic in clear terms and code them irrespective of that part of code that interacts with user. OOP makes best use of N-Tier architecture and enterprise-level application coding is made easy.

SEH -- This article: Scripting Languages as a Step in Evolution of Very high Level Languages nicely sums up the issues of scripting vs. object-oriented approaches IMO. I think it highlights the chief weakness of the OO approach, namely: "Premature abstraction of a problem into classes is similar in its long term destructive effects to premature optimization."

There are other quotable gems, like a restatement of Greenspun's Tenth Law: "any sufficiently complicated and large C-based programming project usually reimplements 50 to 80% of TCL interpreter."