The faux fears of Functional Programming - JS-Republic's Blog

February 08, 2018 0 Comments

The faux fears of Functional Programming - JS-Republic's Blog

 

 

Example:

map :: (a->b) -> [a] -> [b]  

map is a function which returns a list where the function given as argument was applied to each element of the given list.

map is quite an important function, so keep it in mind.

Abstraction: OOP vs FP

The monads

Now, we have some (very) basic understanding about FP, let’s talk about abstraction for a second.

Definition of Abstraction (that better suites Computer Science): « The quality of dealing with ideas rather than events. »
We do not want to deal with concrete, or detailed, events because there are too many factors which will block our way of thinking, so we abstract, losing some of the details but maintaining the focus of the problem (the ideas of the definition).

Wait what?

To be more concise, we handpick the most important parts of our problem and the remaining details are forgotten, easing not only the structure for our types/objects but also our overall programs.

In OOP, the abstraction is quite simply achieved by representing « Things », though, not in all its complexity, only the important properties. Then you can do « Stuff » with the abstracted entity, and it is pretty much it.

By the way, the « Thing » is called Object and « Stuff » is Method.

In FP, we try to max out the abstraction, we cut our problems into simple functions which will after be composed to create more complex functions resulting into a program that does the thing we wanted. It is not only focused on the representation of « Things », it is more about the relations between them, which is ultimately our focus. We create our basic types and then, if we need to have more complex types, we can combine them with various operators e.g. A + B (Either A or B or the Union Type), A x B (A times B, Or the pair type) and a few others.

FP Patterns 101

There we are, the real point of all this rambling, FP patterns, not to be confused with the Design Patterns from OOP, FP patterns is about recognizing repetition, you know, the real meaning of patterns (you need to try harder OOP).
Let’s then talk about Currying, Functors, Catamorphism and Anamorphism (or respectively, Currying, Map, Fold and Unfold). For the sake of simplicity, I will use Lists to explain the last three:

Currying

Curry (not the dish) is what we do when we transform functions with more than one argument into functions which receives one argument and then returning a function responsable for receiving the remaining arguments. This eases the possibility of composition/Chaining.

curry :: ((a,b)->c) -> a -> b -> c  

Map aka Functor

Map aka Functor is the application of a function in a complex structure. For lists, it looks like:

map :: (a->b) -> [a] -> [b]  

e.g. When you want to double the elements of a list, instead of the good old for loop, why not:

map ((elem)=> elem * 2) [1,2,3] = map (*2) [1,2,3] = [2,4,6]  

Reduce aka Catamorphism aka Fold

Catamorphism from the Greek: κατά « downwards » and μορφή « form, shape » or also known Fold is the ability to reduce a structure into another structure, also know as the Conquer from Divide and Conquer.

fold :: forall a b c . (a->b->b) -> b -> [a] -> b  

e.g Want to compute the somation of a list of integers? No problem

fold ((elem,acc)=> acc + elem) 0 [1,2,3] = 6  

To be more explicit, fold is the recursive function with input type list and output whatever type you want. If we deconstruct our example in the corresponding function :

sum :: [int] -> int  
sum [] = 0 -- second argument of our fold  
sum (x:xs) = x + sum xs -- same behaviour as the functions received as argument in our fold example  

Generate aka Anamorphism aka Unfold

Anamorphism from the Greek ἀνά « upwards » and μορφή « form, shape » or also known as Unfold is the ability to generate a structure from another structure, the Divide of the Divide and Conquer.

unfold :: (b->Maybe (Tuple a b)) -> b -> [a]  

This seems more complicated however the function (b->(Tuple a b)) is responsible for generating the elements of the output list.

e.g. generate list from 10 to 1

unfold (seed -> if seed  0 then Nothing else Just(seed,seed-1)) 10 = [10,9,8,7,6,5,4,3,2,1] generateList:: Int -> [Int] generateList seed = if seed  0  
then []  
else seed:(generateList seed-1)  

A Shift towards FP

After analyzing some of the patterns of FP, the question which you asked in your head at the beginning of the article (remember). Why is every language, including Javascript, moving towards functional programming? I think if you read until this point you understand the fact that functions are powerful abstraction. There are easy to read and code and since we move towards coding tiny functions this enables us to glue them together like Legos in order to build bigger programs.

Written by Yoan Ribeiro

PS : You can take a look to my talk and the talk of BloodyOwl (in French) about PureScript and Reason there :

http://blog.js-republic.com/meetup-js-star-reason-purescript-programmation-fp/


Tag cloud