• So You Want to be a Functional Programmer (Part 3)
  • Charles Scalfani
  • The Nuggets translation Project
  • Translator: Airmacho
  • Proofread by Cyseria and Xuxiaokang

Ready to learn functional programming? (Part 3)

To understand functional programming, the first step is always the most important and difficult. But with the right mindset, it’s not too difficult. Previous part: Part 1, Part 2

Point – Free representation

There is a way to write functions without specifying parameters, called point-free notation. This style may seem strange at first, but as you continue to use it, you’ll begin to appreciate the simplicity it brings.

You’ll notice that in mult5AfterAdd10 we use the value variable in two places. One is in the parameter list and one is for internal use.

-- This is a function that expects 1 parameter

mult5AfterAdd10 value =
    (mult5 << add10) value
Copy the code

This argument is not necessary, because add10, the outermost function in the combination, takes the same argument as the combination of functions. This is equivalent to the point-free version below:

-- This is also a function that expects 1 parameter

mult5AfterAdd10 =
    (mult5 << add10)
Copy the code

There are many advantages to using this point-free style notation.

First, we don’t need to specify extra parameters. Because we don’t specify them explicitly, we don’t have to bother naming them.

Second, because it’s simpler, it’s easier to read and understand. This example is very simple, but imagine a function with many arguments.

Trouble in heaven

So far, we’ve seen how function composition works, and how we can use point-free style writing to improve code simplicity, clarity, and flexibility.

Now let’s try using these ideas in a slightly different scenario. Imagine we replace add10 with add:

add x y =
    x + y

mult5 value =
    value * 5
Copy the code

How can we combine mult5After10 with just these two functions?

Think about this before you read on, think about it, and try to do it.

Well, if you really take the time to think about it, you might come up with something like this:

-- This is wrong !!!!

mult5AfterAdd10 =
    (mult5 << add) 10
Copy the code

But it doesn’t work. Why? Because the add function takes two arguments.

Elm may not be obvious, but you can write it in JavaScript:

var mult5AfterAdd10 = mult5(add(10)); // this doesn't work
Copy the code

This code is wrong, why?

Because here the add function takes only one of the two arguments, and then the error result is passed to the mult5 function, the result is also wrong.

In fact, in Elm, the compiler won’t let you write this kind of broken code (one of Elm’s strengths)

var mult5AfterAdd10 = y => mult5(add(10, y)); // not point-free
Copy the code

It’s not point-free, but it works. But instead of a combination of functions, I wrote a new function. Also, if the function is more complex, for example, if I want to combine mult5AfterAdd10 with other functions, that would be a hassle.

The usability of visible function combinations is limited because we cannot combine the two functions together. Too bad.

How can we solve this problem? What do we need to do?

It would be great if we could find a way to make the add function take one argument and then a second one when we call mult5AfterAdd10 later.

There is such a thing as corrification.

My brain!

That’s enough to digest for now.

In the rest of the article, I’ll cover Currification, functions common in functional programming (map, filter, fold, etc.), referential transparency, etc.

And then part four