Where programmers share ideas and help each other grow. All developers are welcome to submit stories, tutorials, questions, or anything worth discussing. The front page is curated by the folks behind @ThePracticalDev.
Have fun and don't be afraid to contribute, everyone's perspective is valuable! ✌️
Where you leave commits is very subjective, and best left to the programmer to decide where the logical breaks should be. I follow these rules:
1) Start a new commit with a message describing your planned change immediately before doing any real work. Use an arbitrary file with a date or version number or whatever.
2) Commit frequently, --amend is your friend.
3) Don't be afraid to amend your commit message when you have to change your mind about what you need to do, but...
4) Stick to simple incremental changes that focus on the direction in which your program is evolving.
5) A commit (or its final amendment) must be a complete change, compile and run without obvious errors for all targets, and pass all tests.
FP knowledge is kind of universal. You can write pure code in just about any language.
The experience I herein describe is from my time with Haskell.
In FP you don't modify anything yourself, you just tell the compiler how to make convert data from type a to type b.
My mindset is that every program only converts some data into a different representation, be it input from the user and some database that is being converted into an HTML document or just some input that is converted to it's base64 representation.
Especially if you adhere to Unix philosophy you end up writing little "subprograms" that just do a simple job like base64.
FP then gives you a huge set of readily available functions to achieve exactly that.
It also forbids you to do anything impure, so you end up with small little functions that transform some a to some b and bs to cs. Then you just call them along the lines of foo(bar(baz)) and return the result to the user.
Why is this so popular you ask?
Well, it makes a lot of things disappear: race conditions, irreproducible behaviour, unintended side-effects just to name a few.
It also makes a lot of things easier.
There is for example the maintenance. You can easily replace a function that does not perform as it should and, once it works, it probably keeps on working forever.
How about testing? If you have a high unit-test coverage then you have actually tested everything that could go wrong because there are no side-effects in pure functions.
If you profile your application you see how long each function takes and how often it's called. This makes it easy to find a bad performing function and simply rewrite it, if possible, or reduce it's usage or the way it's used.
Adding a feature is as easy as adding the new functions and putting a call to them somewhere. You cannot break any of the existing parts of the program if you do not touch them due to the complete lack of side-effects.
Just for the FP people some corrections:
Yes, there are side effects, for example IO, but you either have some Monads do the job or abstract over them using e.g. the interact function in Haskell.