Wednesday, November 12, 2014

Functions

Functions, and their close cousins methods, are fundamental to software development.  Syntactically, there is no real difference between the two.  They really only differ in terms of the context in which they operate.  Technically, functions should not depend on anything except the information they are given.  If you call a function called 'add' with 2 and 3 as parameters, it should always return 5 regardless of what else might be going on inside your system.  A method called 'add' might only be given one parameter, and be expected to operate in a context where it is aware of some other number to which the parameter will be added.  Please note that it quite possible to write your code so that it does not abide by these rules, but it's probably not in your best interest to do so.

Suppose we want to write that function mentioned above, 'add'.  Furthermore, let's suppose we want it to be made available to any class that wants to call it, and that it is expected to do only integer (whole number) arithmetic.  We might write it like this:

    public static int add ( int number1, int number2 ) {
        return number1 + number2;
    }

This is of course simplistic, and probably better accomplished in-line where you need to perform the addition, but that's the nature of an example.

This function should be easy enough to understand once you understand the required syntax.  It starts off by being declared 'public', which means any other class can call it.  By declaring it 'static' we've indicated that we do not wish to have to create an object in order to call the function.  It has to give back an integer value to the code that calls it, so we put that up there, too.  Then we have the name of the method, followed by parentheses.  Inside the parentheses is a list of parameters (which can be empty).  Parameters are just variables given to a function from an outside source.  Note that every time it's given the same set of parameters it will give back the same result.  There are no hidden variables or shared secrets that will affect its operation and change the return value.

If I want to use add in this same class I can just write:

    public static void main(String[] args) {
        int answer = add ( 2 , 3 );
        System.out.println("The answer is " + answer );
    }

This will call 'add', which will see number1 as having the value 2, and number 2 as having the value 3.  Then add will then return 2 + 3, which is of course 5.  Because it's a return value, we can use the equal sign to set 'answer' to the returned value.  So 'answer' becomes 5, and we print out:

The answer is 5

Naturally, most useful functions will do a bit more than this, and they can in fact get very complicated, calling other functions and methods to do all sorts of tasks.  Returning a value is strictly optional, but you must declare the 'return type' for every function you write.  If you do not wish to have a return value, you can declare the return type as 'void'.  If you do declare a return type that is not void, you must ensure that you return an appropriate value when your function ends.  This would be an error and would fail to compile:

    int badAdd( int value1, int value2 ) {
        if ( value1 < 100 ) {
            return value1 + value2;
        }
     //Fails to compile!
    }

I've introduced another new concept here, a conditional statement in the form of 'if'.  This is another key concept, the idea of taking some action only if a specific condition is met.  In this case, if the value of 'value1' is less than 100 we'd execute all of the code between the brackets immediately following the if.  Technically the brackets are not required if you only have one line of code, but now forget I ever said that and just use them.  Many hours have been lost to misunderstandings that crop up from failing to use brackets where they can be.  Don't waste minutes (or worse, fail to notice a problem) by saving a half a second of typing and a couple of characters of disk space.

There are ways to get around returning a value in case of error conditions, which I will discuss under the topic of Exceptions at a later date.

View code here