<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tomasz Cichocinski</title>
    <description>The latest articles on DEV Community by Tomasz Cichocinski (@baransu).</description>
    <link>https://dev.to/baransu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F321039%2F8b00c180-36a3-4ff3-8bfb-21b522f763a5.jpg</url>
      <title>DEV Community: Tomasz Cichocinski</title>
      <link>https://dev.to/baransu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/baransu"/>
    <language>en</language>
    <item>
      <title>How Trying New Programming Languages Helped Me Grow as a Software Engineer</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Sat, 22 Oct 2022 23:13:13 +0000</pubDate>
      <link>https://dev.to/baransu/how-trying-new-programming-languages-helped-me-grow-as-a-software-engineer-38jc</link>
      <guid>https://dev.to/baransu/how-trying-new-programming-languages-helped-me-grow-as-a-software-engineer-38jc</guid>
      <description>&lt;p&gt;When you use one programming language daily in your job as a Software Engineer, it's easy to fall into the trap of that language bubble. I want to show you how stepping outside your comfort zone and learning new languages and paradigms helped me grow as a Software Engineer.&lt;/p&gt;

&lt;p&gt;Over the years I've transitioned from frontend developer to full-stack developer and even tried professional game development! In that time, I managed and mentored developers at different stages of experience.&lt;/p&gt;

&lt;p&gt;Let's get right into it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Your primary programming language
&lt;/h2&gt;

&lt;p&gt;There are dozens of programming languages out there. In a lot of the cases we, as programmers, get fluent in one. Every so often, it's the first language we were taught in college or bootcamp. Maybe a more experienced friend recommended his favorite language to us. Or perhaps we had dreamt about making a specific type of software like video games and picked the most popular technology in the specialization. Once we land our first job, experience skyrockets.&lt;/p&gt;

&lt;p&gt;For me, JavaScript became my primary language and stays to this day. It wasn't my first language, but it was the most accessible for me during high school when I could write and run it on basically every computer without any special compiler or IDE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stepping outside comfort zone
&lt;/h2&gt;

&lt;p&gt;When still in high school, I got more and more experience creating many toy projects. From simple games to more complicated ones like "2d game engine" as an Electron application.&lt;/p&gt;

&lt;p&gt;Because of some of my programming teachers, I had a feeling that JavaScript is not a “real” programming language. In addition, it was JavaScript in the frontend environment, so you know, moving divs and buttons around, not algorithms.&lt;/p&gt;

&lt;p&gt;Around that time, I got introduced to Elixir by one of my close friends. I remember I was binge-watching conference talks about it for a week straight. It got me so inspired. It's a backend language and frontend was my natural environment, so it wasn't an easy thing to grasp for me at that time.&lt;/p&gt;

&lt;p&gt;Fortunately, functional programming, stuck with me.&lt;/p&gt;

&lt;p&gt;It started a spiral of new languages' fascination. Over the years I had programmed as a hobby or professionally with Elm, ReScript (formerly known as ReasonML or BuckleScript), OCaml, Haskell, Scala.&lt;/p&gt;

&lt;p&gt;I was still working with JavaScript almost daily, but learning so many new concepts like immutability, statelessness, monads, algebraic data types or actor model, made solving problems easier. It even helped me &lt;a href="https://www.youtube.com/watch?v=6lVAJddaTe8"&gt;give a lightning talk at international conference&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;And because certain concepts are more popular in different communities, it exposed me to so many programming architectures and patterns found in different kinds of systems like &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design"&gt;DDD (Domain-Driven design)&lt;/a&gt; or &lt;a href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/"&gt;Category Theory&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going back to junior level
&lt;/h2&gt;

&lt;p&gt;Fast-forward to March 2022, when I left my job at &lt;a href="https://jam.dev"&gt;jam.dev&lt;/a&gt; as an Engineering Lead.&lt;br&gt;
I decided I need a break to figure out what's the next thing I want to pursue in life.&lt;/p&gt;

&lt;p&gt;Since my early days with programming, I was always fascinated with video games and computer graphics. Back in high school I was experimenting with OpenGL, later with ray tracing and during last year's Christmas I started implementing Physically Based Renderer in Vulkan and Rust as a side project.&lt;/p&gt;

&lt;p&gt;During my first month off, I got back to that Vulkan and Rust project. Working on it, I came to conclusion what I want my next job to be: Graphics Programmer. But it's not an entry-level job if you don't have experience in this field. And because game development is the closest thing I could think of, I decided I'm doing to recruit to the local game dev company in Kraków where I live.&lt;/p&gt;

&lt;p&gt;I asked my friends about learning materials, and immediately dove into the world of C++ and Unreal Engine! It took my two weeks to complete &lt;a href="https://courses.tomlooman.com/p/unrealengine-cpp?coupon_code=COMMUNITY15"&gt;Tom Looman's Unreal Engine C++ course&lt;/a&gt; (which is incredible, I highly recommend it if you want to level up with Unreal Engine). I did a lot of reading about C++ and game development environment, made some simple game with SDL and after 2,5 months after quitting my Engineering Lead job I started my journey as Unreal Engine C++ programmer.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ew1hnxpB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1578119730229116940/8FBl6RMy_normal.jpg" alt="Tomasz Cichociński profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Tomasz Cichociński
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @_cichocinski
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I’m dropping web development and going into game development soon! 🤞🎉
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      12:22 PM - 27 May 2022
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1530162489392254977" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1530162489392254977" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1530162489392254977" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 

&lt;p&gt;I was expecting landing in junior position, and I wasn't concerned about salary. Surprisingly, I met requirements for a regular level 🤯. It turns out, general programming knowledge and years of experience with different technologies build up quite nice job profile 😅&lt;/p&gt;

&lt;p&gt;I'm no longer working at that company. I haven't renewed my contract after probation period. Therefore, I'm also not pursuing graphics programming as a career. But that's a story for a different time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try something new!
&lt;/h2&gt;

&lt;p&gt;It's completely fine to deepen one technology or one programming language knowledge. It's totally fine to just have a 9-5 job that pays the bills.&lt;br&gt;
But if you aim to level up, I'm highly recommending trying something new to broaden your perspective.&lt;/p&gt;

&lt;p&gt;If you're writing JavaScript, try some functional language like Elixir or ReScript. If you're already familiar with high level, garbage collected languages, try something low level like Rust or even C/C++. Play with different concurrency model like coroutines or actor model.&lt;/p&gt;

&lt;p&gt;You don't need to change your job, you don't need to ship products with it. Try to create something fun. You'll thank yourself later.&lt;/p&gt;

&lt;p&gt;If learning new programming language gave you a new perspective or opened some doors, don't hesitate to &lt;a href="https://twitter.com/intent/tweet?text=https://cichocinski.dev/blog/trying-new-programming-languages-helped-grow-software-engineer"&gt;share your story on Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>career</category>
      <category>growth</category>
    </item>
    <item>
      <title>I'm available for a free mentorship!</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Thu, 13 Oct 2022 22:29:13 +0000</pubDate>
      <link>https://dev.to/baransu/im-available-for-a-free-mentorship-2occ</link>
      <guid>https://dev.to/baransu/im-available-for-a-free-mentorship-2occ</guid>
      <description>&lt;p&gt;Hi! I'm Tomasz Cichociński 👋&lt;/p&gt;

&lt;p&gt;I have over 7 years of professional software engineering experience.&lt;/p&gt;

&lt;p&gt;I want to share my knowledge to &lt;strong&gt;empower juniors to become remarkable seniors&lt;/strong&gt;! I'm offering a &lt;strong&gt;free mentorship&lt;/strong&gt;, no hidden costs, it's my voluntary work!&lt;/p&gt;

&lt;p&gt;Do you feel you need help with your career? Or maybe you're stuck with some technical challenges?&lt;/p&gt;

&lt;p&gt;Learn more at: &lt;a href="https://cichocinski.dev/mentorship"&gt;cichocinski.dev/mentorship&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mentorship</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Using Default Exports Makes JavaScript Harder to Read!</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Wed, 12 Oct 2022 19:52:25 +0000</pubDate>
      <link>https://dev.to/baransu/using-default-exports-makes-javascript-harder-to-read-894</link>
      <guid>https://dev.to/baransu/using-default-exports-makes-javascript-harder-to-read-894</guid>
      <description>&lt;p&gt;In this blog post, I would like to show you how using JavaScript &lt;code&gt;export default&lt;/code&gt; hurts your codebase readability and refactorability. I'll also share some tips for using named exports!&lt;/p&gt;

&lt;p&gt;I like to treat my code as a clay, it's constantly evolving when I'm adding new features or changing existing ones. But using default exports not only makes it harder, it also adds complexity when using already existing code!&lt;/p&gt;

&lt;p&gt;Allow me to explain my reasoning!&lt;/p&gt;

&lt;h2&gt;
  
  
  You can export anonymous functions and values
&lt;/h2&gt;

&lt;p&gt;The first major problem with default exports is naming. You have to think about name import every time you include it. Not only that, but you're not forced to come up with a good name when creating a new function, as it's allowed to export anonymous values.&lt;/p&gt;

&lt;p&gt;Let's take a look at this simple JavaScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// cookies.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// baking 🍪 cookies logic&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;makeChocolateChipCookies&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./cookie.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have no idea what your default exported function from &lt;code&gt;cookies.js&lt;/code&gt; does. Of course, you can peek into the implementation or count on documentation, but it's definitely adds way more &lt;a href="https://en.wikipedia.org/wiki/Cognitive_load"&gt;cognitive load&lt;/a&gt;. You cannot spot right on what's that function is supposed to do.&lt;/p&gt;

&lt;p&gt;That forces you to think about naming that function in every place you want to use it. And naming things is hard. Maybe you wrote that function yourself, you know exactly what it's doing. But if you have a new team member joining, it's much harder for them to understand what this function is doing.&lt;/p&gt;

&lt;p&gt;That can also leads to other team members picking up different name when working on new features or refactoring existing code. And consistency and convention is a key for high performing teams! You can suggest a different name in the code review, but it's adding that complexity which could be easily avoided in the first place by using named exports.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's awkward when importing all from module
&lt;/h2&gt;

&lt;p&gt;JavaScript's import allows you to import everything from the module using &lt;code&gt;import * as X&lt;/code&gt; syntax. And default export is just available under &lt;code&gt;default&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Cookies&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./cookie.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// usage - yikes&lt;/span&gt;
&lt;span class="nx"&gt;Cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, if you export one thing it's not that important as you most likely won't use &lt;code&gt;import * as X&lt;/code&gt;. But you may want to group multiple things you import by module name for readability.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
  While I really love grouping module functions, and I think it's really&lt;br&gt;
  excellent practice for readability, it may not always be optimal for tree&lt;br&gt;
  shaking and may increase your bundle size!&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Default exports and folder-based routing
&lt;/h2&gt;

&lt;p&gt;Frameworks like Next.js or Remix force you to use default exports to define components with the folder-based routing. I'm not a big fan of forcing default exports in any case.&lt;/p&gt;

&lt;p&gt;TypeScript is lacking at this point some kind of support for "template" style exports, where a single file can export a predefined set of optional named exports in addition to the main default export. I would love to see something like that included in the language in the future, based on the popularity of previously mentioned frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using named exports
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Export each function individually, or export everything at once?
&lt;/h3&gt;

&lt;p&gt;Syntax allows you to use &lt;code&gt;export&lt;/code&gt; keyword before each function, type or value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeCookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// baking 🍪 cookies logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also possible to have export multiple things at the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeCookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// baking 🍪 cookies logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;eatCookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// eating 🍪 cookies logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makeCookies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eatCookies&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tend to prefer first approach as you clearly see whether the function you're reading is exported or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Named export alias to the rescue
&lt;/h3&gt;

&lt;p&gt;When you really need to use a different name, named exports allow &lt;strong&gt;named export aliases&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// cookies.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeCookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// baking 🍪 cookies logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makeCookies&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;makeCookiesWithStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./cookie.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Even though we have ES2015 (ES6) for quite some time already, I see a lot of default exports in all types of applications. They were introduced for CommonJS interoperability, and there is not much reason to use them in the internal code. I hope this post will help you convince your team not to use default exports when it's possible.&lt;/p&gt;

&lt;p&gt;If you have some default exports refactoring horror stories, don't hesitate to &lt;a href="https://twitter.com/intent/tweet?text=https://cichocinski.dev/using-default-exports-makes-javascript-harder"&gt;share them on Twitter&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;List of resources I used when researching this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export"&gt;https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.neufund.org/why-we-have-banned-default-exports-and-you-should-do-the-same-d51fdc2cf2ad"&gt;https://blog.neufund.org/why-we-have-banned-default-exports-and-you-should-do-the-same-d51fdc2cf2ad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Read more at &lt;a href="https://cichocinski.dev"&gt;cichocinski.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Improve your TypeScript with union types!</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Tue, 11 Oct 2022 12:13:04 +0000</pubDate>
      <link>https://dev.to/baransu/improve-your-typescript-with-union-types-145j</link>
      <guid>https://dev.to/baransu/improve-your-typescript-with-union-types-145j</guid>
      <description>&lt;p&gt;TypeScript's unions are a powerful feature. Let's dive into what they are and how you can use them to your advantage!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is union type?
&lt;/h2&gt;

&lt;p&gt;Union type is a set of types that are mutually exclusive. The name &lt;em&gt;union&lt;/em&gt; (or &lt;em&gt;sum type&lt;/em&gt;) comes from type theory. According to Wikipedia definition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Sum_type"&gt;sum type&lt;/a&gt; is a “tagged union”. That is, for types “A” and “B”, the type “A + B” holds either a term of type “A” or a term of type “B” and it knows which one it holds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in TypeScript it's similar to type theory (&lt;a href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/"&gt;as programming has a lot in common with set, type, and category theory&lt;/a&gt;). Let's look how official documentation defines union type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A union type is a type formed from two or more other types, representing values that may be &lt;em&gt;any one&lt;/em&gt; of those types. We refer to each of these types as the union’s &lt;em&gt;members&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most basic union type consists of two primitive types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Union&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// defined as inline type&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows to handle value which can be &lt;em&gt;either&lt;/em&gt; &lt;code&gt;number&lt;/code&gt; or a &lt;code&gt;string&lt;/code&gt;. This is great to prove code is type safe for all possible cases!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this guide, I'm not going to discuss &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; and how by default they are assignable to anything. Please do yourself a favor and start using &lt;a href="https://www.typescriptlang.org/tsconfig#strict"&gt;strict&lt;/a&gt; or at least &lt;a href="https://www.typescriptlang.org/tsconfig#strictNullChecks"&gt;strictNullChecks&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to use union type?
&lt;/h2&gt;

&lt;p&gt;Union types are perfect to express a finite number of known options, either primitive literals or objects (as discriminated union which we'll discuss those later), where single logic has to handle all the possible cases. A few great examples where union types shine are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Finite-state_machine"&gt;finite state machines&lt;/a&gt; (like React's &lt;code&gt;useReducer&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;event names&lt;/li&gt;
&lt;li&gt;object fields (using &lt;code&gt;keyof&lt;/code&gt; keyword)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You shouldn't use union types where the amount of possible options is too large, for example, a person's name as there is basically infinite number of options. Also keep in mind, they exist only at type level. They are striped out during compilation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to narrow union type?
&lt;/h2&gt;

&lt;p&gt;If your function logic can work most of the time on union type, it's great. But sooner or later you'll need to narrow it down to a specific &lt;em&gt;union member&lt;/em&gt;. There are few common patterns when narrowing union type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;typeof&lt;/code&gt; keyword
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;typeof&lt;/code&gt; Keyword is the most basic TypeScript tool. Unfortunately, it will work only with &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt; or &lt;code&gt;function&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getDateFullYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using &lt;code&gt;instanceof&lt;/code&gt; keyword
&lt;/h3&gt;

&lt;p&gt;While &lt;code&gt;typeof&lt;/code&gt; works great with primitives, &lt;code&gt;instanceof&lt;/code&gt; is great for the OOP feature of TypeScript — classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Developer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;develop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Manager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Developer&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Developer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;develop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is more OOP way of implementing &lt;code&gt;work&lt;/code&gt; function, but above example should do the job as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;switch&lt;/code&gt; statement
&lt;/h3&gt;

&lt;p&gt;Because union types can also consist of literal type members, not generic types but specific values, it's easy to use &lt;code&gt;switch&lt;/code&gt; or &lt;code&gt;if&lt;/code&gt; statements on them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;darkk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 🛑 Argument of type '"darkk"' is not assignable to parameter of type '"dark" | "light"'.(2345)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;String literals are really helpful for specifying a limited set of possible options, similar to enum&lt;br&gt;
being a great replacement for them, as there is not that much of added complexity as in enum's case. Using union type of string literals will help not make typos or passing generic &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you need to narrow type down from string to string literal, you can use a type guard function, we'll discuss later in this post!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Using “pattern match” object
&lt;/h3&gt;

&lt;p&gt;When talking about string or number literals, there is great trick allowing to achieve "pattern matching" in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, it may look noisy, but the advantage of this solution is the fact it's an expression not statement, which may be sometimes required in places like in JSX.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using type guard function
&lt;/h3&gt;

&lt;p&gt;One nice but advanced feature TypeScript provides us is the ability to define a custom &lt;strong&gt;type guard&lt;/strong&gt; function. By default, TypeScript provides us with built-in type guards like &lt;code&gt;typeof&lt;/code&gt;, &lt;code&gt;instanceof&lt;/code&gt; keywords we discussed earlier. There is also &lt;code&gt;Array.isArray()&lt;/code&gt; which is really handy when we need to handle either a single value or multiple values of the same type.&lt;/p&gt;

&lt;p&gt;But sometimes it's required to write something more specific to our business logic.&lt;br&gt;
Let's take a look at a simple function that narrows &lt;em&gt;any&lt;/em&gt; string to &lt;em&gt;either&lt;/em&gt; &lt;code&gt;dark&lt;/code&gt; or &lt;code&gt;light&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// default case&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is helpful when your value is coming from outside world (API or used provided) and you cannot be sure it will be always within your expected range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not only primitive types
&lt;/h2&gt;

&lt;p&gt;Union types are not limited to primitive types or type literals. They can as well be objects. I'm using the following pattern all the time as a TypeScript's equivalent of &lt;a href="https://en.wikipedia.org/wiki/Algebraic_data_type"&gt;algebraic data type (ADT)&lt;/a&gt;. It's a great pattern to express values which may contains different payload or same payload interpreted in different way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Credit&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Debit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Credit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Debit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleAccountEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;handleAccountEvent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// account == 10&lt;/span&gt;
&lt;span class="nx"&gt;handleAccountEvent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// account == 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope you understand union types better! With all that knowledge and all the TypeScript features now under your belt, you can take advantage of them when working on the next great feature!&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;List of resources I used when researching this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Union_(set_theory)"&gt;https://en.wikipedia.org/wiki/Union_(set_theory)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types"&gt;https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://basarat.gitbook.io/typescript/type-system/discriminated-unions"&gt;https://basarat.gitbook.io/typescript/type-system/discriminated-unions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://camchenry.com/blog/typescript-union-type"&gt;https://camchenry.com/blog/typescript-union-type&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Read more at &lt;a href="https://cichocinski.dev"&gt;cichocinski.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>5 reasons why destructuring and inline types hurt your TypeScript codebase</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Sun, 09 Oct 2022 19:42:34 +0000</pubDate>
      <link>https://dev.to/baransu/5-reasons-why-destructuring-and-inline-types-hurt-your-typescript-codebase-2a3k</link>
      <guid>https://dev.to/baransu/5-reasons-why-destructuring-and-inline-types-hurt-your-typescript-codebase-2a3k</guid>
      <description>&lt;p&gt;Recently I've seen a tweet by Jamie Kyle about using destructuring, default params, and inline types:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q5mUjlRl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FeK6_CyVsAACFdf.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xs_YP1Qz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1404512666253631488/8b5hCuyx_normal.jpg" alt="Jamie Kyle 🏳️‍🌈 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Jamie Kyle 🏳️‍🌈
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @buildsghost
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Maybe this is controversial, but this is why I don't use destructuring, default params, inline types, etc.&lt;br&gt;&lt;br&gt;All this or:&lt;br&gt;&lt;br&gt;enqueueMessageForSend(&lt;br&gt;  message: MessageDetails,&lt;br&gt;  options: MessageOptions,&lt;br&gt;): Promise&amp;lt;Message&amp;gt; {...} 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      20:18 PM - 03 Oct 2022
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1577030375158607872" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1577030375158607872" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1577030375158607872" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 

&lt;p&gt;That tweet and a few React components I have seen recently in my day job inspired me to write this blog post. I want to show you how using destructuring and inline types makes your TypeScript less readable!&lt;/p&gt;
&lt;h2&gt;
  
  
  How TypeScript function definition look like?
&lt;/h2&gt;

&lt;p&gt;In JavaScript and TypeScript, you can define a function either using &lt;code&gt;function&lt;/code&gt; keyword or lambda/arrow-function. Both ways are valid, but have their differences. Let's take a look at the simple &lt;code&gt;sendMessage&lt;/code&gt; function. Implementation logic is not relevant to us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// sendMessage function written using `function` keyword&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// function logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// same sendMessage written as arrow function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// function logic&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When function definition is quite simple, the function accepts a few params of a different type. If they are primitives like strings or numbers, everything is readable.&lt;/p&gt;

&lt;p&gt;Let's say you want to pass some additional information alongside your message content to the &lt;code&gt;sendMessage&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;senderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;replyTo&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// you can assess content using `message.content` here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, TypeScript allows you to write an inline type definition for the &lt;code&gt;message&lt;/code&gt; object you want to pass without specifying the type using &lt;code&gt;type&lt;/code&gt; or &lt;code&gt;interface&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Let's add destructuring. When you pass a large &lt;code&gt;message&lt;/code&gt; object to your function, TypeScript allows breaking apart passed arguments to reduce the code boilerplate of repeating &lt;code&gt;message&lt;/code&gt; variable many times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;senderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;replyTo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;senderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;replyTo&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// you have access to `content` directly&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why I think it's a bad idea and how you can make it better
&lt;/h2&gt;

&lt;p&gt;It may look like a nice idea, after all, you don't need to write &lt;code&gt;message&lt;/code&gt; that many times, right? It turns out it's not that great. Let's talk about 5 reasons why I think it's an antipattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. You're not sure where your data is coming from
&lt;/h3&gt;

&lt;p&gt;When you're reading the function body, and you see &lt;code&gt;senderId&lt;/code&gt; you have to double-check to be sure from where that function comes. Is it passed as an argument or calculated somewhere in the function?&lt;/p&gt;

&lt;h3&gt;
  
  
  2. It's hard to write documentation
&lt;/h3&gt;

&lt;p&gt;There is no natural place to write documentation comments when all the types are cramped with destructuring in the function definition. You could write comments between each type field, but that makes the whole function definition even longer. It's actively discouraging you from writing a quick summary of the data you're passing.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. It's hard to pass that data forward
&lt;/h3&gt;

&lt;p&gt;When your data is destructured you need to structure it again into a new object if you want to pass it forward. This discourages creating smaller helper functions and relying on composition to build up your main function logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. You cannot reuse argument types outside this function
&lt;/h3&gt;

&lt;p&gt;If you need to reuse your function arguments in helper functions when composing your main function logic, you must type the same set of types repeatedly. This makes it easier not to write types at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. It just takes a lot of space
&lt;/h3&gt;

&lt;p&gt;Let's face it. It's just a lot of lines of code that take up a lot of screen space. And in addition, it focuses on implementation detail – the inner type of the arguments you are passing to a function, which is most of the time not relevant when you're looking at that function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just create type for it
&lt;/h2&gt;

&lt;p&gt;Extracting the type and placing it right above the function makes it much more readable. There is a place for documentation comments, you can reuse that type in some other helper function and change the type definition in one place if needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Message to send using XYZ API
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MessageToSend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Markdown string of the user's message
   */&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Id of the sender user
   */&lt;/span&gt;
  &lt;span class="nl"&gt;senderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Other message ID if this is a reply
   */&lt;/span&gt;
  &lt;span class="nl"&gt;replyTo&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageToSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// function logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserIdsToNotify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessaageToSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// function logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;List of resources I used when researching this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/variable-declarations.html#object-destructuring"&gt;https://www.typescriptlang.org/docs/handbook/variable-declarations.html#object-destructuring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Read more at &lt;a href="https://cichocinski.dev"&gt;cichocinski.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>typescript</category>
      <category>antipattern</category>
    </item>
    <item>
      <title>Types of devs</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Mon, 25 Jan 2021 23:20:08 +0000</pubDate>
      <link>https://dev.to/baransu/types-of-devs-g0c</link>
      <guid>https://dev.to/baransu/types-of-devs-g0c</guid>
      <description>&lt;p&gt;There are few types of developers I've encountered throughout my programming career:&lt;/p&gt;

&lt;h3&gt;
  
  
  over-engineering devs
&lt;/h3&gt;

&lt;p&gt;They care only about engineering, system architecture but not really about the business of the created application. They like to talk about using advanced patterns like event sourcing, actor model, using message broker or message queue just to implement a simple to-do list.&lt;/p&gt;

&lt;h3&gt;
  
  
  happy path = done devs
&lt;/h3&gt;

&lt;p&gt;They care only about the happy path. Making PM/CEO/client happy, especially if the person they are reporting to has no idea about the technical side of building things. They copy-paste existing code, add new fields to data models, and don't bother thinking twice about the consequences of their changes. What matters is just covering one simple case they have in their task.&lt;/p&gt;

&lt;h3&gt;
  
  
  let's try that new shiny OSS library devs aka hype devs
&lt;/h3&gt;

&lt;p&gt;As soon as there is a possibility to add a new dependency or blame slow performance/bugs on not so trendy library the project currently uses you know they will be the first to jump to rewrite existing code and burn old to the ground. Especially if the new library is few days old and just blows up on Twitter gaining few hundred/thousands stars in the first few days.&lt;/p&gt;

&lt;h3&gt;
  
  
  so we're creating user-facing application devs
&lt;/h3&gt;

&lt;p&gt;This is a special breed of backend developers that only care about data, security, system architecture, system resilience, fault tolerance, containers, and Kubernetes. Super happy when writing new services to cover business logic (the more complex the better) but they are disgusted when asked to expose API for "frontend" or implementing something even remotely close to user-facing UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  let's write that ourselves devs
&lt;/h3&gt;

&lt;p&gt;Screw that OSS library everyone uses. Sure it has hundreds of contributors is used by a lot of companies in their core products but we should write that ourselves to have 100% control. Yeah, sure...&lt;/p&gt;

&lt;h3&gt;
  
  
  we should have eslint for that devs
&lt;/h3&gt;

&lt;p&gt;This special kind of developer creates the most impossible eslint rules to fix the JS. Ban half of the language, force conventions, have 10 times more eslint config than actual code.&lt;/p&gt;

&lt;h3&gt;
  
  
  endofunctor devs
&lt;/h3&gt;

&lt;p&gt;Freshly after reading about category theory just have to use that Kleisli composition in your codebase. And not forget about using all of the possible custom operators to express even the simplest business logic.&lt;/p&gt;




&lt;p&gt;We all probably know some of those developers and can recognize our colleagues among them. We can even make fun of them, but the truth is - we all should take the good parts from each one of the above and balance it. This is what makes us better developers.&lt;/p&gt;

</description>
      <category>humor</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>TIL: React Server Components</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Wed, 30 Dec 2020 02:04:07 +0000</pubDate>
      <link>https://dev.to/baransu/react-server-components-952</link>
      <guid>https://dev.to/baransu/react-server-components-952</guid>
      <description>&lt;p&gt;After being late to the party I've finally watched &lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html"&gt;the React Server Components introduction from the React team&lt;/a&gt;. Here are my thoughts.&lt;/p&gt;

&lt;p&gt;In recent months I felt a need to explore more "traditional" ways of doing web apps. More server rendering, less client-side logic. In my case mostly the Phoenix framework and Phoenix LiveView (it's great). It's really good to see more and more movement in that direction in the React community (with recent additions to Next.js) and from the React Core team itself.&lt;/p&gt;

&lt;p&gt;I think current React development is really complex and requires a lot of work with separate backend and frontend "services" and REST/GraphQL API to connect both. If you're using a framework like Next.js and/or your team is full-stack it's much easier because you probably share the same codebase and technology you work in. But that doesn't reflect your application. Still, only the first render of the page happens on the server. With React Server Components you'll get more tools at your disposal to create a better experience for your users.&lt;/p&gt;

&lt;p&gt;Knowing that I'm also kind of worried about the complexity of those things. "With great power comes great responsibility" right? For example, React Hooks were a great addition to React and made hard things easy, but also made easy things hard. With React Server Components we won't be talking only about React components and their state or effects but also about their runtime. If this is a shared/server/client component? Will there be a different behavior on server and client? And I'm 100% sure devs will do weird things with direct Node access inside server components. For sure TypeScript and the ungodly amount of Eslint config will make it work great but that's a good thing to keep in mind.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>react</category>
    </item>
    <item>
      <title>ReasonML – My Best Practices</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Sat, 25 Jan 2020 22:51:04 +0000</pubDate>
      <link>https://dev.to/baransu/reasonml-my-best-practices-2gla</link>
      <guid>https://dev.to/baransu/reasonml-my-best-practices-2gla</guid>
      <description>&lt;p&gt;Programming is constant learning. Improving your skills, learning new things, establishing best practices. I want to share a few best practices I developed based on my experience in various Reason projects. Some of those are BuckleScript specific and some of them apply to Native ReasonML development as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post contains only a list of few that I find important in my projects but Leandro Ostera collected a great set of design patterns and best practices: &lt;a href="https://github.com/ostera/reason-design-patterns"&gt;https://github.com/ostera/reason-design-patterns&lt;/a&gt; - definitely check them out!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article I want to focus on the following patterns and best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project structure&lt;/li&gt;
&lt;li&gt;Creating data modules to hide your implementation details and place your logic in one place&lt;/li&gt;
&lt;li&gt;Always defaulting to Belt&lt;/li&gt;
&lt;li&gt;Using Pipe first&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;It's an adoption of &lt;a href="https://dev.to/yawaramin/a-modular-ocaml-project-structure-1ikd"&gt;Yavar Amin's Project structure&lt;/a&gt; but adjusted to my needs and project size. I highly recommend reading the mentioned article.&lt;/p&gt;

&lt;p&gt;My setup is very similar. I try to divide my application into business entities and build folders structure around them. Let's take a basic blog application as an example. First thing every blog application needs are posts. Because of that &lt;code&gt;src/post&lt;/code&gt; would be my first folder with a single &lt;code&gt;Post.re&lt;/code&gt; in it. ReasonML module system is folder agnostic so I don't have to import it in any of my other modules - &lt;code&gt;Post&lt;/code&gt; is available globally. That module would have one main purpose - providing a clear list of all submodules that are available for use outside of &lt;code&gt;src/post&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Alongside &lt;code&gt;Post.re&lt;/code&gt; I would have &lt;code&gt;Post_Query.re&lt;/code&gt; reexporting all my GraphQL queries like &lt;code&gt;Post_Query_Single.re&lt;/code&gt; or &lt;code&gt;Post_Query_List.re&lt;/code&gt;. If you're using REST instead of GraphQL the same applies. My React component could be &lt;code&gt;Post_View_Single.re&lt;/code&gt; containing single post logic. It would be reexported in &lt;code&gt;Post_View.re&lt;/code&gt; and then in &lt;code&gt;Post.re&lt;/code&gt; for usage in other parts of the application. &lt;/p&gt;

&lt;p&gt;In the future, when the application would grow I could add comments functionality with &lt;code&gt;src/comment&lt;/code&gt; and &lt;code&gt;Comment.re&lt;/code&gt; reexporting all my other modules: &lt;code&gt;Comment_View.re&lt;/code&gt;, &lt;code&gt;Comment_View_List.re&lt;/code&gt; and &lt;code&gt;Comment_View_Single.re&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I found this structure work well in medium size with projects - between 200-300 files and 20-30k lines of code. None of my applications surpassed that numbers so far. If any of them will get bigger and this structure will become hard to maintain, I'll think about changing it. There is no need for prematurely optimizing it as ReasonML gives us strong guarantees when refactoring 😎. For me, it's also important to remember that this is only a framework. You don't have to follow this religiously. Try it and adjust to your needs and your application requirements. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create data modules to hide your implementation details and place your logic in one place
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I also wrote about creating modules hiding your implementation details in my previous post:  about lessons learned creating a first Reason production app: &lt;a href="https://dev.to/baransu/first-reasonml-production-app-lessons-learned-l3o#3-create-more-modules-hiding-your-implementation-details"&gt;First ReasonML production app - lessons learned&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As we covered folders and file structure it's important to think about what would be in them. When I started programming in JavaScript I had no idea how to structure my projects. I randomly created React components when they were required and objects in random places with random shapes. Over time I paid greater attention to my React code structure and this part improved. Later, when I learned about Flow I started caring more about types and where they are located in my project. But my logic tended to be scattered in random places. It was painful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I haven't always had type definition for data, a lot was relying on type inference&lt;/li&gt;
&lt;li&gt;When I moved my React components, a lot of functions defined in the same place changed place as well thus requiring import fixes&lt;/li&gt;
&lt;li&gt;I had random functions scattered across all my codebase doing random stuff with my data. Not everything was wrong (like mutating data or firing side effects) but it was a mess.&lt;/li&gt;
&lt;li&gt;Code discoverability was super hard - to find if the logic I need is already implemented or do I have to write everything from scratch, I had to browse through dozens of files and rely strongly on my memory. I don't recommend anyone joining a team working on such codebase 😅 &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;When we started using Reason, a lot of bad practices migrated with us from JavaScript into our new Reason code. More powerful language doesn't mean you automatically write better code. It takes time to learn how to use this power correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In functional programming languages, you usually have two most important constructs you can use to create bigger abstractions: functions and modules. Functions are the basic logic primitives you can combine into larger pieces of logic and modules which are a collection of your functions.&lt;/p&gt;

&lt;p&gt;Let's dive into a simple example. Imagine we have a refund policy in our application. Communication between our client and server is done via GraphQL thus our refund policy will be GraphQL Enum type - in Reason, it will be a polymorphic variant. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to better understand the difference between different types of variants in Reason I highly recommend &lt;a href="https://2ality.com/2018/01/polymorphic-variants-reasonml.html"&gt;this article by Dr. Axel Rauschmayer&lt;/a&gt; about polymorphic variants.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What we want is basicly &lt;a href="https://github.com/ostera/reason-design-patterns/blob/master/patterns/1-module-1-thing.md"&gt;1 Module 1 Thing&lt;/a&gt; pattern. Our basic module can look as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* RefundPolicy.re */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, we have our type defined now we can move to our functions. Because we're working on frontend application, sooner or later we will have to show refund policy to the user. Let's introduce the &lt;code&gt;toMessage&lt;/code&gt; function. It takes our &lt;code&gt;type t&lt;/code&gt; (following OCaml convention for definition leading type in the module) and outputs i18n message our UI can display:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* RefundPolicy.re */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="cm"&gt;/* Using bs-react-intl for i18n */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;intl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"fullReturn"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"refundPolicy.fullReturn"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"defaultMessage"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Full return"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"noReturn"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"refundPolicy.noReturn"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"defaultMessage"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"No return"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;toMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;##&lt;/span&gt;&lt;span class="n"&gt;fullRefund&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;##&lt;/span&gt;&lt;span class="n"&gt;noRefund&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, we have a way to display our refund policy to the user! But what if the user needs the ability to select the option? Well, we need more functions.&lt;/p&gt;

&lt;p&gt;Usually, React select components work on string values so it would be nice to convert our refund policy to string and from a string. This is where BuckleScript converters come handy, one in particular: &lt;code&gt;jsConverter&lt;/code&gt;. It gives us the ability to convert our polyvariant into a string and from a string. It's also a great option if only part of your system is written in Reason and other in Flow/TypeScript where enums are usually represented as strings. Let's use that!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* RefundPolicy.re */&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deriving&lt;/span&gt; &lt;span class="n"&gt;jsConverter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;toString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tToJs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fromString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tFromJs&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getWithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you can safely convert your polyvariant to and from a string. &lt;code&gt;tFromJs&lt;/code&gt; returns &lt;code&gt;option(t)&lt;/code&gt; so you can unwrap that early or return &lt;code&gt;option(t)&lt;/code&gt; and handle such case later. It all depends on your use-case. As many BuckleScript interoperability helpers &lt;code&gt;jsConverter&lt;/code&gt; have few handy features. One of them is &lt;code&gt;[@bs.as]&lt;/code&gt;. It allows you to customize how each case is converted to a string. By default they are all converted as-is: &lt;code&gt;FullRefund&lt;/code&gt; will become &lt;code&gt;"FullRefund"&lt;/code&gt; and &lt;code&gt;myOtherCase&lt;/code&gt; will become &lt;code&gt;"myOtherCase"&lt;/code&gt;. You can use &lt;code&gt;[@bs.as "full-refund"]&lt;/code&gt; if you need different output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* RefundPolicy.re */&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deriving&lt;/span&gt; &lt;span class="n"&gt;jsConverter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="cm"&gt;/* will output "full-refund" */&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;"full-refund"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we have a way to put it into select, it would be great to provide variable providing all available options. Of course, you can get this data from backend if it's not constant and rely on your business logic but let assume this list is constant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* RefundPolicy.re */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`FullRefund&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;`NoRefund&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;toMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now you have a pretty nice module containing all your logic. In the future, when your business logic changes and available refund policies change, you only have to change code in one place to match new requirements.&lt;/p&gt;

&lt;p&gt;Of course, the above functions are trivial but this example is to illustrate the concept. You can create as complex modules as your business requires and restrict access to internals using interface files exposing only public API. It all depends on the size of your team and your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Always default to Belt
&lt;/h2&gt;

&lt;p&gt;Belt is a BuckleScript standard library. It provided a set of data structures and modules to interact with them. Modules like &lt;code&gt;Belt.List&lt;/code&gt;, &lt;code&gt;Belt.Array&lt;/code&gt;,  &lt;code&gt;Belt.Option&lt;/code&gt; and &lt;code&gt;Belt.Result&lt;/code&gt; are compatible with built-in Reason types but provide functions that have consistent API and great performance in JavaScript runtime. When I started using Reason, I had few problems with Belt. Mainly because I loved pipe last operator &lt;code&gt;|&amp;gt;&lt;/code&gt; and all Belt functions have pipe first &lt;code&gt;-&amp;gt;&lt;/code&gt; API (I'll explain differences between &lt;code&gt;|&amp;gt;&lt;/code&gt; and &lt;code&gt;-&amp;gt;&lt;/code&gt; in-depth in next chapter) and good documentation was lacking (now &lt;a href="https://reasonml.org/"&gt;there is ongoing&lt;/a&gt; process of creating better documentation for ReasonML ecosystem). &lt;/p&gt;

&lt;p&gt;As of today, Belt comes with BuckleScript compiler and people starting with Reason are confused about what they should use: &lt;code&gt;Array&lt;/code&gt; or &lt;code&gt;Belt.Array&lt;/code&gt; module? It's probably ok to mix that up when you're working on a toy project but the problem starts when you have a team of few developers working on a bigger project.&lt;br&gt;
Some of them use &lt;code&gt;open Belt&lt;/code&gt; on top of a file, some don't. Some use &lt;code&gt;Belt.Array&lt;/code&gt; and some &lt;code&gt;Array&lt;/code&gt; module. In general, it gets quite messy fast. You can enforce code style in code reviews but it gets tedious. What I started doing is adding &lt;code&gt;-open Belt&lt;/code&gt; flag to &lt;code&gt;bsc-flags&lt;/code&gt; in &lt;code&gt;bsconfig.json&lt;/code&gt;. It implicitly opens Belt in all your modules. Some people may agree, some may not but I think it helps keep certain conventions in a project.&lt;/p&gt;

&lt;p&gt;If you don't like &lt;code&gt;Belt&lt;/code&gt; and want to use other libraries like &lt;a href="https://github.com/darklang/tablecloth"&gt;tablecloth&lt;/a&gt; or &lt;a href="https://github.com/reazen/relude"&gt;relude&lt;/a&gt; you can do the same. It works perfectly fine. Problem with Belt can be versioning reliable on &lt;code&gt;bs-platform&lt;/code&gt; release, the slow pace of adding functions and modules required by community. &lt;a href="https://github.com/BuckleScript/bucklescript/issues/3947#issuecomment-552847492"&gt;There are plans&lt;/a&gt; for extracting it from BuckleScript.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Use Pipe first
&lt;/h2&gt;

&lt;p&gt;Yeah, right. One of those great battles in functional programming and  BuckleScript took that to the extreme.&lt;/p&gt;

&lt;p&gt;Pipe operators, at this point, exist in quite a lot of languages: F#, Elm, Elixir, Reason. A lot of people debate about the "data" place. Some languages like Elm use data last approach, where data is the last argument of a function, and other languages like Elixir prefer the data-first approach - data is the first argument.&lt;/p&gt;

&lt;p&gt;Here comes Reason - exactly BuckleScript, distorting well-established practices used in OCaml. In OCaml, where pipe operator is not shipped in the standard library (&lt;em&gt;Yavar Amin corrected me that &lt;a href="https://caml.inria.fr/pub/docs/manual-ocaml/libref/Stdlib.html#VAL(%7C%3E)"&gt;OCaml std skips with a pipe last operator&lt;/a&gt; - thanks&lt;/em&gt; 😅) people are implementing it in userland as it's just a one-line infix function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Native Reason comes with &lt;code&gt;|&amp;gt;&lt;/code&gt; by default. It's data last because of currying and partial application. When you create a function, you sometimes want to omit data passed and create a partially applied function with a logic you created. Let's take &lt;code&gt;List.map&lt;/code&gt; as an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;doubleElements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It allows you to double every element in the list. With data last approach and partial application you can shorten it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;doubleElements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It means the same thing and is preferred by some people.&lt;/p&gt;

&lt;p&gt;Using the pipe last approach you can use it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/* or */&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubleElements&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's great because you have a nice flow of how your data is transformed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;mod&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string_of_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"You happy numer is: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem started when BuckleScript introduced &lt;code&gt;-&amp;gt;&lt;/code&gt; (pipe first) operator. It behaves similarly but inserts the left side of the operator as the first argument of a right side function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;mod&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string_of_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;happyNumber&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"You happy numer is: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;happyNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now all your existing libraries, including OCaml/Reason standard library which is data last, are not working with BuckleScript pipe first operator.&lt;/p&gt;

&lt;p&gt;Why is that you may ask? There are a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-&amp;gt;&lt;/code&gt; unlike &lt;code&gt;|&amp;gt;&lt;/code&gt; is just a syntax sugar - it's removed during compilation. Pipe last is just a function and it's not so easy to remove. So in the above example, you have more function calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pipe first has higher associativity than pipe last, thanks to that you can do things like this.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* without -&amp;gt; */&lt;/span&gt;
&lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;ReactEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;##&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="cm"&gt;/* with -&amp;gt; */&lt;/span&gt;
&lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;ReactEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;##&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's something JS API specifics and BuckleScript tries to optimize such cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipe first works better with BuckleScript bindings: &lt;code&gt;[@bs.send]&lt;/code&gt;, &lt;code&gt;[@bs.set]&lt;/code&gt;, etc where data is required to be first
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;myComplexClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;makeComplexClassInstance&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;myComplexClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ComplexClass"&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;callMeMaybe&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myComplexClass&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"callMeMaybe"&lt;/span&gt;

&lt;span class="n"&gt;myComplexClassInstance&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;callMeMaybe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;myComplexClassInstance&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;callMeMaybe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"911"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Few more things, all mentioned in the issue in BuckleScript repo: &lt;a href="https://github.com/BuckleScript/bucklescript/issues/2463#issuecomment-361863485"&gt;https://github.com/BuckleScript/bucklescript/issues/2463#issuecomment-361863485&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My rule of thumb is using pipe first. When it's not possible BuckleScript supports pipe placeholder which makes it compatible with data last collections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reason community seems divided because the pipe first doesn't work on Native. But I think people working with JavaScript as Reason target are embracing pipe first approach. Some libraries like &lt;a href="https://github.com/darklang/tablecloth"&gt;darklang/tablecloth&lt;/a&gt; are using labeled arguments to support both pipe first and pipe last approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to read more about the differences between those two approaches, there is &lt;a href="https://www.javierchavarri.com/data-first-and-data-last-a-comparison/"&gt;a great article by Javier Chávarri&lt;/a&gt; which goes into details about differences between pipe first and pipe last in BuckleScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope those few things will help you in the current and future projects and allow you to ship great features! If you have some other practices you follow - share and discuss them with the community!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Many thanks to &lt;a href="https://twitter.com/___zth___"&gt;@zth&lt;/a&gt;, &lt;a href="https://twitter.com/JaapFrolich"&gt;@jfrolich&lt;/a&gt; and &lt;a href="https://twitter.com/fp_pawel"&gt;@Faliszek&lt;/a&gt; for proofreading!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>reason</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>First ReasonML production app - lessons learned</title>
      <dc:creator>Tomasz Cichocinski</dc:creator>
      <pubDate>Wed, 06 Mar 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/baransu/first-reasonml-production-app-lessons-learned-l3o</link>
      <guid>https://dev.to/baransu/first-reasonml-production-app-lessons-learned-l3o</guid>
      <description>&lt;p&gt;Over the last 5 months, we at &lt;a href="https://codeheroes.io/"&gt;Codeheroes&lt;/a&gt; had a chance to work on a mobile application for both iOS and Android as well as web-based panel providing "admin" functionality for a mobile app. We always want to push our skills further and create better and more reliable software with every next project so we went with ReasonML for both applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to learn more about Reason I highly recommend official documentation and a great book by Dr. Axel Rauschmayer - &lt;a href="http://reasonmlhub.com/exploring-reasonml/"&gt;Exploring ReasonML and functional programming&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had prior experience with Reason but the rest of the team (one junior and two developers with about two years experience each) had only worked with typed JavaScript using Flow, React and React Native. This project was not only our first Reason project as a team (previously I was writing parts of another app in Reason to test if it suits our needs) but also I had to learn and support other developers on their Reason path.&lt;/p&gt;

&lt;p&gt;I want to share our experience and lessons learned from creating mobile and web apps in ReasonML!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Reason?
&lt;/h2&gt;

&lt;p&gt;We believe in a statically typed and functional approach as we worked with Flow previously. We also try to write software in an as much functional way as it makes sense in JavaScript. Additionally, our backend is written in Scala so our Backend Developers influence our way of thinking a lot.&lt;/p&gt;

&lt;p&gt;I was thinking a lot about introducing Elm to our projects. The language is very hermetic and in my opinion, it would be impossible to create a project using all our previous React experience and technology we developed over the years.&lt;/p&gt;

&lt;p&gt;When I learned about Reason somewhere in 2017 it was not mature enough to use it in production then. But in 2018 a lot of Reason community effort with tooling, bindings, talks, blog posts made the language mature enough to test it as a part of our existing JavaScript application. After that, as it went well it convinced us it's reasonable to go with Reason for the whole project.&lt;/p&gt;

&lt;p&gt;In case of some real problems, we knew we can go back to JavaScript to finish the project on time. Fortunately, we hadn't had to do so. The last 5 months only convinced us it was a really good decision.&lt;/p&gt;

&lt;p&gt;One of the things we were afraid of was interoperability with JavaScript...&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Don't be afraid of bindings
&lt;/h2&gt;

&lt;p&gt;The core functionality of the application is a medical Bluetooth device for women. They can connect the device to application and "play" simple games using their pelvic muscles.&lt;/p&gt;

&lt;p&gt;We knew we had to use a few libraries that don't have existing bindings. The two most significant were: &lt;a href="https://github.com/Polidea/react-native-ble-plx"&gt;react-native-ble-plx&lt;/a&gt; which we used for Bluetooth connection and &lt;a href="https://github.com/bberak/react-native-game-engine"&gt;react-native-game-engine&lt;/a&gt; which provides nice API we used for creating games controlled by Bluetooth device.&lt;/p&gt;

&lt;p&gt;Bindings forced us to define types for every function we used. It's the same story as Flow or Typescript type definitions but it gives us much more!&lt;/p&gt;

&lt;p&gt;In Flow you can omit types, you can do whatever you want and if you decide to write types (or use already existing types from &lt;a href="https://github.com/flow-typed/flow-typed"&gt;flow-typed&lt;/a&gt;) they can lie to you not reflecting the real API. They are not implementation they just type annotations. In Reason, you have to create bindings which are both type annotations and actual implementation of how we want to connect to existing JavaScript code. Of course, you can create bindings that lie about the API but it comes a lot quicker during development in Reason than in Flow.&lt;/p&gt;

&lt;p&gt;You can disagree with me 😉.&lt;/p&gt;

&lt;p&gt;Another cool Reason feature are abstract types. Those are types that don't have an internal structure. You define them as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* abstract type */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;someComplexJavaScriptType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* normal record type */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create a type that is only passed from function to function. You don't have to care if it's a string, int or some complex object, and what field it has. It exists only in bindings. Here is an example of &lt;a href="https://github.com/Polidea/react-native-ble-plx"&gt;react-native-ble-plx&lt;/a&gt; bindings using abstract types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;bleManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"react-native-ble-plx"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;createBleManager&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bleManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"BleManager"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;removeSubscription&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"remove"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;onStateChange&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bleManager&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"onStateChange"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we define &lt;code&gt;bleManager&lt;/code&gt; type and don't care about its internals. Then we have a function to create it from thin air. Great. The same goes with &lt;code&gt;subscription&lt;/code&gt; type. We know &lt;code&gt;onStateChange&lt;/code&gt; function returns subscription but we don't have to care what it is. We need only to know there is &lt;code&gt;removeSubscription&lt;/code&gt; function to remove a subscription.&lt;/p&gt;

&lt;p&gt;Once we're forced to create those bindings (and the process of writing them is not hard nor time-consuming) we have a nice place to slightly adjust the library to our needs. We can create an intermediate layer in which we can, for example, rearrange function arguments order for fast-piping or make them labeled, we can compose one or more functions together, we can model the API for our application use case. Without bindings, API we created around those libraries would be much worse.&lt;/p&gt;

&lt;p&gt;Of course, this makes it harder to share bindings as an open-source project but I think it should never be the primary goal if you're forced to create bindings in your application code.&lt;br&gt;
It's great to do that so others can benefit but I believe it's the second step. First, create bindings for any functionality you need, then write your application using them so you can validate if they are any good, then publish it as open-source and share with the community to gather feedback from other developers.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Render props, using let-anything and bs-epitath, are awesome
&lt;/h2&gt;

&lt;p&gt;Render props is popular &lt;a href="https://reactjs.org/docs/render-props.html"&gt;React pattern&lt;/a&gt;. It allows you to reuse component logic in multiple places. A popular use case is &lt;code&gt;react-apollo&lt;/code&gt; query component allowing you to create GraphQL queries. The problem is it makes your component bigger and harder to read. If you have one such component it's ok but if you have two or more you are creating that nested callback monster.&lt;/p&gt;

&lt;p&gt;PPX to the rescue! PPX is something called a syntax rewriter. It's OCaml/ReasonML compiler extension which allows you to create compile-time macros.&lt;br&gt;
One of such is &lt;a href="https://github.com/jaredly/let-anything"&gt;let-anything&lt;/a&gt; - created by Jared Forsyth. Together with &lt;a href="https://github.com/Astrocoders/bs-epitath/"&gt;bs-epitath&lt;/a&gt; from Astrocoders, it gives us real superpower. Let's look at React Context render props example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* without let-anything and bs-epitath */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statelessComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Logged as: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;Contect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* with let-anything and bs-epitath */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statelessComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nc"&gt;Epitath&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;Contect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;

    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Logged as: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sweet, right?&lt;/p&gt;

&lt;p&gt;But be aware! We fall in the trap of overusing it in large components with not only data render props components but combined with view components.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/Astrocoders/bs-epitath/pull/2"&gt;Latest changes&lt;/a&gt; to bs-epitath will make it almost impossible to write such code as presented below. But since they want to support old and new syntax please be cautious!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* don't do this, please */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statelessComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nc"&gt;Epitath&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Section&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;Contect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Section&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* real part of the component */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While it's valid to do so, I think it introduces a lot of indirection and makes things harder to read. If you want to learn more, Gabriel Rubens Abreu wrote a great post - &lt;a href="https://medium.com/astrocoders/render-props-composition-for-reasonml-is-here-b9c004ca9fcb"&gt;Render Props composition for ReasonML is here&lt;/a&gt; that describes the concept in details.&lt;/p&gt;

&lt;p&gt;When starting with a new language, it's often difficult to learn best practices and deeply understand how to model your application. It was true for us, and we learned about it when working on the core functionality of the app...&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Create more modules hiding your implementation details.
&lt;/h2&gt;

&lt;p&gt;When we created functionality around Bluetooth connection we had to gather samples send by the device. We used them for controlling games and for sending them to our backend for further analysis. While sending samples to the backend is rather easy and requires little or no interaction with samples, the game part is rather complex as we want to process samples in various ways.&lt;br&gt;
Iterate over samples applying some transformation to part of the samples, get samples in some timeframe, find spikes in a list of samples and much, much more.&lt;/p&gt;

&lt;p&gt;We failed but not creating a dedicated &lt;code&gt;Sample&lt;/code&gt; module. It should have &lt;code&gt;sample&lt;/code&gt; type and all functions we would like to use across the whole application. It was a really bad decision that impacted the development of every part relying on that data. We had functions in many modules, many implementations of the same or similar function made by different developers. In general, it was a mess.&lt;/p&gt;

&lt;p&gt;Lesson learned here - create modules for your data types to hide the implementation. Let's assume you have a simplified sample that consists of a timestamp and some value gathered in that time. Example module would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Sample.re */&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;samples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fst&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;snd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* more complex functions... */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, you decide that tuple is not a suitable data structure for your use case and you want to change it. Let's assume record because you have more than two elements tuple. You change only lower-level functions interacting with the &lt;code&gt;type t&lt;/code&gt; and everything works as expected. No need for going through every module using &lt;code&gt;Sample&lt;/code&gt;. One file, one commit. Done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Sample.re */&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;samples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* other functions... */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple example that was most significant to us and was probably the worst decision in the whole development but we learned a lot from that and wouldn't make the same mistake twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. react-navigation is hard, but with Reason, it's not that hard
&lt;/h2&gt;

&lt;p&gt;In our previous React Native application, we had a hard time around &lt;a href="https://reactnavigation.org/"&gt;react-navigation&lt;/a&gt;. It's really hard to make it statically typed and sound in Flow. Making refactor to screen names and props passed between screens caused us a lot of headaches during the development of a previous application.&lt;/p&gt;

&lt;p&gt;When we started work on this application I was a little worried about how it would go. There were no good bindings to react-navigation at a time. But thanks to initial work on &lt;a href="https://github.com/callstackincubator/bs-react-navigation"&gt;bs-react-navigation&lt;/a&gt; by guys at Callstack we had something we could work on.&lt;/p&gt;

&lt;p&gt;Here are three parts making whole navigation a lot easier.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Explicitly passed navigation to every screen which wants to change currently active screen&lt;/li&gt;
&lt;li&gt;Variant describing all available screens and their params&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getScreen&lt;/code&gt; function rendering currently active screen based on screen variant&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;A simplified version looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* our screen type */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Products&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* get screen function rendering currently active screen */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getScreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Products&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductsScreen&lt;/span&gt; &lt;span class="n"&gt;navigation&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;,&lt;/span&gt;
        &lt;span class="n"&gt;screenOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Products"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductScreen&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;navigation&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;,&lt;/span&gt;
        &lt;span class="n"&gt;screenOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* example screens creating our application */&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;ProductsScreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statelessComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="cm"&gt;/* other products... */&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;ProductScreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ReasonReact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statelessComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="cm"&gt;/* product query */&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="cm"&gt;/* product details... */&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nn"&gt;BsReactNative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It makes it almost impossible to pass wrong params, forgot about something and in the process of adding more params or changing existing routes&lt;br&gt;
you know every place you have to adjust. And if you make them, the compiler tells you what's wrong and as soon as it compiles - in 99% of cases it works as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Don't be afraid of polymorphic variants.
&lt;/h2&gt;

&lt;p&gt;We used &lt;a href="https://github.com/mhallin/graphql_ppx"&gt;graphql_ppx&lt;/a&gt; and &lt;a href="https://github.com/apollographql/reason-apollo"&gt;reason-apollo&lt;/a&gt; for GraphQL client-server communication. In our schema, we have a lot of GraphQL Enum types. From things like application locale to things like available games and their configurations. In graphql_ppx generated code enums are polymorphic variants.&lt;/p&gt;

&lt;p&gt;When we started writing application we were "scared" of polymorphic variants and decides to create normal variant types for each enum we use in our GraphQL schema. We created a module for each one with a bunch of functionality for converting them back and forth. We had to convert them to every place of the application. From polymorphic variant to variant, from variant to string, from variant to i18n message. It was a lot of duplicated logic only because we were afraid to use polymorphic variants. And what about adding or removing something in API? We had to change our types twice, both polymorphic variants and normal variants.&lt;/p&gt;

&lt;p&gt;We learned polymorphic variants are just as fine as normal variants. They give you fewer guarantees and code is harder to debug since compilation errors can pop up in strange places not directly related to please when you use them. Despite all that you shouldn't be afraid. But remember, they are more expensive than normal variants, so use them with caution after all 😉.&lt;/p&gt;

&lt;p&gt;My rule of thumb is - if you only pass some variant from the API to the view, it's totally fine to use a polymorphic variant. If they live only in your application (like in navigation) it's better to use normal variants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community is great, open-source is great!
&lt;/h2&gt;

&lt;p&gt;Without great projects like &lt;a href="https://github.com/reasonml-community/bs-react-native"&gt;bs-react-native&lt;/a&gt;, &lt;a href="https://github.com/alexfedoseev/re-formality"&gt;re-formality&lt;/a&gt;, &lt;a href="https://github.com/mhallin/graphql_ppx"&gt;graphql_ppx&lt;/a&gt; and &lt;a href="https://github.com/apollographql/reason-apollo"&gt;reason-apollo&lt;/a&gt;, &lt;a href="https://github.com/apollographql/reason-apollo"&gt;reason-apollo&lt;/a&gt;, &lt;a href="https://github.com/callstackincubator/bs-react-navigation"&gt;bs-react-navigation&lt;/a&gt; and &lt;a href="https://github.com/alexfedoseev/bs-react-intl"&gt;bs-react-intl&lt;/a&gt; our work would be much harder or maybe even not possible. We wouldn't choose to go with Reason without those libraries. I want to thank everyone involved in making those libraries and other open-source libraries we used.&lt;/p&gt;

&lt;p&gt;If you want to talk more about our work or Reason, DM me on &lt;a href="https://twitter.com/_cichocinski"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>reason</category>
      <category>reactnative</category>
      <category>react</category>
    </item>
  </channel>
</rss>
