I've been learning some functional programming with JavaScript lately, and wanted to put my knowledge to the test by writing a simple ToDo app with just functional programming. However, I'm not sure how does one store the state of the list in a pure functional way, since functions are not allowed to have side effects. Let me explain with an example.
Let's say I have a constructor called "Item", which just has the task to be done, and a uuid to identify that item. I also have an items array, which holds all the current items, and an "add" and "delete" functions, like so:
function Item(name){
this.name = name;
this.uuid = uuid(); //uuid is a function that returns a new uuid
}
const items = [];
function addItem(name){
const newItem = new Item(name);
items.push(newItem);
}
function deleteItem(uuid){
const filteredItems = items.filter(item => item.uuid !== uuid);
items = filteredItems
}
Now this works perfectly, but as you can see functions are not pure: they do have side effects and don't return anything. With this in mind, I try to make it functional like this:
function Item(name){
this.name = name;
this.uuid = uuid(); //uuid is a function that returns a new uuid
}
const items = [];
function addItem(array, constructor, name){
const newItem = new constructor(name);
return array.concat(newItem);
}
function removeItem(array, uuid){
return array.filter(item => item.uuid !== uuid);
}
Now the functions are pure (or so I think, correct me if I'm wrong), but in order to store the list of items, I need to create a new array each time I add or remove an item. Not only this seems incredibly inefficient, but I'm also not sure how to properly implement it. Let's say that I want to add a new item to the list each time a button is pressed in the DOM:
const button = document.querySelector("#button") //button selector
button.addEventListener("click", buttonClicked)
function buttonClicked(){
const name = document.querySelector("#name").value
const newListOfItems = addItem(items, Item, name);
}
This is once again not purely functional, but there is yet another problem: this will not work properly, because each time the function gets called, it will create a new array using the existing "items" array, which is itself not changing (always an empty array). To fix this, I can only think of two solutions: modifying the original "items" array or store a reference to the current items array, both of which involve the functions having some kind of side effects.
I've tried to look for ways to implement this but haven't been successful. Is there any way to fix this using pure functions?
Thanks in advance.
functions here should be unaware of the original item, to me. In a nutshell, they should not take care whether the array is new or not, they should just alter it. Somewhere else, in your code, you should handle whether the array to alter should be duplicated in order to avoid altering existing references or not. You can do that with pure functions, of course, you just need to think where you want to store the array and when you want to alter an array without affecting other references to it and when you don't.uuid()isn't pure. Randomness is also an effect. Don't focus on purity in Javascript though. Btw., you shouldn't rely onthisbut simply construct the object through a literal, becausethisis the first step towards side effects.Arraytype, which is inherently imperative. The functional paradigm requires its own purely functional data types with certain traits like structural sharing. Look into immutablejs in order to get an idea.