Finally, progress learning functional programming
Tags: beginners, functional, javascript, neuralnetwork
Published: 2019-05-08 09:54:21

---
title: Finally, progress learning functional programming
published: true
description: Shouting "Yes!" when code works the first time...
tags: beginner, functional, JavaScript, neural network
---

Functional programming is a tricky beast but I am finding it unexpectedly liberating. Here's an example that might help you make progress too.

It has a different sense of reasoning and problem solving concepts from how most of us learnt to code. I've gone through the process of developing (essentially) vanilla JavaScript apps with jQuery (fine until you have to maintain your code). And (fortunately?) only started to consider React once Hooks arrived (previously React seemed neither one thing nor another).

Suddenly the benefits of functional programming (FP) seemed well worth investigating properly.
#Learning FP
I read a couple books ([this one](https://www.goodreads.com/book/show/37482278-functional-light-javascript) and [another](https://github.com/MostlyAdequate/mostly-adequate-guide)), plus a few Medium and DEV articles. Then took a more direct step and went through [this](https://www.udemy.com/functional-programming-for-beginners-with-javascript/) whole Udemy course. I must admit to skipping some of the later exercises - I find it really tough to focus sufficiently on problems for their own sake. Need a real issue to implement!

So it was lucky that I was in the latter stages of developing an app which has a very data hungry modal dialog (not yet in production release, will try to update later with a link). So I built this using the framework applied in the Udemy course - and it was very liberating. The framework isn't React but has similarities, with virtual DOM, data driven state, protection from mutation, clean event loops and complex UI that is easy to update or extend.
#But
After the reading and the course, did I really think I'd "got" it? By which I mean the fundamental reasoning and problem solving concepts - things like:
* no data mutation
* no `for` loops
* pure functions

Somewhat...

Understanding these in principle is fine, but it takes practice, as for any code reasoning, to re-configure your problem solving processes.

The data mutation thing I got first, although it is tightly linked to the concept of pure functions:
* Keep functions simple
* Think in terms of individual functional steps rather than integrated bundles of logic
* Return new versions of your data
* Make sure to avoid library functions which mutate the passed-in data (e.g. `Array.slice()` rather than `Array.splice()`)

I can't say my code is perfect in these regards but I think I'm doing OK at knowing when there is a problem and whether I care.
#Drop the loop
Dropping `for` loops has been the trickiest. Recursion has always filled me with dread and examples of `map()` and `reduce()` are typically quite simple. They give you the technical syntax but not really the reasoning process you need in order to actually use them.
# Finally 'getting it'
This morning I did a rare thing and shouted "Yes! OMG it actually worked!" when a piece of refactored code worked the first time. A joyous occasion. I won't claim that the refactor is perfect FP but for me the diff is instructive - hope you find it so as well.

The code below is training a neural network (using [Brain.js](https://github.com/BrainJS/brain.js)) and returning some test results to a web page. In the `try` block, the CSV data file is processed (get the training and test data) followed by returning the results via the `res` object. I used a `forEach` loop to iterate through the CSV data, responding according to need with some nested if/else control logic.
So I started with this procedural tangle:
{% gist https://gist.github.com/johnkazer/f381540c039945448b47d90340a1e5b4 %}
Which I turned into the following, whilst also adding some additional logic to analyse the neural network (a bit). The long `if` statement in the `parser()` function has been simplified to a few lines, kicking off a recursive function. I also replaced the two `forEach` loops which processed the raw training and test data with functions `definedTrainingDataset()` and `generatedTestResults()` using `map()`. Finally, the new functionality `identifySignificantInputs()` I added to process the network's weights uses a `reduce()` within a `map()` to iterate (or map) through the hidden nodes and sum up (or reduce) each node's set of weights.
{% gist https://gist.github.com/johnkazer/ee7b608b41bee1f67c3db900bd0e1c0a %}
Now I just need to write it this way _first_ time rather than with a re-factor!

For reference, here is the (edited for brevity) neural network definition object that contains the weights.
{% gist https://gist.github.com/johnkazer/6c1b8f1f0198717ac065905f63b77c01 %}