Rescript and Functional Programming

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?

4 Likes

Hello! Welcome =)

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.

For stdlib: the usage heuristics is here.

3 Likes

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 :sweat_smile:). I hope this, in some way answer your question

5 Likes

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 :slight_smile:

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?

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.

5 Likes

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.

1 Like

Yep, and I don’t mean that! :stuck_out_tongue_winking_eye: (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.

and if you are interested in Functors, this is the best explanation about this topic i could find: http://2ality.com/2018/01/functors-reasonml.html

4 Likes

I’m glad we finally got pass that! :stuck_out_tongue:

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?

2 Likes

I am definitely in the crowd “passing functions around and making sure things aren’t mutable” :sweat_smile: - love that quote :smiley:

1 Like

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.

1 Like

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 :smiley:

1 Like

Thank you @chenglou

Your proposed FP concepts I should master (on top of the basic FP parts) seem like a sweet spot for me that balances between pragmatism and elegance.

1 Like

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.

7 Likes

Wow, I wasn’t expecting that!

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.

1 Like

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.

1 Like

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.

Thank you, I really appreciate it!

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)

This is a joke, by the way. It’s not meant to be taken seriously: http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html

Unfortunately, the internet being what it is, people started quoting it all over the place and it became another thing that intimidates newcomers.

You’re talking about category-theory functors, I believe others in this thread are talking about ReScript functors, which are a different thing.

4 Likes

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.

5 Likes