Over the last two posts I’ve made a few efforts to explain how we can drop of explicit argument references when moving functions towards point-free style. We’ve looked at currying, partial function application, and function composition as explanations for this. These concepts are really important, but after kicking around various ideas about this with a colleague I’ve decided to try and separate all these concepts from the most fundamental form of reducing a function towards point-free.

## Eta reduction

Say we have two functions, `f`

and `g`

, with exactly the same types. Both take one argument of type `a`

and return something of type `b`

. We’ll define `f`

in terms of `g`

:

```
f :: a -> b
g :: a -> b
f = \a -> g a
```

In Haskell this this can also be written as:

`f a = g a ... (1)`

If `f`

and `g`

are pure functions (deterministic, no side-effects, no state), then we have:

`f = g ... (2)`

We’ve just said in `(1)`

that the functions are equal when applied with the same argument, so for all values in type `a`

the functions `f`

and `g`

will be equivalent; we can use them interchangeably. We don’t have to worry about partial application, or currying, or anything else; we can just apply this equivalency.

Removing redundant argument references like this is called eta reduction (also written as *η-reduction*). Continually reducing in this way can lead to point-free functions once we’ve omitted all redundant argument references.

## Applying with multiple arguments

We can apply this same equivalency to our previous example with multiple arguments:

```
z = \acc x -> const (acc+1) x
-- `z` is of the form:
-- f x = g x
-- where:
-- f = z acc
-- g = const (acc+1)
z = \acc -> const (acc+1)
```

We use currying, partial application, and concepts like function composition to get our functions into the required `f x = g x`

form, but once we’re there we can use η-reduction to drop the explicit reference to the last argument.

## Impure functions

Notice that this doesn’t apply for impure functions, as we could have:

```
int f(int x) { Console.WriteLine(x); return g(x); }
int g(int x) { return x+1; }
```

In this case we can’t use `f`

and `g`

interchangeably as they behave differently. In a pure functional language like Haskell we don’t have to worry about this; the type system will differentiate functions with side-effects.