[tweet https://twitter.com/Swizec/status/196543519446409216]

The other week I was working on my compilers homework – the semantic analysis part is an object-oriented nightmare. Something called the visitor pattern to traverse trees and do weird stuff.

It made me want to curl up in a fetal position in the corner, rocking back and forth in a padded room, while mumbling tongues at myself. As River Tam would say before running out of the room in panic “Too crowded!”

What OOP feels like

Schizophrenic?

Schizophrenic?

In object-oriented programming everything gets muddled together. Functions are bundled with data, everything is codependent and there’s no telling what a function might do when you call it.

And that’s assuming there are no side-effects outside the object monad. Otherwise, who knows, the world might explode!

This creates software that is impossible to understand. I used to think I could, but after a few months of functional-style programming I realized that I simply don’t have the brainpower to understand object oriented code. It’s too messy.

When you put singletons into the picture and objects using other objects it all just gets … let me give you a simple example:

foo: object {
   i: private integer = 0;
   add: function (a:integer) {
      i += a;
      return i;
   }
}
 
/* lots of code happens here, foo has been passed around, things happened */
/* foo is not a singleton though, just used a lot */
 
a:integer = foo.add(5);
 
// What is the value of a?

Answering this simple question requires knowing everything. The whole execution history of foo. The whole codebase. You name it, you have to keep it in your head.

Oh and did I mention class bar? It depends on foo for a lot of its stuff. Oh yeah, they got into a little friends with benefits situation last year. It all gets pretty interesting. I think bar cheated on foo with baz once, though. There’s no telling how foo might react to that!

Functional programming

fp, by okeef creations

fp, by okeef creations

With a lot of gentle poking and prodding from @sbelak, I started learning functional programming about two years ago.

I was promised easy scalability, working with multiple processors without cost, expressive code, things that Just Work ™ and software with less bugs that is easier to maintain and shorter/quicker to write.

I may not have gotten all that, but I did get a whole new way of thinking about my craft. An easier way to understand.

At first functional programming felt like performing a lobotomy on myself by sticking hot pokers into my feet. Are you sure I don’t need loops? But I do need variables don’t I? At least a bit of mutability? Really? I don’t? This is some sort of hazing ritual isn’t it, any moment now you’re all going to jump up, shout “surprise” and start laughing at me.

 But I kept at it. And even though my code looked horrible, I fell in love.

The first attraction of functinal style code was writing python functions that just pass data around. No storing in intermediate variables, just passing one function’s result directly into the arguments of the next function in the chain.

Because who cares about reading intermediate steps? All I care for is that this chunk of code creates X. Not that it first does Y, then Z, then pulls in A and B and combines them into X.

Sure, you could define a function called X that combines Y, Z, A and B, but why create a new function for something that only gets called once? Much better to just do something like X = A+B(Y(Z)) isn’t it?

A waterfall of data

Plitvice falls

Plitvice falls

The way I think about code now is a waterfall of data.

You have data and every function in the chain is a ledge. The data stops falling, changes course a bit, perhaps even changes some properties, and falls onward to the next function.

In the end you have a pool. This is where your data ends up after falling through many functions and being changed. But then it flows onward to the next function, or wherever you might need it.

You might say this is really procedural programming, but I don’t like side-effects, imperative bits of code and so on. It’s still functional programming, but this is how my brain understands code. Your mileage might vary.

Fin

Whatever way you think about your code, whatever way you visualise execution in your head … hat’s off to you, if you can handle the inherent complexity of object-oriented programming. You are a better man than I am.

I think you should give “this functional programming fad” a try anyway. You  might like it ;)

Enhanced by Zemanta
  • MoreMoschops

    The whole point of OOP is that it makes it easier for you to think about the problem and easier to think about how to solve it. If you end up just jamming everything into a big ball of mud you’ve missed the whole point of OOP (and indeed, programming).

  • Guest

    I agree with your general sentiment, however I believe you have not understood OOP. The code you’ve posted as an example is procedural and not really object-oriented: Your object is actually a data-structure. Read on the ‘tell don’t ask principle’ and you will understand!

  • Tim Case

    I think you are on the right track to understanding OOP, I once had the exact same difficulties with it, and the first step I think is to really get frustrated with it.  The second step is to recognize that the thinking that got you to where you are with procedural and functional programming will not contribute to you understanding OOP, in fact the more you think in terms of a waterfall of data the more you will continue having difficulty with object oriented thinking.  Object oriented thinking is about behaviors of objects, it’s about an ecosystem of actors passing messages to one another.  With OOP you are less inclined to try and think through all the interactions that the objects can possibly have with one another because the permutations of interactions becomes exhausting quite quickly and this is why the world seems like it might explode.  Here’s an analogy I’ve come up with that helps me keep procedural vs OOP thinking separated.  Suppose I have a puppet, the kind with strings on each hand and foot where I can stand above the puppet and by pulling the strings I can make it move exactly in the ways that I want.  The puppet is completely under my control, and I have no trouble understanding why it moves the way it does because I’m standing above it controlling it’s movements.  To me this is what procedural programming feels like.  Now contrast this with a robot.  Suppose I create a robot and I tell it to walk without stopping and should it reach a wall or a barrier that it can’t pass then I want it to turn 90 degrees and walk in that direction and to keep doing this until it’s no longer blocked by a wall.  If I turned the robot on and sent it on it’s way it would be very difficult for me to predict where it would end up given a certain amount of time, but if you asked me where did the robot go, I could answer…  Well it walked until it hit a barrier and then it turned 90 degrees and kept going…  Okay but did it end up 5 meters from start? or 10 meters from start? or 15 meters from start?  I don’t know, it would be too complex for me to try and and calculate that in my head so I don’t even concern myself with it.  For me as an object oriented programmer it would be sufficient to know that the object performed consistent with the behaviors that I expect from it and wherever it ended up is where it should be, “it walked until it hit a barrier and then it turned 90 degrees and kept going… ”

    You’ll get it eventually, it’s a use the force type of thing.  The more you hang onto your procedural mindset the more it’s going to be difficult to understand OOP.  Think now in terms of behaviors, not data.  

  • William Payne

    I like OOP when I am the one writing the software, because I can think very naturally in terms of modelling the problem domain, but my opinion rapidly turns on it’s head when I need to read/debug some OOP software that somebody else has written (When I need to think about control flow and behavior).

    Writing good (readable) OOP problems is hard. Debugging them is even harder. Navigating then when armed with just the source code is harder still. (Diagrams please!)

    Whilst most individual objects and methods in OOP systems are small and easy to understand in isolation (this is a good thing), I find that the flow of execution and the behavior of the system in the large becomes very difficult and time-consuming to understand. It is as if the fundamental complexity of the problem has been shoveled around from the small scale to the large scale.

    To be fair, the same complaint probably applies to FP as much as to OOP; the tension driving this dialectic exists between the Functional Decomposition and the DRY principle on the one hand, and readability and narrative flow on the other. (Or the battle between reader and writer, to put it more colorfully)

  • ach

    This is a terrible post –  you obviously have very little understanding of the point and method of OOP. Imagine if I wrote an opposing article about Functional programming with only my limited knowledge of the field? It would appear needlessly complicated as well. OOP isn’t a programming syntax, it’s a way of thinking about a problem so that it abstracts the programming and helps to build a relevant model.

  • Samuel Hart

    Problem is that functional programming still have variables and mutability; it’s just disguised. Functional programming has as many glaring flaws as OOP.
    There was an article a while back about reaching “Programming enlightenment”. First you start with OOP which is the best way. Then you discover FP and it’s far better. Then a few years later you realise they’re both crap. No programming style, structure or language is better than any other, it’s YOU and how you use them that makes it work.

  • digler99

    My humble opinion says it takes a good 10 years to get “good” at C++ from scratch, maybe less if you already knew another language first. I got lucky (one way of looking at it) because my first C++ jobs weren’t OO C++, it was the watered-down “C with classes” crap. I didn’t know this at the time, then 3 years into it I had the epiphany and worked to learn all I could about *real* C++. This made it much easier for me, despite the fact that I was at first deceived.

    My opinion about OO is this: When you learn gradeschool English, they teach you all the rules: No starting sentences with “and”, no ending sentences in prepositions, always indent new paragraphs, no run-on / rambling sentences. Then in college, you pick up an epic novel, and its full of rule violations, yet you can’t use the 3rd grade rules to argue that classic novels are flawed, because according to most literary experts, they’re epics. They would probably argue that the *content* and *concepts* delivered by the novel are what you get, and it transcends the fact that some sentence might run way too long, or start with “and”.

    With my analogy, OO doesn’t break rules, in fact it has more of them. But what you’re doing with OO code is trying to express these higher-level concepts that sit one layer higher in thought, like 3D video, than the 2D code that’s sitting on the screen, the same way that novelists create something on top of the thousands of 2D words they lay down.

    Hope this helps, don’t give up.

  • http://lcf.name/ Alexander Steshenko

    It’s not OOP that bothers you. It’s “state” vs “no state”. And, of course, “no state” is always easier to understand, debug… you’re much less likely to make a mistake with “no state”.

    However the truth is people are more comfortable thinking in terms of state. Most people. I know, I know, the adepts of functional programming always say “it’s only natural to have functional reasoning about the world and when you write programs i.e. to express what you need to do through other things that need to be done”. But… if that was the case we would all be writing in Haskell now.

  • Pingback: A geek with a hat » Remember to feed your sysadmins

  • Rafael

    I used to love OOP but it’s too hard to know what exact design patter should be apply at a given moment and some time later class A too much interested on class B attributes, soo too many classes and you fuck with encapsulation (getter and setter aren’t encapsulation) and finally NullPointerException (or something like). FP sounds like heaven to me. It’s simple and pure and ease to know what’s happening, though, IMHO if it’s not a pure FP language like Haskell you’r not really doing FP as, of course, you can’t really trust the code isn’t changing anything.

  • Pingback: 我的大脑不能再处理面向对象了 - 博客 - 伯乐在线

  • Stuff

    Functional is hardly a fad, it’s been around and coming back, and I like it. I’m with Dykstra, OOP is a bad joke. It seems to be modeling for those who cannot think (or cannot be trusted to think). But set both aside for a moment. I’ve lately been writing a lot of chip level code, and it makes me think we miss the point in computing entirely. Write a few assembler routines and gain a fresh view of the whole mess.