Saturday, June 23, 2007

How not to teach programming: Getter and Setter Methods

I am far from the first person to rant about "Getter and Setter" methods. (some have even said they are evil).. but it's been awhile since anyone has posted a new diatribe on the subject, so what the heck:

Introducing "Getters and Setters" to neophyte programmers can be harmful unless it's done right... Yes, I said harmful.

Becoming a good programmer requires internalizing the concepts of programming... One must learn to think like a good programmer and that requires being able to truly grok "why" the concepts were developed, not just blindly adopt or obey them like religious dogma.

"Getters and Setters" are an artifact of the Encapsulation concept.
The Encapsulation concept, simply put, is to hide details that do not have to be exposed. Keep secrets: Do not tell anyone about the internal details of a program unless they absolutely need to know those details.

The big "why" of the Encapsulation concept is to preserve flexibility. People who use a program can only truly rely on the published details about that program. Keeping internal implementation details private allows the programmer to change those details in the future, as long as those changes do not impact the previously published details about the program.

I could easily launch into a discussion on the evil caused by programmers who rely on unpublished side-effects, but I will resist that urge (for now).

So back to "Getters and Setters"; Where's the potential for harm?

Consider the following Java class definition:

public class Dog
{
private int fleas;
public int getFleas()
{
return fleas;
}
public void setFleas( int howMany )
{
fleas=howMany;
}
}


This example is a pretty standard introduction to "Getter and Setters"... and in fact I copied it (with modifications to protect the guilty) from a very popular Java book. Nothing fancy, and certainly nothing that could possibly be harmful... unless of course you are actually trying to learn how to program.

This example focuses on language features and could be interpreted to read something like this:

"All data elements of a class should be private, and for each data element you should write one method to set the value of the data element and another method to get the value of the data element."

Sounds more like a rule than an explanation... and the neophyte will end up thinking that they have to expose every data element via a Getter and Setter. So much for Encapsulation.

Learning to Program is not just about learning rules.

Maybe it's a stretch to cause this example harmful... but it demonstrates a rule rather than a concept. This example shows "How"... but there is no clue of "Why?". What is the underlying principal we are trying to teach?

The following change to the method "setFleas" makes this example much better:


public class Dog
{
private int fleas;
public int getFleas()
{
return fleas;
}
public void setFleas( int howMany )
{
if(howMany >=0){fleas = howMany;}
}
}

Minor change, but now we have supplied a bit of the "Why?".


If all of data elements of a class are made private, then you can insure that checks can be run before anyone changes the value of any data element.

This isn't the only reason to encapsulate data, and it may not even be the most important reason to encapsulate data, but for an aspiring programmer it's a very important principal to learn:

If you don't check input parameters before using them, your program can get very messed up ("My dog has -3 fleas!"). The use of "Getters and Setters" is one way to guarantee that checks will be run before data values are changed.
As new programmers progress in experience, they'll come to appreciate the other benefits of using "Getters and Setters": Advanced concepts don't make sense unless you already understand the simpler underlying concepts.
If I am right, and teaching concepts is more important than teaching rules, then the obvious question has to be asked:
"What programming concepts should be taught first?"
I'll have to give that one a bit more thought.... What do you think?

Thursday, June 14, 2007

Hello World!


I would be stretching the truth if I claimed to remember the first program that I ever wrote.

I am quite sure that the year was 1975, and that I was in a computer lab at Rice University in Houston, Texas. I'd even be willing to wager that the programming language that I used was called "APL" and that I used something very much like a DECWriter II to input the program and to see the results when I ran the program... At that time CRTs were rare; Output was printed on that lovely green and white computer paper.

Most likely, the first program that I ever wrote was "Hello World!"... For some reason, the most common way of introducing a programming language back in the 70's was to show the instructions that were necessary to get the computer to output the text: "Hello World!". In my case, the output was printed, but whether printed or displayed on a screen it's pretty much the same... Some things seem to never change, as can be seen by the Richard Dooling's: Python on Windows XP: 7 Minutes To "Hello World!".

To be truthful, I'm not fully convinced that "Hello World!" really even qualifies as a program. True.. the programmer is giving the computer an instruction to perform, but it's not much of an instruction, and the "program" doesn't include any of the core factors that most real programs share.

Most "real" programs include the following:
  • Data Input (get stuff into the program)
  • Data Storage (keep stuff around for later)
  • Data Access (get that stuff someone saved earlier)
  • Data Manipulation (change that stuff in some way)
  • Data Presentation (output the stuff)
  • Computations (plug that stuff into formulas and see what happens)
  • Flow Control (do different things based on the computations you ran on your stuff)
Of this list, "Hello World!" only makes a lukewarm attempt at "Data Presentation"... and the data is hard coded at that. Not an auspicious start... but I learned how to program anyway.

The best thing about "Hello World!" is that it is simple. In a few minutes, pretty much anyone can take the first step towards becomming a programmer... a person who writes instructions that tell a computer what to do.

Unfortunately, the later steps towards becoming a programmer aren't so easy. To become a "real" programmer requires a great deal of study... and once you do become a programmer you can never rest... the field is continually evolving and what is now cutting edge will likely soon be obsolete or extinct.

Continue learning new things, or you won't be a programmer for long.

Having said that... I would like to contradict myself:

There is a core to programming that never changes.
There are key concepts to master, and once those concepts are truly mastered the rest is just veneer.

I'll go even further and say that the key concepts of programming can be mastered by almost anyone if they are presented properly... and I would like to take a stab at doing just that (and I challenge my fellow programmers to do likewise)...

"Hello World!"