Mathematical Functions vs. Programming Functions

Something is bugging you about your program but you don’t know why…

Simon Janes
The Accepted Forest
4 min readAug 22, 2017

--

Mathematicians have it easy. Their functions always make complete sense. There are never any exceptions. They always work in the same way. A set of inputs results into another set of output results. If you have the function that “squares a number” it will always give you a 25 when you give it 5. No exceptions. Never happens in mathematics, if it does, it is a mistake — and it isn’t the math.

Programmer’s Functions

A programmer’s life is not a simple life. In the crush of “getting things done” we got lax. We make things that are functions that are not actually functions in the mathematical sense.

We can make a function that sometimes returns 26 when we expect 25 from the input 5. Some functions cause the program to abort giving no result at all — an equally horrible problem in some contexts. Nowhere in the mathematics of “squaring” does it say to return nothing, an incorrect answer or even halt and catch fire. As these functions are composed together in complexity we start to have more and more complicated interactions between every piece in the system. A program may run perfectly fine in an operating system one day and then find itself viciously murdered by another component — often called an Out of Memory killer — without warning. Why did the OOM killer get the program? Very likely, another program on the system stumbled into a flaw with its own particular set of non-mathematical functions and started to use all the available memory.

Pure Functions

You could imagine that this can be quite frustrating to find that your programs composed of functions that sometimes throw faults or crash or do the wrong behavior. A solution — there are always multiple — emerged repeatedly from the “functional programming” paradigm that is called “pure functions.” As is typical in the fog of naming things, we had to add something to the name “function” in order to regain or capture the essence of what it had in its former glory: predictability.

Pure functions are nothing more functions that have no side-effects in their definition. Surprise, the mathematics has returned back to programming!

Purity isn’t Enough…

But we still have a nasty surprise for the creation of “pure” functions — how can we know for sure that they are pure? Now we have to turn the difficulty up to a new level and at the same time acknowledge that there is something that is likely impossible.

Total Functions

A total function is the pure function with another feature: it can show that it will return a result for all possible inputs. A partial function can be “pure” part of the time but not all of the time — partial functions will crash should they ever receive an input outside of their capability.

Halting Functions

The man in the lab coat puts the device on the steel table under the bright lights of the gallery. The man turns around and with his back to the audience connects the cables for power to the device placed just so, in front of all. The audience’s murmurs raise and hush as the man in the lab coat turns around in a flourish and announces loudly “Ladies and Gentlemen, we are here to evaluate the utility of this device and answer the ultimate of energy and power-conversational resource questions — a problem that is of course important to us all —that is… ‘Will it end?’”

The easy part of the halting problem is knowing that the halting problem exists and it has been proven to be insurmountable. Relax. Alan Turing proved that there is no general-purpose algorithm to analyze a program to determine if it “halts.” It isn’t the first time this has been shown. What does that mean for the working programmer? It means they need to simplify their work so the available known special-purpose algorithms can be used to improve and certify it.

Testing Functions

One of the greatest things that computers can do other than the functions you have created to accomplish important works, are the functions that watch and guard the behaviors of those other functions to certify that they are working as you expect. The more often you run those tests while you develop the more confidence you can have that nothing is going horribly wrong.

Best Practices

The best any programmer can do is just this: make the functions small, make the functions pure and make the functions total. Use other functions to automate and evaluate these functions to confirm that they are doing what you expect. And if you can’t understand the function, break it apart into smaller pieces until you do — because if you don’t you can be certain there is a bug waiting to bite you there in the dark.

--

--