Chickens are not Bird-Mammals. A Software Developers Rant
A chicken is not a bird-mammal. It is not a mammal of any kind.
This seems obvious, but exactly the same mistake is uttered every day by software developers.
Ask a Java programmer what this is :
static int main( String args... ) { }
and the likely response is : "It's a static method".
The problem is, it has NONE of the features of a method.
Definition a of Function
To a software developer a function is similar to (but not exactly the same as) a mathematical function. It has inputs (called arguments), and an optional output (often called the return value).
Definition of a Method
A method is more complicated, and was invented as a replacement for functions in OO (object oriented) programming.
A method has a receiver in addition to arguments.
Which implementation is called depends on the type of the receiver. We call this polymorphism.
Differences between Functions and Methods
- Functions are not polymorphic. They can achieve the same result using if / case / when statements. (I'm not trying to claim that methods are better or worse than functions!).
- Functions can have zero or more inputs (arguments)
- Methods have 1 or more inputs (the receiver, and the zero or more arguments)
- The receiver of a Method (the first input) is special, and it used to work out which implementation to be called.
- A method's receiver can never be null, without throwing a NPE (null-pointer exception).
- All inputs to a function may be null without throwing a NPE.
Back to Java
In the example Java code above, main has no receiver. No polymorphism. No special inputs. All inputs can be null without causing a NPE.
I don't care what prefix you put before method, it isn't a method, it's an f'ing function.
To call it a static method is like calling a chicken a bird-mammal. It makes no sense.
By comparison, it is correct to call a whale a sea-mammal.
Kotlin
My rant isn't aimed at Java or Java programmers. It is aimed at misuse of technical terms across the board.
Kotlin is my favourite language, and it made exactly the OPPOSITE mistake.
As with Java, Kotlin has both functions and methods. Kotlin calls them all fun (short for function).
That's both funny, and tragic.
Words Have Meaning
Words have meaning. When you twist their meaning, sentences become meaningless.
Learning a new language, or learning computer programming in general is HARD. Don't make it harder by (deliberately) misusing terms.
The people who designed Kotlin and Java are obviously very clever. They know what method and function mean.
They just didn't care that they were misusing those phrases. They didn't care that their mistake/laziness/slackness have caused confusion in generations of computer programmers.
Shame on you.
Extend Don't Replace or Remove
I take even more umbrage of the phrase static method, because Java is an object oriented (OO) language. And in OO, there is a golden rule.
- A subclass should not remove or replace functionality. It should only extend the base class's functionality.
If we consider Method a base class, and Static Method a subclass, then it breaks the golden rule.
The designers of Java failed that golden rule in spirit.
In practice, there is only 1 class, called Method, and it has two different behaviours embedded in it. Acting as both a function as well as a method. So while not strictly breaking the golden rule, it most certainly does NOT embrace the OO methodology.
If they had called it invokable or something else which encompass both functions and methods, that would be fine. It would also be a good example of when non-OO design is preferable to a pure OO design!
FYI, A pure OO design would have an Invokable interface with two concrete implementations Method and Function.
Feather
Years ago, I wrote a language called Feather. The syntax is deliberately similar to Kotlin, and it uses the keyword fun.
Shame on me. Sorry, that was a mistake. I'm not going to shift the blame to Kotlin. It was my mistake. I should have know better. Copying a mistake is itself a mistake.
I'm currently rewriting Feather. Should I break backwards compatibility with version 1, and fix my mistake?
This rant, is in part, a way to force me to do the right thing. Suck it up, and fix it (including patching the hundreds of Feather scripts that I've written over the years).