Picture by Markus Spiske
What is a function? Wikipedia says, "In mathematics, a function is a binary relation between two sets that associates every element of the first set to exactly one element of the second set.". Simply put, it maps a value in a set to a value in another set.
Source Wikipedia
In programming, we may be used to using a function called double
which is used to erm ... double a number. So x
will map to 2x
, or a square
function which maps x
to x*x
.
Let's try something more simple. A function that takes in one argument and returns the same value. In mathematics, we would represent it as below.
f(x) = x
It is called and identity function. How would this look like in a programming language? Let's try a few popular ones and compare
Haskell
f x = x
Haskell clearly maps to the mathematical definition of a function. It even uses less number of characters. It is succinct, clear, and has a smaller semantic gap between the programmer and the language.
Rust
fn f<T>(x: T) -> T {return x;}
C#
static T f<T>(T x) {return x;}
Rust, C#, and even Java follow a C-like syntax. One may observe that the number of parentheses is similar to that used in Clojure. The placement of the parentheses and their positions may differ a bit. Apart from this, we may notice some more characters sprinkled around. Only when we compare these group of languages, we realize the magic present in Haskell and the languages related to it.
Haskell is influenced by ML a programming language that was introduced in 1973. It was the first language that introduced implicit type and generics. Yes, generics was introduced 47 years back. ML and its family of languages - OCaml, F# - and even languages like Haskell that are influenced by it implemented generics and implicit typing from the start. The result is that you don't even think about it.
C# and Java implemented this at a later stage - around 2004 and you see the impact on these languages. These already required the programmers to specify a type for all variables, parameters, and return types. So when they implemented generics, they needed you to put a place holder - the T
or any other arbitrary name instead.
static int f(int x) {return x;}static string f(string x) {return x;}
above could be written as one function below
static T f<T>(T x) {return x;}
One may argue that, this is required because we are implementing a generic function. That this is computing, and not math. But so is the case in ML family of languages. Another argument could be that it makes the types more explicit, and while that is true, one can still argue that we want the majority of our programs to be more generic and reusable, won't it be better if we imply generics by default. Would that make you a better programmer? It is arguable.
I personally prefer Haskell, where types are implicit and functions are generic by default. You can provide type information as shown below, when you feel it is required. You get a choice. And even if you provide the type information, it is separated from the function itself, almost like a part of the function documentation. Allowing you to think more clearly about the implementation and the algorithm.
Haskell
factorial :: (Integral a) => a -> afactorial 0 = 1factorial n = n * factorial (n - 1)
It also makes it easier for beginners to grasp programming better. It is surely less intimidating. Imagine yourself to be in school, which of the above samples would make more sense to you if you were to take up a programming class at that age.
I haven't spoken about JavaScript, Python, or other languages here. They are dynamic in nature. Which means that programmers can get away with mentioning types explicitly, (without the performance benefits of static typing of course). But if you look below. It makes the program more readable. I would feel tempted to put this as one of the top reasons why these languages are so popular among grad students and anybody else from outside the field but want to pick up programming.
JavaScript
const f = x => x
Hmm, I will end my rant here. I thought it would be a good use of my time to write this article while I wait on Go to get generics 😉.
Note: I'm not asking you to give up your favorite language and submit yourself to Haskell type of languages. But they are surely worth a look 🙂.
For more fun posts like these, click here to see a list of all my posts