How deep should I go learning Functional Programming concepts in order to get the best out of Rescript?
I understand the intention of RS is to be on the pragmatic side and not to lean too much towards either imperative or functional paradigms so that it would be more approachable by developers with JS/TS experience and you know - to get things done with the best tools available for the job at hand and not have just a hammer (FP) and force everything to look like a nail (function).
That being said, it seems in RS a developer such as myself with JS/TS background could benefit greatly by learning some theory around FP. Functor and itās map function seems to be a must, but where should I go from there, if I want to stay true to the RS standard libraries and do not intend to use a FP library such as Relude?
The point of ReScriptās pragmatism isnāt (just) to have a language thatās familiar to existing JS/TS devs. Sure, familiarity hits a sweet spot, but the larger point is that said pragmatic practices are actually more effective for your software. Thereās a mistaken impression that our stance on familiarity is compromising software quality, when in reality, we stand by pragmatism and that often happens to induce familiarity.
So when the team or the community dissuades concept X (e.g. some FP stuff), itās not always because itās āscaryā to newcomers; itās often because X turns out not to be as effective as proclaimed and should be used in more limited fashion than what some learners are advertising.
However, you donāt know when not to use something until youāve learned it! In that sense, youāre right that folks might benefit from being exposed to the concepts.
Functor and itās map function seems to be a must
Theyāre not, but you can learn them for fun. Try using them more will help you develop a mature mindset so that next time you spot them, your experience might tell you to maybe avoid these and simplify the code. Even Belt uses some Functor (and more), but thatās because we had no choice, not because we want to encourage it.
Ok, so take my answer with grain of salt because I am still learning.
TLDR: Start build stuff and ask here for directions if you are lost.
I very often started with this approach similiar to yours. First learn the theory and then try to apply it. But it makes me feel like fraud, i thought that i understand some concept but i didnt have the feeling that this was something useful.
The moment that it clicked for me was that I had a lot of logic in my component that needed to be changed. After 2 hours fixing compiling errors, i was really frustrated that it took that long (in js i will be done in 30 minutes, and I will have more time to test it in browser, then fix it, check again fix it etc). But the beauty of the rescript version was that after compiler said ālooks fineā - shit just worked.
I run the app, clicked on it, tested all edge cases and it seemed working perfectly fine, and I try to understand how this happened, why i donāt need fix anything. I started to read about it in more details and occured to me that I used in my code this monad thing that only the chosen ones can use, without knowing it. It was much more pleasent expierience than trying to grab concept like āit just monoid in the category of endofunctorsā¦ā - (I will definitely look into this, but I dont feel like it is a good starting point ). I hope this, in some way answer your question
Thank you for sharing. I agree, theory should go hand-in-hand with practical application, but I donāt think by just throwing stuff at the wall to see what sticks, would be the best approach either. Iām glad it works for you though
I think what @faliszek is trying to say is that he went bottom up, i.e. reaching upward but staying grounded, which is an excellent, recommended approach. I donāt think he was trying to throw things at the wall.
Hi, thanks for the reply. Can you please expand a little bit on what FP concepts besides Functors are you using in the Belt library?
For the most part:
A few variants and pattern matching
Higher-order functions
Some immutability
A few local recursions
Types, of course
Maybe a bit mundane, but itās a good thing to study where these are effectively applied.
The things you mentioned are already built into the language and are mostly covered by the docs. Iām already familiar with all these and using them more or less effectively. I was thinking about more abstract concepts that require developers to be a bit more proactive to learn and apply effectively. To help me come up with elegant design decisions that could be incredibly useful if applied correctly and at the same time would not require me to include full-fledged FP library such as Relude into the mix. So again, Iām not really interested in accidentally reinventing a Monad like @faliszek has, Iād like to learn about them beforehand.
Yep, and I donāt mean that! (see @chenglou answer), sorry for not being clear enough
If you really want to go first with learning FP concepts that is fine! I just find myself more enjoying writing Rescript if i can produce some actual software/app with it, and not go too deep with FP concepts.
For me Rescript was āfirst real FP languageā, and I assumed that yours too. (if this assumption is wrong and you have solid grasp of what FP is, and how and when can be useful to build things - then ignore all my answers in this topic ;p)
What I was meant to say is, that sometimes if you goal is to build something with Rescript it is not rewarding to go deep with some of the concepts that can be pretty abstract, and might disencourage some people.
But regarding FP concepts that I found useful working with Rescript, @chenglou answer cover most of them. I will also add:
Currying
Reducer (i think it is a functional concept ^^) - very useful, specially when working with React.
No, I donāt have a strong functional programming background, hence the question. But also Iām not a novice who has never passed a function as an argument to another function before so mentioning something like higher-order functions doesnāt help me at all. I suppose I should have been more specific with my question.
As for currying, I already have an intuitive understanding how they work and Iām familiar with reducers from the time when I was using React Redux.
I also know about Functors and Applicatives thanks to a series of brilliant blog posts written by the author of Relude.
I havenāt yet found any good materials covering Monads though, which seem to come up pretty often when FP is mentioned.
I did realize however that going all the way deep into the FP concepts might not be the best use of my time because as far as Functional Programming is concerned, Rescript only goes as far as the āmundaneā stuff @chenglou mentioned.
To be able to use more abstract FP concepts effectively I would probably have to use a library like Relude which I currently do not want to introduce into my codebase.
Now, I would like to know which FP concepts beyond what Rescript supports natively, would be useful to know that would be just below this threshold where I would have to include a full FP library such as Relude. How deep should I go regarding learning stuff such as Monads, Semigroups etc? Does anyone here use any constructs like these without Relude or does everyone just stop at passing functions around and making sure things arenāt mutable?
To help me come up with elegant design decisions that could be incredibly useful if applied correctly
The elegance you seek will likely ultimately be in the form of these mundane FP features instead of the fancier ones I think, but I digress.
Does anyone here use any constructs like these
Thereās a pocket of folks in the community who do try those, but in general, not much.
Regarding how deep you should go: obviously thatās your choice, though in terms of learning, if you really want to learn for the sake of being able to preemptively use a concept for future use-cases (which, again, is fine as a learning process but maybe not for production): Iād say maybe look into GADT, polymorphic variant, currying and functor.
But learning aside, in general, itās preferred to stop at the mundane parts we mentioned earlier.
Thatās not the reaction I was expecting. I wanted to provoke people who think they are better than this to come forward to share their insight, but it looks like I failed at that spectacularly
Besides functional programming or not, I think another topic that is waaaaay more valuable, is thinking about good UI / UX patterns. A good book recommendation on the topic is Refactoring UI from the TailwindCSS folks.
A lot of FP enthusiasts talk about wonderful mathematical abstractions, and (apparently) clean looking code, but when they need to deliver a modern, good looking kind of user experience, their abstractions often fall apart and it gets really complicated really quick in scenarios where a well placed for loop and some mutable array would have been 10 times more effective.
I repeat myself over and over, but I will say it again: Functional Programming (as in, heavy weight topics such as Category Theory), is a good way to widen your horizon on whatās out there from a computer science / philosophical perspective, but if you are trying to find the best topic for seriously leveling up your ReScript / JS skills, look into usability / UI / human-centered design topics.
People waste so much time perfecting their code-golfing skills that they are forgetting about building products, unfortunately.
You may be right here, I mean I trust that you are because I donāt know enough about FP and Category Theory to be able to tell myself.
I had a feeling that one could go very deep into the FP world with diminishing returns as far as productivity goes as you go deeper. I just wanted to know how deep I should go to get the most benefit.
I have to admit, I havenāt looked that much into the usability side of things either so thatās definitely something I want to know more about. Thank you for the book recommendation, I will make sure to read it.
Also I really appreciate @faliszekās input. When someone in the community starts out by building e.g. a React application, and he / she is trying to build a certain experience, itās way easier to give feedback on how to improve / simplify the code and remove any doubts. If the learner feels that the code isnāt right, then there is probably a more experienced ReScript user who is willing to help figuring it out.
If someone starts out e.g. learning the piano, he / she is probably not going to start with Mozartās ways of composing sheet music before they even got the first one or two years of serious practise out of their simpler repertoire. They need to learn the ins and outs of their instrument first. Our instrument is plain ReScript without any crazy gimmicks and / or type hackeries (if we can prevent it).
Also itās really hard to tell someone to ā¦ I donāt knowā¦ learn about functors, or monads, or applicatives, without even properly understanding what they are trying to solve.
Another excellent book I can recommend is The Design of Everyday Things by Don Norman. A timeless piece that applies to all kinds of design, not only web applications. The principles of human-centered design are pretty much independent from the medium.
What I always recommend for people new to FP is Prof. Dan Grossmanās free online course, Programming Languages Part A. I feel it goes into exactly the right level of depth for teaching how to architect programs in the āMLā style (which includes ReScript). It teaches:
Expression-oriented programming
Understanding both the syntax and semantics of the ML language
Understanding currying, higher-order functions
Understanding algebraic data types and pattern matching
How type inference works (this one is super useful when dealing with compiler error messages)
Modular programming (using modules for abstraction and architecture)
Iām kind of answering my own question here a bit, but I found Functors to be incredibly useful for understanding how Option type works and why it has a map function, which seemed very odd coming from Js/Ts where only arrays can be mapped.
Iām currently looking at the Belt.Option.flatMap function which looks a lot like bind from a Monad. Now even with very little knowledge I have about Monads, Iām able to tell that Belt.Option.flatMap would be very convenient to combine multiple null checks together into a chain that would return None whenever one of the functions in the chain returns None. The docs donāt mention any of this and it wouldnāt be immediately obvious if you took the bottom up approach to learning.
I would argue that if you didnāt know the full potential flatMap has, but you had code that would benefit from chaining flatMap functions together, chances are you would just settle with nested switch statements or what have you, not even knowing it could be made to look much nicer and not reaching out to the community in the first place - I know I wouldnāt.
Apparently knowing a thing or two about Monads is also very useful when working with Rescript and itās standard library, at least it is for me.
So as far as Category Theory goes in the context of Rescript without additional FP libraries, I have Functors and Monads in my list. Please let me know if I missed anything.
Iām currently looking to become a better (Rescript) developer, I will be looking design related material another time.