Advantages of OOPObject-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.
- Data Abstraction and Encapsulation
DiscussionMoritz: 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:-
- operator overloading
- type safety
- dynamic binding
- 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:-
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 orientedMany 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 closeObject 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)
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 XOTclQuite 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?
- 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!
- 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.
- 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.
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 codeUnderstanding 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 seperate 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."