Shifting The Paradigm To A Paradigm Shift Cliche

Spread the Love
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

When you write a story, you don’t just simply throw a bunch of nouns and verbs into a jumbled word salad and call it a story.  The same is true with computer programs.  You can’t just randomly mash data and functions together.  If you want people to understand your code, you need to adhere to a specific coding structure.  I’ll review three of the most popular programming paradigms in use today.

In the Beginning, God Created the Digital World ...

Back in the old-timey days when primitive programmers coded on cave walls, nouns and verbs were considered equals.  That is, both data and functions were first-class citizens.  Neither were thought of as better than the other.  Both had voting rights and could own land.

But, it was also common practice to keep them segregated.  This was for structural and security reasons.  Programmers felt that code integrity could be better maintained if mixing were minimized.  The only way nouns and verbs could interact was via the nouns getting passed in as arguments to verbs — i.e. verb( noun ).  Here’s an example:

run( dog )
{
    repeat
    {
        move_right_front_paw_forward( dog );
        move_left_hind_paw_forward( dog );
        move_left_front_paw_forward( dog );
        move_right_hind_paw_forward( dog );
    }
}

If you think about this setup for a moment, you’ll realize that this causes quite a few problems.  One headache is that every time a new data type is created, all the functions that will be interacting with it need to be updated as well.  Let’s say you’ve created a new animal, called cat.  Unlike dogs, when cats run, they like to bound across the ground by pushing both front paws forward first, then both hind paws, like so:

run( animal )
{
    if ( animal == dog )
    {
        repeat
        {
            move_right_front_paw_forward( dog );
            move_left_hind_paw_forward( dog );
            move_left_front_paw_forward( dog );
            move_right_hind_paw_forward( dog );
        }
    }
    else if ( animal == cat )
    {
        repeat
        {
            move_right_front_paw_forward( cat );
            move_left_front_paw_forward( cat );
            move_left_hind_paw_forward( cat );
            move_right_hind_paw_forward( cat );
        }
    }
}

Well, that doesn’t seem too bad.  But wait!  You’ve also created another animal called duck.  So now, you have to account for the fact that a duck has two legs with webbed feet instead of four legs with paws:

run( animal )
{
    if ( animal == dog )
    {
        repeat
        {
            move_right_front_paw_forward( dog );
            move_left_hind_paw_forward( dog );
            move_left_front_paw_forward( dog );
            move_right_hind_paw_forward( dog );
        }
    }
    else if ( animal == cat )
    {
        repeat
        {
            move_right_front_paw_forward( cat );
            move_left_front_paw_forward( cat );
            move_left_hind_paw_forward( cat );
            move_right_hind_paw_forward( cat );
        }
    }
    else if ( animal == duck )
    {
        repeat
        {
            waddle_right_webbed_foot( duck );
            waddle_left_webbed_foot( duck );
        }
    }
}

The more varied the data and functions are, the more complicated things get.  Adding new code to existing functions can introduce bugs and break things that previously worked.

“Excuse me, what now?  You’re telling me the data type employeeBenefits
just had a baby named 401k?!  Well, whoop-dee-damn-doo!  I’ve been working six days straight, and Sunday is supposed to be my day off.  But now I have to come in and update all those friggin’ functions just to get them to work with this stupid new variable!”

Another problem this paradigm creates is ambiguity.  For example, let’s look at the verb, chase(  ).

chase( dog, cat, mouse )

Which animal is doing the chasing, and which animal is being chased?  You can’t tell just by looking at the function header.  You’d have to crack open the function itself to find out.

So these cave-dwelling programmers would sit around the campfire, chewing on dinosaur meat and regaling each other with epic Homeric tales.  But because of this issue with ambiguity in primitive programming, they’d constantly get interrupted with questions like,

  • “Wait, who shot who in the heel with an arrow?”
  • “Who blinded the Cyclops?”
  • “What do you mean nobody blinded the Cyclops?  Then how’d he lose his eye?”
  • “Huh?  How can Odysseus be a nobody?  Isn’t he the protagonist?  Not to mention Penelope’s husband and Telemachus’s father — so I’d say he’s definitely a somebody to some somebodies!”
  • “I’m confused.  Agamemnon’s face launched a thousand ships?  How can that be?  His nickname is ‘buttface.’  Were the ships sailing away from him?  That would make a lot more sense.”

... And Adam Named All The Animals ...

Frustrated with these problems as well as many others, a few programmers eventually decided to create a new programming paradigm.  Object-oriented programming, or OOP for short.  Thus, modern programming was born, and the cave-dwellers evolved into modern programmers.  Today, OOP is the most popular way to code.  No one will take you seriously unless you can OOP.

The biggest difference between this paradigm and primitive programming is that nouns and verbs are no longer equals.  In OOP-world, nouns are considered the feudal lords, while verbs get knocked down to lowly serfs.  Verbs can no longer vote nor own land.  Nouns, on the other hand, in addition to rights they have before, can now own verbs and even other nouns as well.

To emphasis their new stature, nouns have been given a new name — objects.  ( Hence, “object-oriented.” )  And those that are owned by other nouns are called properties.  Although properties may be lower in stature than their masters, they themselves can still own verbs and other nouns that are hierarchically lower than they are.

To reflect their second-class standing, verbs have been assigned a new name as well — methods.  As in, the “method” by which to carry out an action.  Every single method is owned by some object.  You can ONLY define a method within the confines of an object.

On the bright side, unlike primitive programming, nouns and verbs are completely mixed together.  Unfortunately, this mixing comes in the form of a master-servant relationship.

Let’s crack open the object dog to see what this looks like:

Object dog
{
    /* properties of dog */
    puppyDogEyes;
    floppyEars;
    snout;
    leftFrontPaw;
    rightFrontPaw;
    leftHindPaw;
    rightHindPaw;
    tail;
    …

    /* methods of dog */
    run( )
    {
        repeat
        {
            move_right_front_paw_forward( );
            move_left_hind_paw_forward( );
            move_left_front_paw_forward( );
            move_right_hind_paw_forward( );
        }
    }

    bark( )
    { … }

    play( game )
    { … }

    …
}

Why would such a terrible feudal system become the most popular way to program in the modern era?  Well, probably because it mirrors the way human beings think.  We all think in terms of nouns — it’s difficult to conceptualize verbs.  Even when we talk about a verb, we still think in terms of what a noun does.  For example, I’ll bet that if I mention the verb run( ), you’d imagine some person doing the running, rather than the act of running itself.

Alright, so you’re visiting OOP-world and would like to access some method or property.  Unfortunately, you can’t talk to these peons directly.  Instead, you need to speak to the overlord who presides over them.  How do you do that?

One of the coolest things you’ll ever come across in OOP-world is the dot operator — which, obviously, is represented by a dot (“.“).

You interject, “Is the dot operator cool because it’s part of the Special Forces?”

“Sir!  We’ve located the terrorists’ base camp!”

“Great!  Send in the dot operators to capture them!”

Uhh — not quite.  But almost as cool!  A dot indicates possession.  It means that everything to the left of it owns everything to the right of it.  It’s equivalent to ‘s in the English language and represents the genitive case.

You’re aghast.  Whaa?  How can this possibly be cool?  In a horrible system like this, possession literally symbolizes brutal oppression!”

Well, um, yes, that’s true — but the fantastic news is that the verbs’ pain is your gain!  This barbarity allows you to write code that sounds a lot like sentences you would normally write in a natural language!  Here are a few examples:

dog.run( );
dog.bark( );
dog.play( fetch );

dog.snout;
dog.snout.mouth;
dog.snout.mouth.bite_on( stick );

i.laugh( ).cry( ).ate( giantSandwich );
i.read( waltWhitman.leavesOfGrass.iSingTheBodyElectric );
i.watch( rayBradbury.iSingTheBodyElectric );
i.sing( fame.iSingTheBodyElectric );

myMom.cooks( bigTurkey.filled_with( stuffing ), during( thanksgiving ) );
loveTriangle.formed_by( romeo, juliet, paris );
gambler.bets( big ).wins( big );

Combiner devastator = longHaul.combine( hook ).combine( scrapper )
.combine( mixmaster ).combine( bonecrusher )
.combine( scavenger );

Neat, huh?  I can tell you’re impressed.

But that’s not all!  OOP eliminates many of the problems that plague primitive programming.

For instance, this programming paradigm minimizes the amount of changes you need to make to previously working code.  Let’s revisit run(  ).  Once you’ve created a run(  ) method for dog, you don’t need to crack it open ever again.  Even when you create a new object, say, cat — you don’t touch dog.run(  ).  Instead, you create a separate run(  ) method within cat that only cat can access.

Because nouns and verbs are intermingled, you don’t even need to pass the master object in as an argument.  Since run(  ) is within the scope of dog, typing dog.run(  ). is enough for run(  ) to find dog.

On the problem of ambiguity, here’s how you can rewrite the primitive function, chase( dog, cat, mouse ):

mouse.chase( dog ).to_help_best_friend( cat );						

We instantly understand the relationship between these three animals — who’s chasing who and for what reason.  We don’t need to search through the messy details inside the methods to find the key information.

Unfortunately, while OOP solves a lot of problems, it also creates a whole new set of issues.  One of the biggest challenges is the explosion of duplicated code.  Concepts like inheritance, delegation, and design patterns have been developed to address this, as well as many other shortcomings.

... But Then Eve Ate The Forbidden Fruit — causing God To Cast Them Out Of Paradise And Make Functional Programming Confusing As Sin

If you’re uncomfortable with the cruel treatment of verbs in OOP-world, then perhaps the third paradigm is more to your liking.  Functional programming, as you can probably guess, is oriented around functions.  In FP-land, the roles are reversed.  Here, the verbs are the feudal lords who control everything, while nouns are basically nothing more than interchangeable chattel.

FP hasn’t really taken off the way OOP has, probably for the same reasons why OOP is so popular.  It is, however, pretty popular among the mathematically-focused.  A good chunk of mathematics revolves around functions, so this type of programming naturally fits.  As a consequence, FP is much more mathematically rigorous than OOP is.

Revelation

If you dislike both OOP and FP, because you hate the idea of one group heinously oppressing another — well, then I don’t know what to tell ya.  Your only option would be to go back to primitive programming.  But doing so will draw the ire of your fellow programmers — who’ll be pissed that you care more about noun rights and verb rights than about programmers’ rights.

In the next post, I’ll walk you through an example of how to use OOP to tell a compelling story.

Footnote

Here’s an interesting article on how OOP and FP can complement each other to improve your code writing:

Speaking of epic Homeric tales, I highly recommend Mad Max: Fury Road.  It’s a 21st century retelling of The Odyssey — with a twist that only George Miller can come up with.  He’s mad, I tell ya, mad!

0 0 votes
Rate This Article!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x