Functional Programming, you've heard the buzz, now what?

Functional Programming, you've heard the buzz, now what?
0

#1

Where to start

If you are reading this, you are probably in the same position as most developers, you already know the definition of functional programming, you’re keen to learn more, but don’t know where to start.
Over the last couple of months I’ve been trying courses and searching for beginner friendly content that will help you on that journey. Here is what I can recommend to get you started.

  1. Learn the fundamentals of functional programming — for free, in your inbox - an excellent intro to fp from Preethi Kasireddy

  2. JavaScript Allongé - by Reginald Braithwaite an excellent read on declarative modern JavaScript.

  3. Fundamentals of Functional Programming in JavaScript by Nate Taylor. You will need a PluralSight subscription for this one.

  4. repl to try out new functions and function composition for yourself. This is the most important step of all.

There are many other resources that I could have listed here, but it is easy to get overwhelmed and give up before you get started. The most important thing here is to have fun and practice what you have learnt, as much as possible.

Tackle some challenges

Congratulations if you have made it this far, even though fp is great fun, it takes a fair bit of persistence, well done!
Time to test your hard gained knowledge!
Please come join us on Exercism to tackle some challenges in ES6 or JavaScript. I’ve set up a team for like minded fp’ers at a beginner level. If you can’t complete a challenge, just submit anything and that way other team members can leave helpful code reviews to help you get over the hump. Setup can also be a bit of challenge, so let me know if you get stuck and I’ll try and help out. Barely Functional exercism team

Next steps

This is where it starts to get really exciting and equally very frustrating. I’ll break this up into next steps in JavaScript and next steps in other functional languages.

Sticking with the JavaScript World that we all know and love:

  1. DrBoolean’s mostly adequate guide e-book

  2. Professor Frisby Introduces Composable Functional JavaScript egghead.io video course

  3. Take a look at JS libraries like Ramda or lodashFP. They offer most of the functionality you are looking for, without having to write your own library.

  4. If this is all too easy for you, check out Sanctuary JS


Although JS can be considered a Functional Programming language, it is not a pure functional programming language. Many of the more advanced patterns can become quite contrived and are so difficult to implement, they probably aren’t worth attempting. Time to try something new.
An excellent place to start is Elm. I can’t offer enough praise for their amazing compiler or the super friendly community. Sure there is plenty of competition popping up in the frontend FP arena, but none are quite as beginner friendly(at present).

This is where I run out of experience. My personal journey has taken me down the path of starting to learn Haskell. It is an amazing language. For example this is a way to create a list of even numbers in the range 1 to 10, that aren’t 6: [ x | x <- [1…10], x mod 2 == 0, x/=6 ]. Try that for yourself in JS and let me know if you manage it in one line. If that has peaked your interest, check out these resources:

If you haven’t already joined, come join us at Barely Functional Exercism and test your new Elm, Haskell or JS skills and help out your fellow learners, by leaving code reviews.


#2

Challenge accepted:

const range10EvensNot6 = () => Array.from(new Array(10), (x, i) => i + 1).filter((el) => el !== 6 && el % 2 === 0);

:smiley:

Thanks for all the great info and resources!


#3

and we have a challenge winner…:laughing:


#5

Definitely going to need this if I want to level up my skills. Bookmarked.

Thanks a lot!!! :slight_smile:


#6

Liked your solution so much that I made a small modification for a function to handle any range:

const rangeNEvensNot6 = n => [...Array(Math.floor(n/2)+1)].map((v,i) => 2*i).filter(v => v != 6 && v);

#7

I’m inspired by everyone’s efforts, but I think the Haskell version is unbeatable, as it manages it in one loop.
evenSquaresNot6upTo10 = [x | x <- [2, 4…10], x/=6]
const rangeNEvensNot6a = Array.from(Array(5),(val,i)=>(i + 1)*2).filter(x => x!==6);
const rangeNEvensNot6b = Array.from(Array(5).keys()).map(x => (x+1)*2).filter(x => x!==6);
const rangeNEvensNot6c = Array.from(Array(5)).map((x, i) => (i+1)2).filter(x => x!==6);
const rangeNEvensNot6d = Array(5).fill(2).map((x, i) => x
i+2).filter(x => x!==6);
const rangeNEvensNot6withRamda = R.range(2, 11).filter( n => n % 2 === 0 && n !==6);

I should add an important note here, while making functions as concise as possible is really fun, it can defeat one of the main goals of functional programming (to be declarative), unless you name your functions well. Everyone seems to be on top of this, so it is probably a mute point :zipper_mouth_face:


#8

generalizing a bit more

f(k, n) returns 0 < i <= n: i%2 == 0 && i != k

f=(k, n)=>Array.from({length:n}, (x,i)=>i%2 && i+1 !== k? i+1: 0).filter(x=>x)
f(6, 10) // [2, 4, 8, 10]

it avoids an unnecessary intermediate array with the Array.from callback

it can be done in a single callback with reduce

f=(k,n)=>Array.from({length:n}).reduce((a,x,i)=>(i%2 && i+1 !== k?a.push(i+1):null, a), [])
f(6, 10) // [2, 4, 8, 10]

#9

heh

const range10EvensNot6  = [...takeUntil(n => n > 10, filter(n => n != 6, countUp(2,2)))];

Given that

function * countUp(start = 1, step = 1) {
  let n = start;
  while(true) {
    yield n;
    n += step;
  }
}

function * filter(fn, iterable) {
  for(let it of iterable) {
    if(fn(it)) yield it;
  }
}

function takeUntil(fn, iterable) {
  for (let it of iterable) {
    if (fn(it)) return;
    yield it;
  }
}

and if, if the pipeline operator makes it into the language, the functions that take an iterator (filter, takeUntil) would have to be modified to be the iterator argument first, but I think could do (should actually be usable if transformed via the Babel stage-0 plugin, but i don’t know how it plays with generator functions):

const range10EvensNot6  = [...(countUp(2,2) |> filter(n => n != 6) |> takeUntil(n => n > 10))];

Anyway, to add to resources, the book Functional Javascript by Michael Fogus is excellent, oldish (uses Underscore to teach the concepts, but everything is still applicable). There is another book with the same title from Manning which is also really good, but the O’Reilly one by Fogus is better. Most useful JS book I’ve read, well written, very clear.

OCaml and Clojure are fully-featured functional languages that compile to JS (via BuckleScript and ClojureScript respectively). I have never used CS, but OCaml I have, and the OCaml syntax Reason has been built specifically to be approachable for programmers coming from JS (and is very easy to set up and get started with), and OCaml itself is excellent (similar to Haskell but more practical & easier to learn I guess) - Real World OCaml is the book for learning the language.

This is worth reading: https://hackernoon.com/functional-programming-in-javascript-is-an-antipattern-58526819f21e

Also that Professor Frisby course on Egghead; ymmv but I don’t think I’ve hated anything related to programming more than I’ve hated that, found the setup to be one of the stupidest and most aggravating things I’ve ever seen (and I love why’s (poignant) Guide to Ruby, which I guess is the kind of level they were aiming for with the Egghead course)


#10

All great responses and valid opinions. So, lets keep the ball rolling…

What does JavaScript do really well as a Functional Programming language?

I’ll start with currying.
For those that haven’t come across it yet:

  • Currying uses the partial application pattern

  • Curried functions must be pure(they can’t produce side effects or be effected by anything other than the arguments they are called with

  • Currying is the art of applying one argument to a pure function, for functions that usually take multiple arguments.

Wow, that sounded a lot easier to understand in my head. Well thankfully, it’s a very easy pattern to understand once seen and easy to implement with arrow functions.
Sorry about this example in advance, please share something better.
lets start with a fairly useless function and turn it into something more versatile:
const add = (a, b) => a + b;
//add(3, 3) === 6

    //Curry
    const curryAdd = a=>b=>  a + b;
    const addThree = curryAdd(3);
    // addThree(3) === 6
    // addThree(1) === 4

#11

Partial application is not the same as currying. What you’ve described is partial application implemented using currying, but they’re two different things.

Currying is converting a function with n arguments into n functions each taking one argument:

function addThreeInts(a, b, c) {
  return a + b + c
}

function addThreeIntsCurried(a) {
  return function(b) {
    return function(c) {
      a + b + c;
    }
  }
}

// or using arrows:

const addThreeInts Curried = a => b => c => a + b + c;

They are called differently, but work the same; the curried version you need to call each function in turn, so the syntax gets a bit clumsy:

addThreeInts(1,2,3) // 6
addThreeIntsCurried(1)(2)(3) // 6

With partial application, what you’re doing is returning one function with one of the arguments “filled in”. You can do this via currying on the the original function, or JS has the bind method. Ex:

const addOneToTwoInts = addThreeInts.bind(null, 1);
const addOneToTwoIntsCurried = addThreeIntsCurried(1);

Called like:

addOneToTwoInts(2, 3)  // 6
addOneToTwoIntsCurried(2)(3) // 6

(re bind, this article by Pascal Hertig is good).


Re currying this doesn’t explain why it’s useful. Partial application is quite useful in JS, and it’s pretty easy to demonstrate why. Currying less so. Currying is extremely useful in languages whose functions take one and only one argument (MLs - Haskell, OCaml, SML, F#). There isn’t really choice for it to be important; you need a way to pass multiple arguments to functions, so they provide syntactic sugar over currying to allow that. So in ReasonML:

let add (a, b) => a + b;

This add function takes a single argument: a tuple of two ints, and adds the two values together. It is NOT the same as:

let add a b => a + b;

Which is a function that takes a single int, returns another function that takes a single int, and adds the values together. The second one is curried, and could be written like:

let add = fun a => fun b => a + b;

The type signatures, describing how they work, look like:

let add : func = fun (int, int) => int

and

let add: func = fun int => fun int => int

JavaScript does not work like that, and although the technique is useful occasionally, it isn’t built into the language - functions can take any number of arguments. This makes currying slightly clumsy in practice. More importantly, if the technique is used, you need to be extremely careful writing the code, because JS cannot reliably detect errors - it’ll just try to execute the code and make it work, vs an ML which will detect errors at the compilation stage.


#12

So pretty much exactly what I wrote, but expressed differently. I like your explanation though.


#13

What I was trying to get across [badly, sorry] though is that currying, despite always being one of the first things brought up by FP weenies, isn’t particularly useful in the context of JS, generally it’s just confusing. It is useful in ML languages, but that’s because it’s integral to how they work. It has its uses, but overall it’s not that practical because of how JS works; it needs lots of boilerplate to avoid edge cases, and calling curried functions requires a confusing syntax. The pattern is ofelten poisonous as well: once one thing is curried, arguments have to be in a very specific order, and that goes for the things they call and the things that call them, it can infect programs and make them fragile, overcomplex

Partial application is very useful, but it doesn’t necessarily have to have anything to do with currying: one of most common use cases is in event handlers, where you just bind the handler.


#14

Don’t worry, it’s a good learning opportunity and stimulating to get a different perspective. Now correct me if I’m wrong, but to my understanding, currying isn’t just the process of converting a function to a function that can be partially applied. There are also rules. Types should be the same and functions should be pure, only one argument can be passed at a time and only one value can be returned (maybe this isn’t the case in JS?). To my mind, this isn’t any harder to understand than applying multiple values at once, if anything it’s easier to reason about and you are less likely to mix up the order in which they are called, at least in ES6, I wouldn’t even try in vanilla JS. I also thought that partial application would be more problematic, as it doesn’t conform to those rules. Allowing for multiple arguments to be called at a time, makes it very hard to reason about how many have been applied or need to be applied, leading to the issues you have highlighted.
The pattern is used quite successfully in Redux and I heard bind() is a curried function, although whether this makes a case for using it is highly dubious.
Anyway, you have changed my mind to the point of not wanting to recommend it, but I want to find out more.
Back to the initial question, what do you think works well in JS?


#15

Its not that it’s a difficult concept, and its definitely very useful, my issue with is that the way it gets brought up as a Very Important functional concept. It’s an abstraction with a tendency to obscure meaning, the way it’s described is often as a neat trick.

The core reason to use currying is to allow for function composition; if all functions only ever have one argument, it’s easier to glue them together.

What JS does really well is first-class functions - it’s really easy to pass functions around in exactly the same way as values, which is a common thing in functional languages (as an aside, that then leads to implementing simple currying being really easy).

Closures are used heavily JS, and they are what allows a very fluid functional style; + they allow functions to take the place o[and act as a much more lightweight version] of classes in OO languages.

JS is basically a form of the Lisp dialect Scheme, which is generally regarded as having strong functional aspects, and JS can do very nice things in the same functional style, piping data through a series of functions rather than operating on it via classes like OO languages.

What it doesn’t do well is immutability, which is generally useful for a functional language. So you need either rely on convention, which makes the code fragile, or use a library like Immutable.js. But then there is a boundary between code that uses the library and code that doesn’t - same as before, but you just move the fragile code. Redux for example relies on using immutable code, so there’s an issue there.

Elm, Bucklescript, Clojurescript fix that at the cost of needing to compile to JS.


Simple solution for search and replace challenge
#16


This post just popped up in my twitter feed and offers a better explanation than I gave.


#17

Personally, I think compiled to JS languages are great. It’s like a having a code mentor check your code and offer you feedback. Just like code mentors, you get good ones and not so good ones. Elm has the best one that I’ve tried so far. I haven’t tried bucklescript, I hear great things and I’m quite interested in learning more about reasonml, but for people starting out, like most on Free Code Camp, myself included, it seems like a step too far. The available learning resources and ecosystem appear to be more suited to experienced devs.


#18

Yeah, it definitely is. Elm is the best introduction imo. Reason/BuckleScript are expressly designed to make it easier for Facebook/Bloomberg developers to build large applications safely, and they kinda expect knowledge of OCaml at the minute - this is a good overview: https://jaredforsyth.com/2017/06/23/when-will-reasonml-be-ready/ (tl/dr play around with it by all means, but it’s ~6 months off being ready). They’re incorporating the niceties you get in Elm (the great errors, the auto formatting etc), and entire package including tooling is a single easy install, so I think Reason might beat out Elm in the long run, but have to wait and see.

As an aside, re functional programming, I’d unqualifiedly recommend this course: https://www.coursera.org/learn/programming-languages

Hands-down one of the best courses I’ve done, first and main part is done in ML, then goes into writing a simple language using the lisp Racket, then into comparing FP with OO using Ruby, everything taught is likely to be helpful re developing with JS/compile-to-js-langs (has the best explanation of how closure actually works I’ve seen, for example)


#19

Edx has a great course that is taught using Racket. I wrote about it here UBCx How to Code - Systematic Program Design
I’d suggest the course to everyone.

The lisps and elixir/erlang are probably an easier introduction to FP than the ML’s like elm, haskell or ocaml.
They are dynamic languages so you don’t need to worry about the type system, ( well you do, but not in the sameway.)


#20

+1 on Systematic Program Design, Gregor Kiczales is a fantastic tutor, the course is amazing.


#21

Sorry for replying to an old discussion, but I am curious how many of you feel that functional programming comes at a cost of slower performance? My first taste of FP in free code camp was the Finders Keepers algorithm. I like running jsperf on my solution and against the other solutions.

My first taste of functional programming was through a Udemy Course. I started implementing function calls to the underscore.js library

I like the way FP looks, I just don’t like the way it performs. Recursion is another one of those things I try to avoid if I can due to performance issues.