Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.

The right place for objects

Posted by ApochPiQ, 19 April 2006 · 185 views

During my usual bouts of procrastination, I dug back up Paul Graham's essays, thinking that I might find some useful stuff in there since my Lisp conversion. Specifically, I started reading Why Arc Isn't Especially Object Oriented, looking to compare notes with Paul's work on the Arc language (a Lisp dialect, for those not familiar with it) with my own dabblings in the fledgling Epoch project.

I've read a lot of "OO considered harmful" type stuff in the past. I guess, like Lisp, it was one of those things that I shrugged off as crazy talk - because I didn't understand it, and because the writer didn't seem to explain it. Actually, I need to qualify that a bit, with some history of my own opinions on the matter of objects.

When I first started using objects extensively (around the time I got ahold of VB5 with its "new" Classes support) I thought objects were kind of handy for certain kinds of data modelling, but really didn't see what all the fuss was about writing entire programs based on objects interacting. As far as I was concerned, the Logical Thing To Do was to use objects to model, well, object-like stuff, and use good-ol' procedural style code to model logic and high-level operations involving objects.

However, I was very much a novice and unaware programmer at the time, so I figured there was a good chance I didn't know what I was talking about. While the attitude was good, I made a terrible mistake, which I now (in retrospect) kind of regret - I moved off into Java land. A lot of people were saying that Java was gonna be Really Big, and you'd better learn it if you want to have relevant skills in the real world.

I tried - really, really tried - for about a month to like Java. It had some of the niceness of VB's "get it done and screw the details" philosophy, and at least by comparison to C was kind of handy in that regard. But one thing just pissed me off about it: Java seemed to have some kind of weird, almost erotic fixation on objects. I ditched Java permanently, which (frankly) I think was a good move on my part. I've hated it ever since.

At that point, I'd been doing parallel work in VB and C for several years. I loved VB for doing "GUI stuff" and maybe the occasional rapid throwaway utility or whatever. For anything heavy-duty, I used C. (Actually, what I used was C++'s flavor of C-style programming - it was trivially isomorphic to C code, but exploited litte gimmicks like omitting struct everywhere. It wasn't legal C in the sense that you could compile it in a C compiler straight, but it was for all intents and purposes C code.) It worked great - I had a potent tag-team of languages that could solve most of my problems. I could even write MS-DOS 6 compatible batch files if I needed to.

However, I felt like I had some kind of gap in my knowledge still, because I didn't quite get this whole "objects" thing. I was still a student looking for a teacher, and sadly, at that point in time, the easiest teacher to find was the OO fanatic camp. I wish I could have found a different teacher instead (like, say, Lisp). But in any case, what happened happened - and I decided to try to learn "real C++" in order to get a handle on this objects stuff.

In the course of learning C++'s flavor of OO, I realized that OO was a vacuous (or, at best, nebulous) term. Every single language had a different notion of how OO should work, and nobody agreed that anyone else's was better (except maybe Smalltalk's). Nobody seemed to agree what OO really was - it just seemed to involve a lot of objects.

Even more unfortunate for me, I chose MFC as my entry point to the C++ land of OO. It permanently warped my opinion of the entire objects notion, although eventually I think the experience will prove beneficial, all things considered - if for nothing else than the fact that it has deeply broadened my experience. Call it an eye-opener, I guess.

I dabbled in this land for a while, doing a few little projects of my own, but never really liking it. I decided that my real problem was that I didn't have a good, hard problem to solve; I was just tooling around, and didn't have room to get a real solid feel for how Objects are supposed to be.

After a couple years of dabbling, I started the Day Job From Hell. (As a matter of fact, I'd "dabbled" a bit by writing a prototype version of what eventually became the product I worked on during that job. But that's another tale.) I figured it was my lucky break: the main thing I was to work on was - you guessed it - a C++, OO-heavy, MFC-encumbered mess. Of course, at that point, it was like some kind of vision from heaven; finally, I could get some clarity on all this OO stuff!

I wrestled, hard, with that project at first. I tried - really tried - to do everything in OO style, like Java. Except at every turn, I had this deep revulsion; I felt like I was going back into Java-land. Java was supposedly this great, highly OO language, but I hated it. Something wasn't adding up in my head.

Around that time I picked up a copy of The Pragmatic Programmer. Finally, things started to click, and it was the beginning of the fastest period of acceleration in my personal understanding of programming that has happened to date (in fact, I think I'm still on that upward trend, and possibly still accelerating a bit). Instead of trying to pursue this ghost, this OO, this object-worshiping nothingness that never seemed to materialize, I started using Pragmatic principles instead.

I rewrote the program, almost 100% from scratch, against very heavy protests from the management. I firmly believe that I made the right decision. Even now, I think the management is starting to grudgingly realize that it was the right thing to do; they've had a far more stable and reliable product even since I quit than they did when it was being actively maintained by the old developer.

After I got done rewriting the entire program, I noticed something funny: it deeply - and I mean very very deeply - resembled what I used to do in VB, all those years ago, when I first got my hands on "classes." Maybe a third of the "stuff" in the program was thought of as an object. The rest was basically procedural code, except with some of the nice trappings of C++ (STL, RAII, and such) to help smooth over the ugliness of doing applications in raw C.

For a while, I felt vaguely guilty about this. I felt like I'd betrayed my quest to Learn Objects, like I'd missed the mark somehow. I thought I had failed to understand the Grand Truth of OO, and that I was committing a deep sin by writing in the same style that I used to write VB code. I mean, hell, everyone knows VB is the worst language ever, right?

So I thought long and hard about this, in the back of my head, while other thoughts filled up my conscious effort. I realize now just how long this has been rolling around in my brain, but has only now attained clarity. The more I thought about it, the more I realized that I couldn't identify a "crime" in that code. Yeah, it wasn't Java-style OO, but it was exceptionally good code, compared to my previous stuff. Maybe it missed the mark of "the grand truth of OO" but it definitely lined up with what Pragmatic Programmer had to say. It wasn't object-laden, but I was still proud of that architecture.

I've been doing a lot of reading to back up my efforts on this Epoch thing. As a result, I've been finding out a lot about the real situation of OO. It seems that a lot of people have arrived at this conclusion long before me; and a lot of people seem to despise OO, at least in the sense of Java's "use objects or die" approach.

Now, though, I see a new perspective. I don't think the problem here is really objects per se - I think it's object orientation. And the more I read, the more I think that this is what all the anti-OO people have really been driving at all along; I just wasn't smart enough to understand it yet.

My problem was premature rejection. I read this stuff that, to me, seemed to be saying "objects are stupid! Use Lisp instead." And this bothered me. I had all kinds of cases where objects were exceptionally good representations of certain classes of problems. Today, I'd say that objects are probably the best method (for now at least) of modelling systems that are dominated by automata. A simulation game like X3 would be a damned nightmare to write without objects.

So, I would read these anti-OO discussions, and figure everyone out there was insane. I could see the benefits and power of objects plain as day, and these people seemed to be telling me that objects were, in fact, not useful. So I largely ignored the whole thing, assuming that once I found the Great Truth of OO, I'd be able to counter their arguments.

I did find the Great Truth of OO, but the truth isn't that the Emperor is also the Messiah. The truth is that the Emperor has had a catastrophic wardrobe malfunction.

Objects are awesome tools of abstraction. I think they should stick around, and here's what I think the term should mean:
  • An object has some state, also called attributes or properties.

  • An object knows how to do interesting things with its own state.

That's all. No more, no less. Encapsulation, implementation hiding, data hiding, all these things are good - but they are not inherent properties of objects, nor do objects hold a monopoly on those notions. In this sense, I think, objects are still very good tools.

Where we get into evil trouble is when we try to write all of our logic as objects. The presence of "manager" or "handler" objects is a tell-tale sign of this. Steve Yegge posted a humorous caricature of this kind of programming in Execution in the Kingdom of Nouns. I think, to a large degree, this kind of stuff is what "object-orientation" is all about: if you have code to write, find a way to cram it into an "object," a noun.

I think that we now have enough history (thanks to Java) to prove that this is a Bad Way To Do Things.

Inevitably, the question of objects is going to come up in the Epoch project. Up until now, I've been basically planning on declaring Epoch to support object-orientation. Now, though, I've changed my mind. Epoch will revile object-orientation. Epoch will spit upon it, deface it, shame it, and tell it to go back to Java land where it belongs, so that we can get work done in peace.

Epoch will have a new perspective. Well, I don't think the perspective itself is really all that new; I just don't think anyone has codified it before. I think a lot of people have become disillusioned with OO (if they were ever "illusioned" to begin with), and already have this perspective. But I've never seen a name for it, or even a really concise description of what it entails - just rhetoric about why OO is bad.

I've started thinking about it as "object awareness." Objects exist, and they're very useful tools in certain areas. As such, I think it's important to allow for them. Epoch will definitely "believe in" objects in that it won't be object-agnostic, the way, say, BASIC or C is. Objects themselves will be welcome citizens. Heck, at this point, I'm moving in the direction of modelling Epoch's language within itself, using self-referential, recursive objects.

Where the line is drawn, though, is in idolizing objects. Some things just shouldn't be objects. I think the term "object oriented" carries a sort of connotation of bending everything in the direction of objects. Objects aren't merely first-class citizens; they're aristocrats, maybe even dictators. That, I think, is the essence of all that is wrong with OO.

Here's to Object-Aware Programming. May our code be more concise, our abstractions more clean, and our modules less cluttered with FooManagers.

Muddled lexicon.

Python is object oriented, yet doesn't require that all your code be expressed as an explicit object attribute or operation - even though everything is an object in Python.

>>> def f():

... pass
>>> f
<function f at 0x009D7570>
>>> type(f)
<type 'function'>
>>> type
<type 'type'>
>>> dir(f)
['__call__', '__class__', '__delattr__', ... , 'func_code', ... 'func_name']
>>> f.func_name
>>> f.func_name = 'g'
>>> f
<function g at 0x009D7570>
>>> f.func_code
<code object f at 0x009D74A0, file "<stdin>", line 1>

As you can see, even a "bare" function is an object - an instance of the function type - with a slew of accessible and modifiable properties, each also an object, and the availability of these attributes makes the language that much more powerful. Access to the properties is precisely what enables metaclass hacking without deep black magic (as would be required in C++), whatever its actual uses in production code.

There's nothing wrong with object oriented languages, so long as their interpretation of object orientation does not limit programmer expressivity. Don't swing from one extreme (Java) to another (the direction in which you seem to be taking Epoch, whatever that is).
I'd call Python object-aware, but not particularly object-oriented. Ditto for Ruby. OCaml (Objective Caml) is a nicely object-aware language without being object-obsessed (largely as a byproduct of being a functional language at its roots). C++ is technically object-aware but most people seem to treat it with object-obsessed designs instead of exploiting the language's multiparadigm capacities.

The fact that first-class language entities can be treated as objects in both languages has absolutely no bearing on how the language encourages/forces programmers to model their own code. Java gives you no choice: you model your code as an object. And yet Java doesn't even have first-class objects for most of its intrinsics... sloppy. Classic case of object-obsession: objects become kings when they should merely be one of many useful tools in the toolbox.

Yes, a fair bit of the problem is that the terminology has no defined meaning, which I commented on in the entry itself. But in my mind the real evil is the compulsive behavior that leads to modelling everything possible as classes, which is just not a good idea in the long term.
I'm relatively new to object. Not programming... I've done that for a while, but haven't stuck to anything for a long time. But I understand your feelings about object oriented programming. To me, it seems that objects have useful capabilities:
an apple is best expressed as an apple. It is red, it is big, it is decaying, it is ripening. Objects fulfil that with members and methods. I tired java once (not porperly, just a hello world tutorial or two), but something about OOP is very odd. You can't "group" things, except if you find some sort of way that they all are similar.

I've done some PHP scripting, and I really liked the procedural approach (yes, objects exist in PHP, but my book had one chapter which was shared with something else that I forgot). So, it seems that a programming style for me has not been made yet, or at least not been set in stone. The Pragmatic Programmer may be a nessessary purchase for me.
Isn't it just a mather of preference?

There is a lazy group of people that enjoys the, perhaps overcomplex, object-obsessed types of highlevel systems that once done take care of themselves.. And there is a practical group that enjoys the, perhaps less dynamic, object-aware types of (sometimes hardcoded) systems that aren't too spacy, if I may.

Both groups agree that in programming there must be some sort of use of objects, and the first clearly agrees more.

I agree with Oluseyi that you shouldn't project a thick wall between the different styles, and I believe that it all comes down to what the programmer decides and prefers.
I also agree with ApochPiQ that it's wrong that an object-obsessed way of programming is promoted and assigned to specific languages but that might have been the hype and revolution (around objects), that hopefully has turned into peacefully rethinking the situation and the needs.
I am late to this thread but I really enjoyed this article.

I am actually a C++ programmer who left C++ to code in straight C. I am not sure if this is typical these days, but it eventually happened. In the C++ world I worked (had to work?) with MFC. And the STL, which I still happen to like.

Nowadays I believe in separating code and data as much as possible though. I have my structs in C. Yes, my apples are red, big, decaying, too. But they don't know by themself how to add themselves to the AppleManager, or have a reference to the NewtonPhysics singleton thingy to call its Impact(Apple*) method when it hits the ground :)

Anyway I am not sure what I'm trying to say. The pragmatic programmer is a great book though, and it did change the ways of how I approach problems, regardless of language.

Regarding your apple and applemanager description, an apple shouldn't know how to add itself to the manager. The manager is only aware of the apple.
I am actually a C++ programmer who left C++ to code in straight C. I am not sure if this is typical these days, but it eventually happened. In the C++ world I worked (had to work?) with MFC. And the STL, which I still happen to like.

It's important to realize that there isn't anything you can do in C++ that you can't do in C. C++ didn't invent OOP; it just added syntatic sugar to make OOP easier. I use 'objects' in C all the time. For a great example of Object Orientation in C, just check out the 'FILE' type. Or just about anything in the win32 api. (Heres a hint: A 'Handle' is an object!)

November 2014 »

23242526 27 2829

Recent Comments