One great way to learn about FP is to read the documentation for Ramda.js [0] and tinker with their playground. For even more ideas check out Ramda-adjunct [1] and Fantasyland [2].
Anyway don’t put FP on a pedestal, main thing is to focus on the core principles of avoiding external mutation and making helper functions. Doesn’t always work because some languages like Rust don’t have legit support for currying (afaik in 2023 August), but in those cases you can hack it with builder methods to an extent.
Finally, if you want to understand the middle of the midwit meme, check out this wiki article and connect the free monoid to the Kleene star (0 or more copies of your pattern) and Kleene plus (1 or more copies of your pattern). Those are also in regex so it can help you remember the regex symbols. https://en.wikipedia.org/wiki/Free_monoid?wprov=sfti1
The simplest example might be {0}^* in which case we find:
“”, “0”, “00”, “000” …
a language with only one letter in the alphabet could still make all the natural numbers like that.
With Boolean alphabet (two variant enum) we have {0,1}^+ which omits the empty monoid by using the + operator:
“0”, “1”, “00”, “01”, …
note this sequence will eventually yield every possible Turing tape, which is the same thing as listing every possible series of coin flip results assuming no coins land on their side (Turing’s undecidability paradox might be bullshit, but that’s another story)
I meekly suggest, FP can save you days of headache if the only thing you do is clone your data and mutate the clone. Yes, that’s inefficient, so is dealing with infinite bugs due to state mutation in multiple places. Also, you can look into HAMTs / immutable / persistent data structures to juggle the pointers and copy-on-write on the storage data structure if you find yourself repeatedly cloning data then it would accelerate your stuff.
6 comments
[ 2.0 ms ] story [ 31.4 ms ] threadTwo great funcprog resources that I know of are:
1. Functional Programming in Haskell by Graham Hutton [0]
2. OCaml Programming: Correct + Efficient + Beautiful [1]
[0]: https://youtube.com/playlist?list=PLF1Z-APd9zK7usPMx3LGMZEHr...
[1]: https://cs3110.github.io/textbook/cover.html
[0] - https://ramdajs.com/docs/
[1] https://char0n.github.io/ramda-adjunct/4.0.0/index.html
[2] https://github.com/fantasyland/fantasy-land (A bit heavy on jargon)
Note there is a python version of Ramda available on pypi and there’s a lot of FP tidbits inside JAX:
3. https://pypi.org/project/ramda/ (Worth making your own version if you want to learn, though)
4. For nested data, JAX tree_util is epic: https://jax.readthedocs.io/en/latest/jax.tree_util.html and also their curry implementation is funny: https://github.com/google/jax/blob/4ac2bdc2b1d71ec0010412a32...
Anyway don’t put FP on a pedestal, main thing is to focus on the core principles of avoiding external mutation and making helper functions. Doesn’t always work because some languages like Rust don’t have legit support for currying (afaik in 2023 August), but in those cases you can hack it with builder methods to an extent.
Finally, if you want to understand the middle of the midwit meme, check out this wiki article and connect the free monoid to the Kleene star (0 or more copies of your pattern) and Kleene plus (1 or more copies of your pattern). Those are also in regex so it can help you remember the regex symbols. https://en.wikipedia.org/wiki/Free_monoid?wprov=sfti1
The simplest example might be {0}^* in which case we find:
“”, “0”, “00”, “000” … a language with only one letter in the alphabet could still make all the natural numbers like that.
With Boolean alphabet (two variant enum) we have {0,1}^+ which omits the empty monoid by using the + operator:
“0”, “1”, “00”, “01”, …
note this sequence will eventually yield every possible Turing tape, which is the same thing as listing every possible series of coin flip results assuming no coins land on their side (Turing’s undecidability paradox might be bullshit, but that’s another story)
I meekly suggest, FP can save you days of headache if the only thing you do is clone your data and mutate the clone. Yes, that’s inefficient, so is dealing with infinite bugs due to state mutation in multiple places. Also, you can look into HAMTs / immutable / persistent data structures to juggle the pointers and copy-on-write on the storage data structure if you find yourself repeatedly cloning data then it would accelerate your stuff.
Options include: Python: Immutables https://pypi.org/project/immutables/ Rust: RPDS https://docs.rs/rpds/latest/rpds/ and Im https://docs.rs/im/latest/im/
Rust isn’t great for letting you do FP things like other langua...