Photo by Gia Oris on Unsplash

What is a method?

Dominik Hirzel
Published in
4 min readJan 17, 2021

--

Since my declared target audience are people who use primarily object oriented languages, the first few posts will put some terminology into perspective. Contrary to many expectations, I will not cover the function first — but the method.

I don’t want this to sound like homework, but take a moment to answer this posts titular question for yourself or with a colleague. Then, let us consider the following TypeScript and Python code examples.

Typescript example
Python example

Looking at the MakeSound and make_sound implementations, it is notable that TypeScript uses the language keyword this to refer to the object that contains the method. In Python on the other hand, the first parameter self is required, since there is no keyword to access the object form within the method. You could name that parameter anything you’d like. For example this, since it is only called self by convention.

Why is there no argument provided for self in the Python example?

Python passes an implicit reference to the object to the call that uses method syntax. But since the method make_sound takes an argument, you could also call it explicitly. Hence, the two Python calls below are equivalent:

Using the type (Animal) and method (make_sound) to refer to the functionality and then passing an object is the more functional way. In many functional languages, you can also pipe from a function to another, similar to how shells pipe stdout to stdin.

From a more functional perspective, a method is a function¹ that takes an instance of its containing class as a parameter.

If that sounds too abstract, it is exactly what Extension Methods do. Like C# by stating the this keyword. Or like Dart, where this feature resembles more of an extension class.

¹ if you disregard static data, state changes, IO, or other side-effects for now

Want to get even more functional?

Although I have already answered this post’s question, there is more to unpack.

Don’t forget to stock up on coffee/tee.

So what if I don’t need anything from this/self?

In TypeScript and many other object oriented languages you don’t have to change anything. Whether or not you use this is your choice. Some compilers or linters may display a hint or even an error, telling you that the method could be static.

In Python however… Consider this alternative implementation of Animal, where I just deleted the parameter for the make_sound method:

Mind the missing parameter for make_sound: this will result in an error.

Python unsuccessfully tries to implicitly pass cricket as the argument to the call in line 10. But since there is no self parameter in the method declaration, the call fails. A fix could be using the decorator @staticmethod on make_sound, preventing Python from passing an implicit reference. This will make make_sound a static method and no longer an instance method.

If you don’t need anything from this/self, you don’t need a class.

In more functional languages you don’t require a class — the last iteration of the Python example could look like this.

Note the indentation — which is important in Python.

In this example we need only lines 6, 7, and 10 to call make_sound. So to answer the posed question: If you don’t need anything from this/self, you don’t need a class.

Comparison

Languages that don’t allow functions (such as C# or Java), implement such functionality as static methods on a (sometimes static) class that serves a topic or theme. Prominent examples are System.Math in C# or java.lang.Math in Java. If those languages allowed functions, System.Math and java.lang.Math could be namespaces/packages instead of classes. Today we work around this by using using static/import static to allow all members of a class to be used in the current scope without mentioning the class.

Using static to work around the required class.

Sometimes there is no correct way to group your methods. Wouldn’t it make more sense for the sine and cosine function be on a class called trigonometry? Why aren’t all the numeric types attached to the Math class as well?

Summary

All static methods are on classes out of necessity — oftentimes because the language doesn’t allow functions. Any modularization or grouping could be done by using namespaces/packages, without resorting to the workaround of using using static/import static.

If you don’t need anything from this/self, you have written a function¹.

In Python you can’t write an instance method that takes no parameter. If you don’t require access to any property or method of self, you have written a function. You have no dependency on that class and could move the function outside the class and it would still, pun intended, function the same.

This post is meant to show a more functional perspective on methods. I hope this has clarified the relationship between methods and functions somewhat. I am happy to answer any question about this topic — even in its own post.

¹ if you disregard static data, state changes, IO, or other side-effects for now

Glossary

Instance Method — functionality that is associated with a class and object
Static Method — functionality that is associated only with a class and no object
Method — umbrella term for both of the above
Function — Functionality that isn’t associated with any class or object
Formal Parameter — a parameter that is accessible inside a method/function
Actual Parameter — the value/reference that you pass to the method/function
Argument — same as Actual Parameter

--

--

Dominik Hirzel
More Functional

Another guy broadcasting his perceived original thought.