by Adam Brett

Function vs Method vs Procedure

There seems to be a lot of confusion around the different names given to what are all effectively sub-routines. Some people erroneously believe they are all essentially the same thing, and technically, whilst they are all simply different words for sub-routines, understanding the subtle differences between each can help you write better code.

Sub-routines

Before you can accurately define types of sub-routine, you need to know what a sub-routine is. It is actually quite simple to define: A sub-routine is a repeatable piece of procedural code you can call by name.

Functions

A function is essentially a sub-routine that returns one or more values. A function should calculate its return value based on its input; It should provide an answer about its arguments, or compute a new value based on its arguments. Here are some examples of functions in PHP:

<?php
function isAGreaterThanB($a, $b)
{
    return $a > $b;
}

This function provides an answer about its arguments. Namely, is $a greater than $b?

<?php
function multiply($a, $b)
{
    return $a * $b;
}

This function calculates a new value based on the values of its inputs, specifically, multiplying $a and $b together and returning the result.

The above examples are considered Pure Functions because they don't rely on or modify anything outside of their own scope, and they don't cause any side-effects; that means they don't write any files, produce any output etc. Given the same input, a pure function will always produce the exact same output.

Procedures

A procedure is a sub-routine that doesn't return a value, but does have side-effects. This could be writing to a file, printing to the screen, or modifying the value of its input. Here are two procedures in PHP:

<?php
function logMessage($message, $level = 'debug')
{
    $bytesWritten = file_put_contents("{$level}.log", $message, FILE_APPEND);
    return $bytesWritten !== false;
}

Here, our side-effect is to write a message to a log file. We can return true or false to determin whether it failed or not, but really should not return anything else.

<?php
function multiply(&$a, $b)
{
    $a = $a * $b;
}

This is an example of a procedure that mutates (modifies) its input value. It is almost identical to our multiply function above, however instead of returning a new value, we pass $a by reference and assign it a new value.

Methods

I have deliberately left methods for last, because a method is really a function or procedure that is executed in the context of an object. That means there are two types of methods: A function method and a procedure method.

A function method calculates a new value based on the values of its inputs and/or the scope of the object instance it's being executed on.

Here are the above function examples in an object context:

<?php
class Integer
{
    protected $a;

    public function __construct($a)
    {
        $this->a = $a;
    }

    public function isGreatherThan($b)
    {
        return $this->a > $b;
    }

    public function multiply($b)
    {
        return $this->a * $b;
    }
}

Following this logically, a procedure method is a procedure that produces side-effects that can include modifying the state of the object instance it's being executed on.

Here are the above procedure examples in an object context:

<?php

class Logger
{
    protected $level;

    public function __construct($level = 'debug')
    {
        $this->level = $level;
    }

    public function logMessage($message)
    {
        $bytesWritten = file_put_contents("{$this->level}.log", $message, FILE_APPEND);
        return $bytesWritten !== false;
    }

}

and our multiply example:

<?php
class Integer
{
    protected $a;

    public function __construct($a)
    {
        $this->a = $a;
    }

    public function multiply($b)
    {
        $this->a = $this->a * $b;
    }
}

Conclusion

It's sometimes easy to forget these distinctions when writing PHP, as everything starts with the function keyword, however, if you ask yourself: "What type of sub-routine do I really want here?" you will hopefully find that you start to make better decisions and will write more logical and maintainable code.

For exclusive content, including screen-casts, videos, and early beta access to my projects, subscribe to my email list below.


I love discussion, but not blog comments. If you want to comment on what's written above, head over to twitter.