constDogFunction=dog=>({map:f=>DogFunction(f(dog));});constwalk=isRaining=>dog=>({...dog,// if there are some other fieldscolor:isRaining||dog.color==='dirty'?'dirty':dog.color,needToWash:dog.needToWash||isRaining,});constbelka=DogFunction({color:'white',needToWash:false});constbelkaAfterWalking=belka.map(walk()).map(walk(true)).map(walk());// belka didn't mutate: { color: 'white', needToWash: false }// belkaAfterWalking: { color: 'dirty', needToWash: true }
DogFunction can have a "walk" method but it is more OOP way. Compare how different it is comparing to the previous more abstract example:
constDogFunction=dog=>({walk:isRaining=>DogFunction({...dog,// if there are some other fieldscolor:isRaining||dog.color==='dirty'?'dirty':dog.color,needToWash:dog.needToWash||isRaining,}),constbelkaAfterWalking=belka.walk().walk(true).walk();// belka didn't mutate: { color: 'white', needToWash: false }// belkaAfterWalking: { color: 'dirty', needToWash: true }});
Still no mutations in between. FP and OOP can be similar only in very simple examples when mutations haven't joined the game.
It is better now w/o a side effect, however, the difference comes with adding more logic, e.g. changing an attribute of it.
Classic OOP way:
FP way based on the example:
DogFunction can have a "walk" method but it is more OOP way. Compare how different it is comparing to the previous more abstract example:
Still no mutations in between. FP and OOP can be similar only in very simple examples when mutations haven't joined the game.
Yes I mentioned this in the post as well