Methods, Procedures and functions are different concepts in programming and the difference between them one of the most misunderstood concepts in programming by beginners. In this post, I will try to explain the difference between them. I will use C programming language to explain the difference between them. I picked C because it does not have any built-in support for object-oriented programming and it is easier to explain the difference between methods and functions in C programming language.

Procedures

A procedure is a parameterized set of instructions that performs a specific task. Procedures are used to break down a program into smaller and modular pieces. Procedures are used to avoid repetition and make the code reusable. Procedures are used to make the code more readable and easier to maintain. Procedures do not have return values, they execute a specific task and return control to the caller. Procedures are fundamental building blocks of assembly programming. In assembly, procedures does not have neither input parameters nor return values. However, we can see them as a 0-arity procedures. Lets look at an example assembly program which is written for x86 architecture (If you are not using linux, you can try with docker run --platform linux/amd64 -it ubuntu):

// Make _start symbol global
.global _start

// Store hello world string in data section
.section .data
msg: .ascii "Hello, World!\n"

// Code section
.section .text
_start:
  call print_hello

  mov $60, %rax
  mov $0, %rdi
  syscall

print_hello:
  mov $1, %rax
  mov $1, %rdi
  mov $msg, %rsi
  mov $14, %rdx
  syscall
  ret

As you can see we are calling print_hello procedure from _start procedure and print_hello procedure is printing Hello, World! to the console by using syscall instruction. However, print_hello procedure does not have a return value, if you want to return a value from a procedure you should store the return value in a register and read it from the caller. Also, in assembly programming, procedure parameters are passed by registers. Therefore, in assembly we can see procedures as just a group of instructions that perform a specific task without taking any parameters and returning any value. However, i think you got the idea. Procedures highly depends on mutating the state of the program.

Mutating the state of the program is not a good practice in programming. Because, it makes the code harder to understand and maintain. Also, a lot of bugs can be introduced by mutating the state of the program. In order to avoid mutating the state of the program, (as possible as we can) we can use functions.

Functions

Function is a parameterized set of instructions that performs a specific task and returns a value. Functions can be seen as a generalization of procedures or function can be seen as special kind of procedures. Lets look at an example in C:

int add(int a, int b) {
  return a + b;
}

Lets compare this function with a procedure:

add:
  mov %rdi, %rax
  add %rsi, %rax
  ret

This add procedure is equivalent to the add function in C. As you can see, the add procedure does not take any parameters and does not return any value. Instead, it starts by moving the first parameter to the rax register and then adds the second parameter to the rax register and simulates the return value by storing the result in the rax register. Therefore, we can see a function as a procedure that writes the return value to a specific register.

Also, we can see a procedure as a function that has void return type. Lets look at an example in C:

void add(int *result, int a, int b) {
  *result = a + b;
}

This function takes a pointer to an integer as a parameter and writes the result to that pointer’s value. We can model functions as static methods of a class. Lets look at an example in Java:

class C {
  static int add(int a, int b) {
    return a + b;
  }
};

Also functions may return multiple values, but we will not cover them in this post. If you want to see some examples, you can check Go programming language. Also some programming languages like Haskell does not support multiple input parameters like in mathematics. If you want to see some examples, you can check Haskell programming language.

Methods

Method is a function that is associated with an object. Methods are used to define the behavior of an object. Lets take a look at an example in Java:

class Point {
  int x;
  int y;

  int distance(Point other) {
    return Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y));
  }
}

In this example, distance method is associated with the Point object. This method calculates the distance between two points. We can model methods as functions that takes a pointer to the object that the method is called on. Lets look at an example in C:

typedef struct {
  int x;
  int y;
} Point;

int Point_distance(Point *this, Point *other) {
  return sqrt((this->x - other->x) * (this->x - other->x) + (this->y - other->y) * (this->y - other->y));
}

As you can see, we named the function as Point_distance and we added a Point *this parameter to the function. This Point *this parameter is a pointer to the object that the method is called on. We are appending class name tot the beginning of the function name in order to prevent name collisions. Because, we can define multiple methods with the same name for different classes. As you can see, we can model methods as functions that takes a pointer to the object that the method is called on.

Also we can model methods as procedures that takes a pointer to the result variable and a pointer to the object that the method is called on. Lets look at an example in C:

typedef struct {
  int x;
  int y;
} Point;

void Point_distance(int *result, Point *this, Point *other) {
  *result = sqrt((this->x - other->x) * (this->x - other->x) + (this->y - other->y) * (this->y - other->y));
}

As you can see, we added a int *result parameter to the function. This int *result parameter is a pointer to the result variable. Also methods can be defined multiple time in a class with different parameters, but we will not cover them in this post. If you want to learn how can you prevent name collisions for overloaded methods, you can check here.

Relation Between Them

There we can construct a table like this:

As Procedures Functions Methods
Procedures - void f() class C { static void f(); }
Functions void f(T *return_value) - class C { static T f(...); }
Methods void f(T *return_value, C *this, ...) T f(C *this, ...) -
  • Procedures can be seen as functions that does not return any value.
  • Procedures can be seen as static methods of a class that does not return any value.
  • Functions can be seen as procedures that takes a pointer to a result variable and writes the result to that variable.
  • Functions can be seen as static methods of a class.
  • Methods can be seen as functions that takes a pointer to the object that the method is called on.
  • Methods can be seen as procedures that takes a pointer to the result variable and a pointer to the object that the method is called on.

Therefore, we can say that they are equivalent to each other in some sense. However, they have practical differences and they are used in different contexts.