Programming Functions and why are they so special

804 views

I’m still trying to wrap my ahead around this concept.

I’ve done basic maths, so I know that f(x) = x is like a function, but I can’t find an intuitive way of explaining why some functions don’t have to return values. In addition, what separates functions from just lines of code?

In: Technology

12 Answers

Anonymous 0 Comments

A function like `f(x) = x + 1`, is a pure function. It takes a value and adds one to it. It is considered `pure` because the output value depends only on the inputs to the function. For example, `f(2)` always returns `3`. And it does not interact with the outside world in anyway. In other words, it is free of side-effects.

A function like: `hi(name) = print (“Hello, ” ++ name ++ “. How are you?”)` doesn’t return any useful value. It is only useful because it causes side-effects. The side effect in this case is causing characters to be printed to the screen. Because it has side-effects it is an impure function.

A function allows you to give a name to a bunch of lines of code. Instead of having to copy and paste those lines of code every time you want to use them, you can just call the name of the function instead.

A function also provides a way to make parts of the function variable. For example, in the `hi` function above, the `name` is variable. So instead of having to write:

print (“Hello John. How are you?”)
print (“hello Mary. How are you?”)

You can write:

hi “John”
hi “Mary”

Notice above how I forgot to capitalize the `h` in `Hello Mary.`. By using a function, I only have to get it right in one place. And if I wanted to change it to say, `”How are you today?”`, I only need to update things in one place.

Modern programming languages often use the term `function` differently from the way mathematicians use the term. Though some languages are closer to the mathematical usage than others. For example, in Pascal, a routine is called a `function` if it returns a value and a `procedure` if it doesn’t.

In some languages, like ML, a function always takes a value and returns a value — much like a standard mathematical function. If you don’t have anything useful to pass to the function or return, you use the value `()`. For example, consider this function:

let hello () = print “hello, world”

To call that function you would write:

hello ()

the `print` function doesn’t have anything useful to return, so it just returns `()`.

So `hello` takes the value `()` and returns the value `()`. But it has the useful side-effect of printing something to the screen.

Other languages, like Haskell, allow you to mark if a function is pure or not. For example, this function:

f :: Int -> Int
f x = x + 1

has the type `Int -> Int`. So we know it is taking an integer and returning an integer, and not interacting with the outside world at all. We do not have to see the function implementation to know that. If there is a function with the type `g :: Int -> Int`, we know it is also pure with out knowing what it actually does.

If we consider this function:

hi :: String -> IO ()
hi name = putStrLn (“Hello, ” <> name <> “. How are you?”)

We see that it takes a `String` and performs some `IO` (input/output — in other words, causes side effects and interacts with the outside world). That IO does not produce any useful return value, so it just returns `()`.

The idea of expressing computation using function abstraction and application and variables actually predates digital computers. Alonzo Church invented Lambda Calculus in the 1930s. The second oldest programming language still in use today, LISP, was based heavily on lambda calculus. And newer languages like Haskell are essentially just very fancy versions of Lambda Calculus.

In the Haskell example, we gave the functions `type signatures` which described their input and output values. Type Theory was actually invented even earlier than lambda calculus. Bertrand Russell begin experimenting with ‘theories of types’ in 1902 and eventually solidified those theories in Whitehead and Russell’s Principia Mathematica published between 1910 and 1913.

Modern programming languages have gone in two directions. Some have focused on the “git ‘er done” and have thrown out the math and formal reasoning aspects of lambda calculus and type theory.

Other languages, like Agda, Idris, and Coq have gone the other direction and worked to create programming languages that not only allow you to have useful side effects, but also allow formal mathematically reasoning and proofs about the behavior of the code.

You are viewing 1 out of 12 answers, click here to view all answers.