Sunday, August 18, 2013

Calling a function with no arguments

Q: I don't understand what it means to call a function with no arguments.

A: Come again?

Q: You see, in mathematics a function is a subset of the Cartesian product of domain and range. If the domain is empty, there's no place to stash the return value. But programmers seem to use such functions just fine. What's going on?

A: Well, the thing that programmers call a "function with no arguments" is never really a function with an empty domain.

Q: What is it, then?

A: There can be different interpretations...

Q: Can you give an example? What happens when I call a C function with no arguments:


A: This part of C doesn't reflect the underlying math very well. Let's look at Haskell instead. Functions in Haskell are curried, here's the type of a function with two arguments:

a -> b -> c

And with one argument:

a -> b

If we follow that pattern, the type of a "function with no arguments" will look like this:


As you can see, that's just a value, not a function at all.

Q: Neat! I remember reading something about constants as "nullary functions". But it's still a little unsatisfying. Can you explain what's going on in a language where functions aren't curried?

A: Haskell also has non-curried functions. They look like this:

f (a,b)

If we follow that pattern, a non-curried "function with no arguments" will look like this:

f ()

Note that () is the empty tuple, aka "unit". The function's domain is a one-element set, not the empty set.

Q: Okay, that's a nice interpretation, and it's closer to the original question I had in mind. But when I call a C function with no arguments, it doesn't seem to pass the empty tuple, it passes nothing at all. Why does that work?

A: If you want to specify an element of a one-element set, zero bits of information is enough.

Q: That makes it clear. Thanks!