<?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: Florian Hammerschmidt</title>
    <description>The latest articles on DEV Community by Florian Hammerschmidt (@fhammerschmidt).</description>
    <link>https://dev.to/fhammerschmidt</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%2F83682%2F97a62cc1-c5d6-4c1d-bc7e-e1f303db36b2.jpg</url>
      <title>DEV Community: Florian Hammerschmidt</title>
      <link>https://dev.to/fhammerschmidt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fhammerschmidt"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Fri, 21 Feb 2025 23:20:23 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/-4e2b</link>
      <guid>https://dev.to/fhammerschmidt/-4e2b</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/dzakh" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F988236%2Fbe515a70-aadf-48ea-ba1f-e92410a78528.jpeg" alt="dzakh"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/dzakh/javascript-schema-library-from-the-future-5420" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;JavaScript schema library from the Future 🧬&lt;/h2&gt;
      &lt;h3&gt;Dmitry Zakharov ・ Feb 21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#schema&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#typescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>schema</category>
      <category>typescript</category>
      <category>rescript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>My programming language history</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Fri, 26 Aug 2022 21:39:14 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/my-programming-language-history-3eae</link>
      <guid>https://dev.to/fhammerschmidt/my-programming-language-history-3eae</guid>
      <description>&lt;p&gt;Nowadays, it is certainly more the norm to be a polyglot programmer than to be lucky enough to only need one main programming language. I am no different. I stumbled over a lot of both popular and unpopular programming languages over the course of my life. &lt;/p&gt;

&lt;p&gt;My first one was something with moving turtles. Probably &lt;strong&gt;Logo&lt;/strong&gt; or some more modern take on turtle graphics, I don't know. However I was too young at that time to even understand what I am doing, but I liked to make the turtle move. Not sure if that experiences formed my brain to dive deeper into all things computers later on.&lt;/p&gt;

&lt;p&gt;My second one was &lt;strong&gt;HTML&lt;/strong&gt;. Yes, it's just a markup language, but I still created &lt;em&gt;something&lt;/em&gt; just by writing text into an editor. Also it felt more useful to me than the Logo turtles which felt more like a game to me.&lt;/p&gt;

&lt;p&gt;As a teenager, I stumbled over Ubuntu and started a bit of &lt;strong&gt;Bash&lt;/strong&gt; scripting. This was when I really got to know the power of programming, because I could just pipe the output of one program to the next one and would only need to combine them to create something I was not even aware I could do. I mainly used it to organize my music collection - streaming services were not a thing back then.&lt;/p&gt;

&lt;p&gt;Later I started a job in a huge company where I mostly formatted Word documents or extended huge Excel sheets. Of course I got into &lt;strong&gt;VBA&lt;/strong&gt; at that time, which I learned quickly, is both boon and bane. Some excel sheets really evolved into unmaintainable behemoths, unfortunately.&lt;/p&gt;

&lt;p&gt;But it started to really diversify when I went to university. I started studying electrical engineering, where programming is an important part. Naturally, you learn &lt;strong&gt;C&lt;/strong&gt; there, which I both liked and hated. I eventually switched to information systems, not because programming in C was too hard, but the physics and electrical engineering classes were just a chore for me I could not really stand.&lt;/p&gt;

&lt;p&gt;In information systems, &lt;strong&gt;Java&lt;/strong&gt; was the bees knees. I learned it, did the necessary exams and classes but still hated it, because I found it too verbose. OOP was no problem for me, though. But using a full-fledged IDE for a project was very overwhelming at first.&lt;/p&gt;

&lt;p&gt;Another class was based around "semistructured data", which was where I learned not only how to write well-formed &lt;strong&gt;XML&lt;/strong&gt; but also &lt;strong&gt;XSLT&lt;/strong&gt;. It's really powerful but also yet another markup language so of course it does not count (or does it?).&lt;/p&gt;

&lt;p&gt;Next up I had a relational databases class FROM WHERE I found the theory pretty useful, but I would SELECT &lt;strong&gt;SQL&lt;/strong&gt; as the most useful skill I took out of this class. Also one of the professors contributed to the SQL-99 standard back then, which made me automatically pay attention a bit more. &lt;/p&gt;

&lt;p&gt;There is always the class where you get to decide what language you use for a project, so naturally our team decided to go with &lt;strong&gt;Python&lt;/strong&gt;. Django was still a young technology, but the project incorporated HTML, CSS and SQL as well, so it fostered my knowledge.&lt;/p&gt;

&lt;p&gt;Of course, some professors prefer pretty weird languages, and in another class I got to know &lt;strong&gt;ooRexx&lt;/strong&gt;, which is an object-oriented extension to IBMs Rexx language which itself is said to be a programming language for humans rather than computers. And it is really true in some ways. Everything is a string, and hello world is just "SAY Hello World" (without the quotes). We scripted office applications with it which felt much nicer than VBA. Later, we also scripted Java apps with it, which felt somewhat weird, since for most things it was easier to write things in Java, which is a much more googleable language than ooRexx.&lt;/p&gt;

&lt;p&gt;Fast-forward to my masters degree, which was when the machine learning hype started to gain traction. So I had a class where we used &lt;strong&gt;R&lt;/strong&gt;. It's a language that specializes in statistical computing. I found it really nice, especially that it was so easy to create nice plots without using MS Excel.&lt;/p&gt;

&lt;p&gt;The masters was also the time when I created my first web app with &lt;strong&gt;PHP&lt;/strong&gt;, &lt;strong&gt;JavaScript&lt;/strong&gt; and GeoServer. I had not really a clue what I was doing, but it worked pretty well regardless.&lt;/p&gt;

&lt;p&gt;Then I took the most technical specialization the degree offered. The first class of it already made us compare the OOP capabilities of JavaScript, &lt;strong&gt;Ruby&lt;/strong&gt;, and &lt;strong&gt;XOTcl&lt;/strong&gt;. Yes the last one is an object-oriented extension to &lt;a href="https://www.tcl.tk/" rel="noopener noreferrer"&gt;Tcl&lt;/a&gt; (the tool command language) which is a pretty esoteric language in itself. Eventually, we got to know this language a bit more in a later class where I made a little forum app with an upvote/downvote system.&lt;/p&gt;

&lt;p&gt;We also had an IOT class where I was introduced to Arduino which you basically write in &lt;strong&gt;C++&lt;/strong&gt;. Still, I resorted to doing the final project with a Raspberry Pi, a Bluetooth low energy module and a bunch of bash scripts. It was good enough for a working prototype (and it got me an A).&lt;/p&gt;

&lt;p&gt;Meanwhile, before the end of my studies, I got a freelancer job as a real software developer. I needed to write a complex signup form with Ruby on Rails. That job was a great reference to land a real job which I did. &lt;/p&gt;

&lt;p&gt;There, I was not only introduced to React, I also learned to write modern JavaScript (with flowtype at that time). Because of React-Native, I also needed to write the occasional Java or &lt;strong&gt;Objective-C&lt;/strong&gt;. Or now &lt;strong&gt;Kotlin&lt;/strong&gt; and &lt;strong&gt;Swift&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We saw that &lt;strong&gt;TypeScript&lt;/strong&gt; is probably the better horse to bet on, so we ditched flow for most existing projects in favor of TS. However, also ReasonML/BuckleScript emerged at that time, which was really a good fit for the mission-critical apps we were building. And now I am involved in developing tools for it, or rather its successor, &lt;strong&gt;ReScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But wait, it does not stop there. Having learned a Meta-Language-like language like ReScript makes it really easy to get into &lt;strong&gt;OCaml&lt;/strong&gt; which behaves similarly. Just for fun I also read two &lt;strong&gt;Rust&lt;/strong&gt; books and tinkered with that language as well. The jump to Rust is not that far-fetched from an ML-descendant.&lt;/p&gt;

&lt;p&gt;In the end I count 22 languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gnu.org/software/bash/" rel="noopener noreferrer"&gt;Bash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/" rel="noopener noreferrer"&gt;C&lt;/a&gt;/&lt;a href="https://www.open-std.org/jtc1/sc22/wg21/" rel="noopener noreferrer"&gt;C++&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://html.spec.whatwg.org/" rel="noopener noreferrer"&gt;HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.java.com/en/" rel="noopener noreferrer"&gt;Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tc39.es/ecma262/" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Logo (again, not sure about that)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html" rel="noopener noreferrer"&gt;Objective-C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ocaml.org/" rel="noopener noreferrer"&gt;OCaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oorexx.org/about.html" rel="noopener noreferrer"&gt;ooRexx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.php.net/" rel="noopener noreferrer"&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.r-project.org/" rel="noopener noreferrer"&gt;R&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rescript-lang.org/" rel="noopener noreferrer"&gt;ReScript&lt;/a&gt; (previously BuckleScript + ReasonML)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ruby-lang.org/en/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;SQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swift.org/" rel="noopener noreferrer"&gt;Swift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;VBA&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/XML/" rel="noopener noreferrer"&gt;XML&lt;/a&gt;/&lt;a href="https://www.w3.org/TR/xslt-30/" rel="noopener noreferrer"&gt;XSLT&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://media.wu.ac.at/" rel="noopener noreferrer"&gt;XOTcl&lt;/a&gt; and its successor, the &lt;a href="https://next-scripting.org/xowiki/about" rel="noopener noreferrer"&gt;next scripting framework&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and that does not even include the languages I did not even learn properly, but just by using it, for instance because they come with the tooling environment, like Groovy, YAML, and so on. Also not the languages I just tinkered with a bit, like Go or Elm.&lt;/p&gt;

&lt;p&gt;How many languages did you already use for more than just writing "Hello, world"? Did you get to know some really weird ones? Tell me about it in the comments!&lt;/p&gt;

&lt;p&gt;Thank you for reading, hope you enjoy this slightly different blog post from me. The next one will be focused at ReScript again, I promise.&lt;/p&gt;

&lt;p&gt;(cover image generated with &lt;a href="https://www.craiyon.com/" rel="noopener noreferrer"&gt;craiyon.com&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>programming</category>
    </item>
    <item>
      <title>Nicer APIs with ReScript</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Wed, 14 Oct 2020 21:27:30 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/nicer-apis-with-rescript-361</link>
      <guid>https://dev.to/fhammerschmidt/nicer-apis-with-rescript-361</guid>
      <description>&lt;p&gt;In the world of JavaScript, many APIs are not designed in a way a functional developer might design them. Although it got a lot better over the last couple of years thanks to technologies like React, most browser APIs are still rather object-oriented or lower-level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rescript-lang.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;ReScript&lt;/strong&gt;&lt;/a&gt; (previously BuckleScript) is a statically typed and sound language, compiler and build system, which generates very readable JavaScript. Thus, it is a great alternative to TypeScript for people who can't stand type holes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReScript&lt;/strong&gt; offers a wide variety of decorators to make binding to JavaScript APIs easier.&lt;/p&gt;

&lt;p&gt;Recently, I was required to use the browser's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices" rel="noopener noreferrer"&gt;&lt;code&gt;mediaDevices&lt;/code&gt; API&lt;/a&gt;. One of the most important methods is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia" rel="noopener noreferrer"&gt;&lt;code&gt;getUserMedia&lt;/code&gt;&lt;/a&gt; method which yields a Promise containing a &lt;code&gt;MediaStream&lt;/code&gt; object. It also has one required parameter, the &lt;code&gt;constraints&lt;/code&gt;  object, to determine if the API user requests audio, video or both. For example, to only request an audio stream one would use the following JS code:&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;video&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For video only you would set &lt;code&gt;audio: false, video: true&lt;/code&gt; and only if you require both, &lt;code&gt;audio: true, video: true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In idiomatic &lt;strong&gt;ReScript&lt;/strong&gt;, such an API would probably be designed in one of the following ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Either via a &lt;code&gt;constraints&lt;/code&gt; variant:
&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;constraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Audio&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Video&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Both&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constraints&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="cm"&gt;/* Calling the function */&lt;/span&gt;
&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Video&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Both&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;Or three separate functions
&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;let&lt;/span&gt; &lt;span class="n"&gt;getUserAudio&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="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getUserVideo&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="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getUserMedia&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="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="cm"&gt;/* Calling the function */&lt;/span&gt;
&lt;span class="n"&gt;getUserAudio&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;getUserVideo&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, I prefer the latter one. Soon you will see, why.&lt;/p&gt;

&lt;h1&gt;
  
  
  Embracing externals
&lt;/h1&gt;

&lt;p&gt;The default way to bind to existing JS functions is the external keyword accompanied by a bunch of different decorators/annotations, which always start with &lt;code&gt;@&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: With the most current bundle of the ReScript platform (bs-platform 8.3), it will be possible to &lt;a href="(https://rescript-lang.org/blog/release-8-3-pt1#lightweight-ffi-attributes-without-bs-prefix)"&gt;omit the &lt;code&gt;bs&lt;/code&gt; part&lt;/a&gt; in the annotations. So &lt;code&gt;@bs.as&lt;/code&gt; will turn to just &lt;code&gt;@as&lt;/code&gt;, etc. Check if your version is new enough for even cleaner code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Binding attempt 1
&lt;/h2&gt;

&lt;p&gt;To bind to global values such as &lt;code&gt;navigator.mediaDevices.getUserMedia&lt;/code&gt;, two annotations are necessary. Let's have a look at how one can write the binding and dissect it into parts later on.&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;/* Navigator.MediaDevices module */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;constraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;bool&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;val&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;scope&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"navigator"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"mediaDevices"&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;_getUserMedia&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constraints&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s2"&gt;"getUserMedia"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;type constraints = ...&lt;/code&gt;: &lt;br&gt;
The first part is a type definition for the constraints parameter we need to give to the &lt;code&gt;getUserMedia&lt;/code&gt; function. It  is a so-called record which looks like an object and also compiles to a JS object of the same shape, but is actually &lt;a href="https://rescript-lang.org/docs/manual/latest/record" rel="noopener noreferrer"&gt;something different&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@bs.val&lt;/code&gt; is to bind to global values. Global values are values which you always have in scope, like &lt;code&gt;navigator&lt;/code&gt;  or &lt;code&gt;window&lt;/code&gt;. Well, depending on the target platform (browser, node, etc.) of course.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@bs.scope(("navigator", "mediaDevices"))&lt;/code&gt;: When those values are nested, you need to define its scope too with &lt;code&gt;@bs.scope&lt;/code&gt;. Here, we use a tuple of strings to tell the compiler that the scope is multiple levels deep. You can tell that it's a tuple because of the double &lt;code&gt;((&lt;/code&gt; and &lt;code&gt;))&lt;/code&gt;. The outer parentheses are from the scope function, and the inner ones are from the tuple. Alternatively, you can also just use a string for the whole thing like this: &lt;code&gt;@bs.scope("navigator.mediaDevices")&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;external _getUserMedia&lt;/code&gt;: The aforementioned annotations only work together with the &lt;code&gt;external&lt;/code&gt; keyword. With it you define the name of the binding, which does not necessarily need to be the same as the JavaScript method you want to bind to. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;: constraints =&amp;gt; Js.Promise.t&amp;lt;stream&amp;gt;&lt;/code&gt;: Then comes the type annotation. According to MDN, this takes the constraints object mentioned earlier and returns a Promise of MediaStream, which translates to the built-in &lt;strong&gt;ReScript&lt;/strong&gt; type &lt;code&gt;Js.Promise.t&lt;/code&gt;. The &lt;code&gt;&amp;lt;stream&amp;gt;&lt;/code&gt; type which is wrapped by the promise is unfortunately not built-in, but can be typed accordingly (left as an exercise to the reader 😉). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;= "getUserMedia"&lt;/code&gt;: At last, a string with the actual name of the function. Watch out for typos!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We also define a helper record here. It looks like an object and compiles to a JS object, but is actually something different. &lt;/p&gt;

&lt;p&gt;Now we have a binding to &lt;code&gt;getUserMedia&lt;/code&gt;, but do we really want to call that ugly &lt;code&gt;Navigator.MediaDevices._getUserMedia({audio: true, video: true}&lt;/code&gt; everywhere in the codebase, or can we achieve a nicer API?&lt;/p&gt;

&lt;p&gt;Let's write some helper functions:&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;/* Navigator.MediaDevices module continued */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;getUserAudio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;false&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;getUserVideo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&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;getUserMedia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The functions can then be called from anywhere in the codebase via:&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="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserAudio&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserVideo&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Simplified example, in practice you would use &lt;code&gt;Js.Promise.then_&lt;/code&gt; or the like, to retrieve the stream itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yay, that looks better. But now we generate some extra code&lt;br&gt;
like this function:&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="nf"&gt;getUserAudio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;param&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUserMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
              &lt;span class="na"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;video&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;h2&gt;
  
  
  Binding attempt 2
&lt;/h2&gt;

&lt;p&gt;Can we do better and still populate the functions with default parameters? I'd say yes, with this nifty trick.&lt;/p&gt;

&lt;p&gt;There is also the very helpful &lt;code&gt;@bs.as&lt;/code&gt; annotation for when you need to give an entity a complex name which you could otherwise not create. For instance, in record fields, there is no &lt;code&gt;-&lt;/code&gt; allowed which can be mitigated by this annotation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@bs.as&lt;/code&gt; takes a single string as an argument. Coincidentally, JSON is basically just a complex string and thus we can inject some complex objects into the default configuration, too.&lt;/p&gt;

&lt;p&gt;Just write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@bs.as(json`{your-config-object}`)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a &lt;code&gt;_&lt;/code&gt; afterwards to omit the value when calling the function.&lt;br&gt;
Also we add a final &lt;code&gt;unit&lt;/code&gt; (the only "parameter" of the 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="cm"&gt;/* Navigator.MediaDevices module */&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;val&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;scope&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"navigator"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"mediaDevices"&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;getUserAudio&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"audio"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_&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;,&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"getUserMedia"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;as-JSON trick&lt;/strong&gt; as I call it has its limits, though. It only works for JSON-compliant values, such as arrays, objects, strings, numbers and booleans. Functions would not work for instance.&lt;/p&gt;

&lt;p&gt;We can do the same with the other two possible functions:&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;/* Navigator.MediaDevices module continued */&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;val&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;scope&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"navigator"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"mediaDevices"&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;getUserVideo&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"audio"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_&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;,&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"getUserMedia"&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;val&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;scope&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;"navigator"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"mediaDevices"&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;getUserMedia&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"audio"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_&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;,&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"getUserMedia"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And end up with the same API as in attempt 1. Again, we can call our functions the same way as before:&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="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserAudio&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserVideo&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="nn"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;MediaDevices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUserMedia&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this time with no build artifacts, the second attempt comes with &lt;strong&gt;zero cost&lt;/strong&gt; 🎉. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule-of-thumb&lt;/strong&gt;: &lt;code&gt;let&lt;/code&gt;s generate additional JS code, &lt;code&gt;external&lt;/code&gt;s don't.&lt;/p&gt;

&lt;p&gt;Thank you for reading and I hope this trick helps some of you. For a condensed example, please have a look at the &lt;a href="https://tinyurl.com/y3owk33j" rel="noopener noreferrer"&gt;ReScript playground example&lt;/a&gt; this blog post is based on.&lt;/p&gt;

</description>
      <category>rescript</category>
      <category>reason</category>
    </item>
    <item>
      <title>What's new in BuckleScript 7?</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Fri, 06 Dec 2019 17:12:39 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/what-s-new-in-bucklescript-7-1bf4</link>
      <guid>https://dev.to/fhammerschmidt/what-s-new-in-bucklescript-7-1bf4</guid>
      <description>&lt;p&gt;Another groundbreaking change for all ReasonML/BuckleScript developers has emerged this week, because BuckleScript 7 has been &lt;a href="https://reasonml.chat/t/ann-bs-platform-7-0-0-is-released/2056/1" rel="noopener noreferrer"&gt;officially released&lt;/a&gt;. The maintainer, Bob Zhang, does a great job in announcing the most important new features and changes on the &lt;a href="https://bucklescript.github.io/blog/" rel="noopener noreferrer"&gt;official BuckleScript blog website&lt;/a&gt;, but I want to cover them in a bit more detail here. Of course, the full changelog can always be viewed at the &lt;a href="https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#701" rel="noopener noreferrer"&gt;repository&lt;/a&gt;, but it's a bit raw to digest and there are some great things hidden behind all those pull requests.&lt;/p&gt;

&lt;p&gt;Allow me to also include some important changes since version 5.2.1, because many people did not even make the jump to v6 already (including me). But v7 has so many good things to offer that the relatively minor risks are outweighed by a bunch of improvements.&lt;/p&gt;

&lt;p&gt;Before I get into it, just a heads up: We upgraded a big codebase to from 5.2.1 to 7.0.1 and had only a very minor &lt;a href="https://github.com/facebook/reason/issues/2507" rel="noopener noreferrer"&gt;issue&lt;/a&gt;. We still released it compiled via BuckleScript 5, because there was just not enough time for thorough testing, but it compiled, no tests failed, and some manual testing has also been successful.&lt;/p&gt;

&lt;p&gt;But we also did not use any &lt;a href="http://ocamllabs.io/doc/ppx.html" rel="noopener noreferrer"&gt;PPXes&lt;/a&gt;, which may be a blocker for others. This was already the biggest hurdle for people switching to v6, since it is based on OCaml 4.06, while v5 is based on OCaml 4.02. The new BuckleScript 7 will still be based on OCaml 4.06, so let's discuss the differences between those two versions first.&lt;/p&gt;

&lt;h1&gt;
  
  
  Changes in V6
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Inline Records
&lt;/h2&gt;

&lt;p&gt;Inline records can now be used as &lt;a href="https://caml.inria.fr/pub/docs/manual-ocaml/manual040.html" rel="noopener noreferrer"&gt;arguments to datatype constructors in sum types&lt;/a&gt;. This is very convenient, for instance when you have a variant type which includes a record in one case, but do not want to create a separate type for the record just for this one variant case. Previously, you were forced to declare a new record type 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="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;x&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="k"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;y&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;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Other&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;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&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;which can be achieved with fewer lines of code now:&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;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;x&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="k"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;y&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="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Other&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;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&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;Nice!&lt;/p&gt;

&lt;p&gt;Well, to be fair the old (v5) compiler gave you an useful error when you used inline records, at least:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;refmt: internal error, uncaught exception:
  File "/[blogposts]/bs-7-example/src/InlineRecord.re", line 2, characters 4-9: inline records are not supported before OCaml 4.03
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Internal Result Type
&lt;/h2&gt;

&lt;p&gt;OCaml baked the &lt;code&gt;result&lt;/code&gt; type with 4.04 into the language. &lt;code&gt;result&lt;/code&gt; is one of the most beloved features about ML and related languages for try-catch-ridden former OOP-developers who found their new home in FP languages. I mean, you can even convert exceptions into less threatening &lt;code&gt;Result.Error&lt;/code&gt;s and everything is fine. On a more serious note, it always bothered me that you need to &lt;code&gt;open Belt&lt;/code&gt; to have a result type at your disposal, because it is equally fundamental to a modern FP language as the option type (in my humble opinion).&lt;/p&gt;

&lt;p&gt;This means that you can do 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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bustAMove&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;move&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;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bust&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bust&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Can't bust a move because of: "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&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;without opening &lt;code&gt;Belt&lt;/code&gt; or any other library which provides a &lt;code&gt;result&lt;/code&gt; type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local opening of modules in a pattern
&lt;/h2&gt;

&lt;p&gt;Local opening of modules can be very useful to prevent name clashes. It's the syntax where you put a &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;()&lt;/code&gt; after a module name to open the module only for what's inside the parentheses, e.g.:&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="nn"&gt;Sausages&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="n"&gt;pork&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;meatGrinder&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fillIntoSkin&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 also use that in a pattern now!&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;module&lt;/span&gt; &lt;span class="nc"&gt;CallMom&lt;/span&gt; &lt;span class="o"&gt;=&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="n"&gt;smalltalk&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;story&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;,&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;callMom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;call&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="nn"&gt;CallMom&lt;/span&gt;&lt;span class="p"&gt;.{&lt;/span&gt;&lt;span class="n"&gt;story&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smalltalk&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;story&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smalltalk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;CallMom&lt;/span&gt;&lt;span class="p"&gt;.{&lt;/span&gt;&lt;span class="n"&gt;smalltalk&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;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Only gossip today"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smalltalk&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;If you tried that with the old BuckleScript, it would yield an error.&lt;/p&gt;

&lt;p&gt;That's all for the changes introduced with BuckleScript 6, let's move on to even more interesting grounds.&lt;/p&gt;

&lt;h1&gt;
  
  
  Changes in V7
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Refmt Update / Re-Error
&lt;/h2&gt;

&lt;p&gt;There has been a lot of work put into a better code parser to get better error messages which was a common pain point for many newcomers. The so-called Re-Error coming with the current ReasonML parser &amp;amp; formatter (refmt) makes the developer experience a bit better.&lt;/p&gt;

&lt;p&gt;Consider the following very simple line of code:&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you compile that, with older refmt versions you only get a&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File "/[redacted]/bs-7-example/src/SampleError.re", line 2, characters 2-6:
Error: SyntaxError in block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;whereas now the message is much more helpful and descriptive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File "/[redacted]/bs-7-example/src/SampleError.re", line 2, characters 6-6:
Error: Unclosed "{" (opened line 1, column 8)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even for more complex errors, it is a great relief that it can still help you out. Imagine having a big tree of JSX functions and a missing closing &lt;code&gt;&amp;gt;&lt;/code&gt; somewhere in the tree:&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&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;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Increment&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Decrement&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;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;action&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;Increment&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;count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Decrement&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;count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&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="bp"&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;state&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reducer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;main&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;React&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;"Simple counter with reducer"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&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="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Decrement&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="nn"&gt;React&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;"Decrement"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&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="n"&gt;span&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;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;string_of_int&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;React&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="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Here we miss a closing '&amp;gt;'&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Increment&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="nn"&gt;React&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;"Increment"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&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="n"&gt;div&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="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The example is from &lt;a href="https://github.com/MargaretKrutikova/reason-minimal-template" rel="noopener noreferrer"&gt;reason-minimal-template&lt;/a&gt;, thanks &lt;a href="https://dev.to/margaretkrutikova"&gt;Margarita&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;BuckleScript 5 cannot deal with this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File "/[redacted]/bs-7-example/src/App.re", line 17, characters 2-66:
Error: SyntaxError in block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;whereas BuckleScript 7 is much better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File "/[redacted]/bs-7-example/src/App.re", line 25, characters 60-62:
Error: syntax error, consider adding a `;' before
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At least the correct line has been found in version 7. The suggestion to add an &lt;code&gt;;&lt;/code&gt; is valid for normal code, but not the syntactic sugar we commonly know as JSX. Still, no more searching for the correct line, you're directly pointed to it and probably can then easily figure out for yourself what's wrong.&lt;/p&gt;

&lt;p&gt;I wanted to make the example simpler initially (i.e. with only setState which means no separately declared types, intitialState and reducer), but then also the old BuckleScript 5.2.1 found the error. The difference is still night and day though, because in my experience, most components turn out more complex than this simple example.&lt;/p&gt;

&lt;p&gt;The work on Reerror is not finalized yet. The roadmap can be found here: &lt;a href="https://github.com/facebook/reason/blob/master/PLAN" rel="noopener noreferrer"&gt;Reerror-Plan&lt;/a&gt;, but it's nice to know that it will continue to improve over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Records as JS Objects
&lt;/h2&gt;

&lt;p&gt;Probably the most impactful change coming with BuckleScript 7 is that now records are not compiled to (nested) arrays anymore, but JavaScript objects. This is not only very nice for debugging, it also makes many of the interop annotations obsolete, or at least makes it more straightforward to write bindings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Easier Debugging
&lt;/h3&gt;

&lt;p&gt;For instance, previously the following record:&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;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;firstName&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;lastName&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;phone&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&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;jordan&lt;/span&gt;&lt;span class="o"&gt;:&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;firstName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Jordan"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Walke"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"73276665"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jordan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produced an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ 'Jordan', 'Walke', '73276665' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which may be more performant, but for more complex records (nested records) it was really hard to find the field you were looking for. Now it produces the following log output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ firstName: 'Jordan',
  lastName: 'Walke',
  phone: '73276665' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is already a great help for debugging, but it gives us much more power.&lt;/p&gt;

&lt;h3&gt;
  
  
  Easier Interop
&lt;/h3&gt;

&lt;p&gt;Let's explore how we can get some cleaner syntax by updating some bindings. As an example, let's take NodeJS' &lt;code&gt;pathObject&lt;/code&gt; which is the output of the &lt;code&gt;parse&lt;/code&gt; function, as well as the input for the &lt;code&gt;format&lt;/code&gt; 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="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;pathObject&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;obj&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;pathObject&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;dir&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;root&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;base&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="o"&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;ext&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;pathObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s2"&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;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;"path"&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;parse&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="n"&gt;pathObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"parse"&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;"path"&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;format&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pathObject&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you wanted to format a &lt;code&gt;pathObject&lt;/code&gt; into a &lt;code&gt;string&lt;/code&gt;, with Bucklescript &amp;lt;= 7 it worked the following way:&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;pathObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/[redacted]/bs-7-example/src"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"NodePath.re"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"NodePath"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;".re"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at how to bind that in BuckleScript 7:&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;pathObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dir&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;root&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;base&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;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;ext&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The methods themselves do not change their type signature, as we use the same name for the type. Calling &lt;code&gt;parse&lt;/code&gt; is a bit more concise and readable now:&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"/[redacted]/bs-7-example/src"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"NodePath.re"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"NodePath"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;".re"&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;It really looks like JavaScript now!&lt;/p&gt;

&lt;p&gt;Bear in mind that for functions with lots of optional parameters it's still easier to use &lt;code&gt;[@bs.obj]&lt;/code&gt;, as you would otherwise need to write conversion functions for the nullable types which come at a runtime cost. Records in ReasonML always need to have all their fields set (even if it is &lt;code&gt;None&lt;/code&gt; or &lt;code&gt;Js.null&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Another benefit of records-as-objects is the ability to pattern-match on them. So now we can match on a NodeJS &lt;code&gt;pathObject&lt;/code&gt; without the need of converting those objects to records:&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;getExtensionType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&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;path&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="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;".re"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Reason&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;".ml"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;OCaml&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;".js"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;JavaScript&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;".ts"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;TypeScript&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="nc"&gt;Unknown&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;Of course in this case you could also just match on &lt;code&gt;path.ext&lt;/code&gt; directly. But it may be the case that you want to combine the extension with a certain name or something. I did not want the example to be too convoluted though, I hope it still supports my intention well.&lt;/p&gt;

&lt;p&gt;Also mentioned on the &lt;a href="https://bucklescript.github.io/blog/2019/12/27/whats-new-in-7-cont" rel="noopener noreferrer"&gt;BuckleScript blog&lt;/a&gt;: you can now use the &lt;code&gt;[@bs.as]&lt;/code&gt; annotation in records too, so whenever you have a &lt;code&gt;-&lt;/code&gt; or any other otherwise unrepresentable character, you could always use that as an escape hatch. It works the same way as usual:&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;httpHeaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;authorization&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="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;"content-type"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;contentType&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="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;"last-modified"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;lastModified&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="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;"if-modified-since"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;ifModifiedSince&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="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Basic thisCouldBeYourCryptoKey"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/javascript; charset=utf-8"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lastModified&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Fri, 06 Dec 2019 07:39:45 GMT"&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;h2&gt;
  
  
  Are we still fast?
&lt;/h2&gt;

&lt;p&gt;One point where BuckleScript never failed to deliver is build time, which has always been very fast. Incremental builds are nearly instant and also full project compilations are no opportunity to do something else in the meantime. However, this time I have to say, that build times actually take a bit longer now, but it is a small fee for a big gain.&lt;/p&gt;

&lt;p&gt;One of our current projects is about 27k lines of Reason code, according to the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find ./src -name '*.re' -o -name '*.ml' | xargs wc -l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the full, cleaned build took around &lt;strong&gt;2250&lt;/strong&gt; milliseconds with BuckleScript 5.2.1, whereas with BuckleScript 7.0.1, it's about &lt;strong&gt;2500ms&lt;/strong&gt;. I do have faith though, that this number will fall again with the next minor releases. The build times were tested on a MacBook Pro (15-inch, 2018), 2,6 GHz Intel Core i7, 32 GB 2400 MHz DDR4.&lt;/p&gt;

&lt;p&gt;That's everything I have to say for today. Maybe some new patterns will emerge from this useful upgrade. I am already exited to use BuckleScript 7 in the next project, what about you? Whenever you are ready to upgrade, consider reading the official &lt;a href="https://bucklescript.github.io/docs/en/upgrade-to-v7" rel="noopener noreferrer"&gt;upgrade guide to v7&lt;/a&gt; first or contact other Reasonauts and BuckleScriptians in the &lt;a href="https://discord.gg/reasonml" rel="noopener noreferrer"&gt;ReasonML discord&lt;/a&gt; for help.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>reason</category>
      <category>bucklescript</category>
    </item>
    <item>
      <title>Reason(React) Best Practices - Part 3</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Sat, 26 Oct 2019 21:12:03 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/reason-react-best-practices-part-3-3bm2</link>
      <guid>https://dev.to/fhammerschmidt/reason-react-best-practices-part-3-3bm2</guid>
      <description>&lt;p&gt;Welcome back to the third part of my blog mini series (&lt;a href="https://dev.to/fhammerschmidt/reason-react-best-practices-2cb7"&gt;Part 1&lt;/a&gt;, &lt;a href="https://dev.to/fhammerschmidt/reason-react-best-practices-part-2-2opc"&gt;Part 2&lt;/a&gt;) which derived from my talk at &lt;a href="https://twitter.com/reasonvienna" rel="noopener noreferrer"&gt;@reasonvienna&lt;/a&gt;. This part is all about writing zero-cost bindings to existing JavaScript functions and React components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Since ReasonReact included Hooks support starting with version &lt;code&gt;0.7.0&lt;/code&gt;, writing React in Reason has become a breeze. The library now became a very thin layer between React and BuckleScript and as a result, we did not need to write tedious boilerplate code anymore (mostly to map to the behaviour of class-based React components). But before the old way gets completely lost in history, here is a small reminder how we wrote React in ReasonML just some months ago:&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;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="s2"&gt;"Greeting"&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;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_children&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;self&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="n"&gt;h1&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;"Hello "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vs.&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;/* Greeting.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;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&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;name&lt;/span&gt;&lt;span class="p"&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="n"&gt;h1&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;React&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;"Hello "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be fair, some magic happens in the &lt;code&gt;react.component&lt;/code&gt; annotation, but it was just more work to create a stateless component in which we needed to spread our component definition into. Not to speak of comparing stateful components, the differences are humungous. For compatibility reasons, we still have the old module (&lt;code&gt;ReasonReact&lt;/code&gt;), but the &lt;a href="https://github.com/reasonml/reason-react/blob/v0.7.0/src/React.re" rel="noopener noreferrer"&gt;new one&lt;/a&gt; (just &lt;code&gt;React&lt;/code&gt;) is about a third of the size of the &lt;a href="https://github.com/reasonml/reason-react/blob/v0.7.0/src/ReasonReact.re" rel="noopener noreferrer"&gt;old one&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Penalty-free bindings
&lt;/h2&gt;

&lt;p&gt;Some of the most important differences though, are the implications on performance. Whereas the old ReasonReact comes with its own React Mini to be compatible with class-based components, the new one is meant to be a very thin layer between React and ReasonML, (mostly) without any additional performance cost. To be fair, this is only true if you use the Hooks API. If you rather write class components, then you still have to use the old approach (but then you probably would not use the FP language Reason either).&lt;/p&gt;

&lt;p&gt;This idea also spilled over to the &lt;a href="https://reasonml-community.github.io/reason-react-native/en/docs/" rel="noopener noreferrer"&gt;React Native bindings&lt;/a&gt;, which are mostly done at this point in time (only some of the more obscure or deprecated ones are missing).&lt;/p&gt;

&lt;p&gt;I think this attitude is a good one to have, because we do not want to lose performance-wise against plain JS - it would make newcomers more hesitant to dive into the ReasonML ecosystem. Even better: by using the right annotations, you get the most out of your bindings and win some developer experience too. For instance if you take &lt;code&gt;[@bs.string]&lt;/code&gt; which converts plain string enums into polymorphic variants (the ones which start with a &lt;code&gt;`backtick&lt;/code&gt;) and in consequence make the compiler restrict your code to using only those variants.&lt;/p&gt;

&lt;p&gt;In the following section, I will examine one of the well-written React-Native bindings, by using example apis or components directly from the &lt;a href="https://github.com/reason-react-native/react-native/tree/master/src" rel="noopener noreferrer"&gt;sources&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  React-Native Alert
&lt;/h3&gt;

&lt;p&gt;The Alert API consists of two callable methods, &lt;code&gt;alert&lt;/code&gt; and &lt;code&gt;prompt&lt;/code&gt;. While &lt;code&gt;prompt&lt;/code&gt; actually does only trigger on iOS devices (and is not even mentioned in the official React Native docs, as of yet), we still want to bind that too for educational purposes. If you look at the &lt;a href="https://github.com/facebook/react-native/blob/0a66ded7d006558213681f8efbdb762cbadfcc08/Libraries/Alert/Alert.js#L19" rel="noopener noreferrer"&gt;JS sources&lt;/a&gt; of &lt;code&gt;Alert&lt;/code&gt;, you will notice the Flow types which make it pretty straightforward to translate everything to Reason code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt;: As the following section contains both JS and ReasonML code, a small comment header will tell you what language I am talking about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: The Reason source code may be formatted differently than what &lt;code&gt;refmt&lt;/code&gt; would put out. I adapted it for readability and conciseness.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first type is &lt;code&gt;AlertType&lt;/code&gt;. It is a string enum consisting of&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="cm"&gt;/* JS */&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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="s1"&gt;plain-text&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="s1"&gt;secure-text&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="s1"&gt;login-password&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;this translates to&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;/* Reason */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alertType&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="kt"&gt;string&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="nt"&gt;`default&lt;/span&gt;
              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`plainText&lt;/span&gt;
              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`secureText&lt;/span&gt;
              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`loginPassword&lt;/span&gt;
            &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you cannot use a hyphen in polymorphic variants, so there is another step necessary:&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;/* Reason */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alertType&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="kt"&gt;string&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="nt"&gt;`default&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;"plain-text"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`plainText&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;"secure-text"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`secureText&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;"login-password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`loginPassword&lt;/span&gt;
            &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;a class="mentioned-user" href="https://dev.to/bs"&gt;@bs&lt;/a&gt;.as] takes care of that. Generally, when there are hyphens, special characters, or numbers at the start, this approach is needed.&lt;/p&gt;

&lt;p&gt;There is also the &lt;code&gt;AlertButtonStyle&lt;/code&gt;, which can be translated in the same way:&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="cm"&gt;/* JS */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AlertButtonStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&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;cancel&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;destructive&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;translates to&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;/* Reason */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;alertButtonStyle&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="kt"&gt;string&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="nt"&gt;`default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`cancel&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`destructive&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then there is &lt;code&gt;Buttons&lt;/code&gt;, an array of &lt;code&gt;Button&lt;/code&gt;. I think it is better to define a button type and then define a buttons array type instead of mixing them all into one type definition, so let's pretend that the JS types are also written like that:&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="cm"&gt;/* JS */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;AlertButtonStyle&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes&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;/* Reason */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// create abstract button type&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;obj&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;button&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;// define a translator function for the button type&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;text&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;onPress&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="kt"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;alertButtonStyle&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="kt"&gt;unit&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;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// returns a button&lt;/span&gt;
  &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// dummy placeholder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one is more complex, so we use &lt;code&gt;[@bs.obj]&lt;/code&gt; here. It lets us define a function from which the compiler derives a JS object. This is useful if you have many optional parameters, as it is the case with the button above. The &lt;code&gt;=?&lt;/code&gt; after the corresponding type denotes that the function is not required.&lt;/p&gt;

&lt;p&gt;Then there is the &lt;code&gt;options&lt;/code&gt; type:&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="cm"&gt;/* JS */&lt;/span&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cancelable&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onDismiss&lt;/span&gt;&lt;span class="p"&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="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which works the same as the button above:&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;/* Reason */&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;options&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;obj&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;options&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;cancelable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;onDismiss&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="kt"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="kt"&gt;unit&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the type information of &lt;code&gt;onDismiss&lt;/code&gt; is much clearer to translate - an empty function body yielding &lt;code&gt;void&lt;/code&gt; which becomes &lt;code&gt;unit =&amp;gt; unit&lt;/code&gt; in Reason land. For translating &lt;code&gt;?Function&lt;/code&gt; one needs to look up the flow docs which say &lt;code&gt;Function&lt;/code&gt; is basically &lt;code&gt;any&lt;/code&gt;, so we only know what it really returns by using it and logging things out or digging through the source code. But in this case, we know it is still &lt;code&gt;unit =&amp;gt; unit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The final piece is the signature of the method itself. As we speak of a JS class component, the &lt;code&gt;alert&lt;/code&gt; method's signature can be found under &lt;code&gt;static alert(...)&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="cm"&gt;/* JS */&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;string&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="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;buttons&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Buttons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which translates to&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;/* Reason */&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;scope&lt;/span&gt; &lt;span class="s2"&gt;"Alert"&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"&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;alert&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;title&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;message&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="o"&gt;~&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;options&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="kt"&gt;unit&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;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most important part here is the first line - we need &lt;code&gt;[@bs.module]&lt;/code&gt; to tell the compiler that we want to call a method from an external module, in this case from &lt;code&gt;"react-native"&lt;/code&gt;. Also we want to look it up under the &lt;code&gt;Alert&lt;/code&gt; module of React Native. Therefore we utilize &lt;code&gt;[@bs.scope]&lt;/code&gt; with &lt;code&gt;"Alert"&lt;/code&gt;. Remember, this is the equivalent of doing&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Alert&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;react-native&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;in JavaScript and I think that it is mapped pretty well that way.&lt;/p&gt;

&lt;p&gt;The signature of the &lt;code&gt;prompt&lt;/code&gt; method is also typed:&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;static&lt;/span&gt; &lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;string&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="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;callbackOrButtons&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;?(((&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Buttons&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;AlertType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plain-text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also looks doable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt; and&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;message&lt;/code&gt; work the same way as in the &lt;code&gt;alert&lt;/code&gt; method,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defaultValue&lt;/code&gt; and&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keyboardTypes&lt;/code&gt; are just strings,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type&lt;/code&gt; is already typed above, known as &lt;code&gt;alertType&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So easy going, right? But what abomination of a property is &lt;code&gt;callbackOrButtons&lt;/code&gt;? This is a JavaScript'ism which I would even call an antipattern in ReasonML. In the Reason (and FP) world, you would rather statically check your types and not inspect whether your prop is an array and do something differently than what you would have done with a function, all at runtime. This is such a thing which can only be done in a dynamically typed language. *&lt;em&gt;hissing snake noises&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;But be assured, that even for such cases, BuckleScript provides a wonderful remedy: [&lt;a class="mentioned-user" href="https://dev.to/bs"&gt;@bs&lt;/a&gt;.unwrap]. It utilizes polymorphic variants which all get compiled away, so we don't lose our precious performance. We just have to create two of them, one for &lt;code&gt;`callback&lt;/code&gt; and one for &lt;code&gt;`buttons&lt;/code&gt;. The button type has been defined already above and the callback just translates easily from Flow again, &lt;code&gt;string =&amp;gt; void&lt;/code&gt; becomes &lt;code&gt;string =&amp;gt; unit&lt;/code&gt; in Reason land.&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;callbackOrButtons&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="n"&gt;unwrap&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="nt"&gt;`callback&lt;/span&gt;&lt;span class="p"&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="p"&gt;)&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`buttons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we end up with 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="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;scope&lt;/span&gt; &lt;span class="s2"&gt;"Alert"&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"&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;prompt&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;title&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;message&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;callbackOrButtons&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="n"&gt;unwrap&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="nt"&gt;`callback&lt;/span&gt;&lt;span class="p"&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="p"&gt;)&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`buttons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;type_&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="cm"&gt;/* alertType */&lt;/span&gt;
              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;`default&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;"plain-text"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`plainText&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;"secure-text"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`secureText&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;"login-password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nt"&gt;`loginPassword&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=?,&lt;/span&gt;
    &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;defaultValue&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;keyboardType&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="kt"&gt;unit&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;"prompt"&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 writing bindings is only half the fun, so here's is an example of how you would use the &lt;code&gt;Alert.alert&lt;/code&gt; binding:&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="nn"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert&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;"Warning!"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Do you want to delete the entry?"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;buttons&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="nn"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;`destructive&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="o"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Cancel"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;`cancel&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="o"&gt;,&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="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nn"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;cancelable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;onDismiss&lt;/span&gt;&lt;span class="o"&gt;=_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Deletion aborted."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="bp"&gt;()&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="bp"&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;And here's is an example of how you would use the &lt;code&gt;Alert.prompt&lt;/code&gt; binding (again, only on iOS):&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="nn"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompt&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;"Enter Password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Please enter your password."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;callbackOrButtons&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;`callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;`secureText&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="bp"&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;Don't forget to call all the defined &lt;code&gt;external&lt;/code&gt;s with their Module name (here &lt;code&gt;Alert&lt;/code&gt;) before or &lt;code&gt;open&lt;/code&gt; it in the scope.&lt;/p&gt;

&lt;p&gt;Speaking of externals, a good rule of thumb to know whether you created some runtime overhead with your bindings, is the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have a look if there are any &lt;code&gt;let&lt;/code&gt;s in your code, rather than &lt;code&gt;external&lt;/code&gt;s.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To be sure look into your created &lt;code&gt;.bs.js&lt;/code&gt; bindings file. When you only see&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="cm"&gt;/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can pat yourself on the shoulder, because you successfully created a zero-cost binding!&lt;/p&gt;

&lt;p&gt;That's all for my mini series about Best Practices in Reason &amp;amp; ReasonReact, at least for now. Any upcoming posts will not be part of this series anymore, but they will almost certainly contain ReasonML stuff.&lt;/p&gt;

&lt;p&gt;So have a great time, and make great (type-safe) things!&lt;/p&gt;

</description>
      <category>reason</category>
      <category>reasonreact</category>
      <category>bucklescript</category>
    </item>
    <item>
      <title>Reason(React) Best Practices - Part 2</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Mon, 30 Sep 2019 12:05:07 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/reason-react-best-practices-part-2-2opc</link>
      <guid>https://dev.to/fhammerschmidt/reason-react-best-practices-part-2-2opc</guid>
      <description>&lt;p&gt;Welcome back to the second part of my blog mini series (the first one is &lt;a href="https://dev.to/fhammerschmidt/reason-react-best-practices-2cb7"&gt;here&lt;/a&gt;) which kinda derived from my talk at &lt;a href="https://twitter.com/reasonvienna" rel="noopener noreferrer"&gt;@reasonvienna&lt;/a&gt;. As promised, the focus of this part is on compiler configuration and the Belt standard library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compiler configuration
&lt;/h2&gt;

&lt;p&gt;Well, it turns out that I am not the first person writing about BuckleScript's compiler flags here on &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;. &lt;a href="https://dev.to/yawaramin"&gt;Yawar Amin&lt;/a&gt; already did a great job with his post &lt;a href="https://dev.to/yawaramin/ocaml-reasonml-best-practice-warnings-and-errors-4mkm"&gt;"OCaml/ReasonML best practice: warnings and errors"&lt;/a&gt;. Still, I have a different view (and only focus on BuckleScript with ReasonML and not native, nor OCaml).&lt;/p&gt;

&lt;p&gt;Furthermore, which warnings you really want to add or remove from the defaults is still highly subjective and may depend on you and your team's specific needs, toolchain and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warnings ⚠️
&lt;/h3&gt;

&lt;p&gt;BuckleScript's compiler warnings can be modified by prepending &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; to a warning number you want to activate or deactivate. No matter whether you just modify one or many warnings, it is always a single string you assign to the &lt;code&gt;"number"&lt;/code&gt; property in the &lt;code&gt;"warnings"&lt;/code&gt; object of your project's &lt;code&gt;bsconfig.json&lt;/code&gt;. Here is an example with one activated and one deactivated warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bsconfig.json&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"warnings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+102-105"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also a special &lt;code&gt;A&lt;/code&gt; modifier, which means ALL of them - so if you for example put a &lt;code&gt;+A&lt;/code&gt; modifier before everything else, it only makes sense to deactivate other warnings, because really all of them are now activated. We at &lt;a href="https://cca.io" rel="noopener noreferrer"&gt;cca.io&lt;/a&gt; don't use that, though. We just use the two you see above. There are even more letter-warnings, but most of them are just aliases for existing warning numbers or groups of warnings. Finally, there is an &lt;code&gt;@&lt;/code&gt; modifier, which does the same as &lt;code&gt;+&lt;/code&gt; and also makes the compiler treat that specific warning as an error. If you want to list the default configuration, you can print that on the terminal via &lt;code&gt;bsc -help&lt;/code&gt; and look under &lt;code&gt;-w&lt;/code&gt; (or use &lt;code&gt;bsc -help | grep "+a"&lt;/code&gt; if you are impatient). It yielded me the following on version 5.2.0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bsc &lt;span class="nt"&gt;-help&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"+a"&lt;/span&gt;
  default setting is &lt;span class="s2"&gt;"+a-4-6-7-9-27-29-32..39-41..42-44-45-48-50-102"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time of writing this post, BuckleScript comes with a whopping 62 availabe compiler warning types which have been inherited from OCaml, whereas they add another five, starting with the number &lt;code&gt;101&lt;/code&gt;. Here are those five BuckleScript-specific warning types (I found them in one place in the &lt;a href="https://github.com/BuckleScript/bucklescript/blob/5.2.0/lib/4.06.1/bspp.ml#L3393" rel="noopener noreferrer"&gt;sources&lt;/a&gt; only, and tried to derive descriptions for them based on my usage experience).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;⚠️&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;Bs_unused_attribute&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;When a BS decorator attribute can not be applied to code underneath (&lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=NoAQRgzgdA9mBWBdAUAGwKYBcAEFsF5sAiACQFEBNIgbiA" rel="noopener noreferrer"&gt;Try&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Bs_polymorphic_comparison&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Disallow polymorphic comparisons (i.e. using &lt;code&gt;==&lt;/code&gt; on complex data structures).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Bs_ffi_warning&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;When a foreign function interface (FFI annotation == BS decorator) is missing. (&lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=NoAQRgzgdAbghgGwLoCgCmAPALmgTgO0QAIAzALiIAoA-OC4IgHyIAM5KBLfLASiR6IBeAHxEIWXFwDmQogCI5AbiA" rel="noopener noreferrer"&gt;Try&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Bs_derive_warning&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;When using &lt;code&gt;[@bs.deriving]&lt;/code&gt; on an unsupported type (&lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=NoAQRgzgdAJgpgJwJYDckDsDmACAVhAYQHt0VEAXRAXQChyBPABzmwEMBuGoA" rel="noopener noreferrer"&gt;Try&lt;/a&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;Bs_fragile_external&lt;/td&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;When using the empty &lt;code&gt;""&lt;/code&gt; shorthand in external declarations to infer the JS function name from the Reason one.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, there is only one warning type deactivated by default, which is 102: &lt;em&gt;Disallow polymorphic comparisons&lt;/em&gt;. We activated this one because when we just started writing apps in ReasonML, we used it heavily to compare deeply nested records. At some point, we stumbled over bugs where things were not equal in our minds, but the language still evaluated them so. Thus, we activated 102 and found some more possible pitfalls in our codebase. If you use it, you need to be prepared to write your own comparison functions for your data structures, or at least use the compare functions provided by the Pervasives module, or Belt's &lt;code&gt;List.cmp&lt;/code&gt;, et cetera. Luckily, we are by far &lt;a href="https://discuss.ocaml.org/t/removing-polymorphic-compare-from-core/2994" rel="noopener noreferrer"&gt;not the only ones with that mindset&lt;/a&gt;. It is also recommended to turn it on by the &lt;a href="https://reasonml.chat/t/polymorphic-compare-in-reasonml-bucklescript/1294/7?u=fham" rel="noopener noreferrer"&gt;creator of BuckleScript himself&lt;/a&gt;, at least when you consider yourself experienced enough.&lt;/p&gt;

&lt;p&gt;We also deactivated 105 for a current project, though that was more due to laziness to not have to change hundreds of lines of JS bindings. There were just too many warnings to cope with, after the &lt;a href="https://bucklescript.github.io/blog/#a-new-warning-number-105" rel="noopener noreferrer"&gt;BuckleScript upgrade to version 5.0.5&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Errors ❌
&lt;/h3&gt;

&lt;p&gt;All warnings can also be treated as errors. This may disturb the developer experience, but in a continuous integration context it can be pretty useful. The programmer only needs to ensure to push code without warnings, so that the app will be built. If you feel like a 10x engineer, you can also activate it in your local coding setup. 😉&lt;/p&gt;

&lt;p&gt;Just add the corresponding string of warnings you want to let the compiler fail on to the &lt;code&gt;"error"&lt;/code&gt; property, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bsconfig.json&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"warnings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+8+11+12+26+27+31+32+33+34+35+39+44+45+102"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The string above also happens to be the one we actually use in CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flags 🏁
&lt;/h3&gt;

&lt;p&gt;There is another very useful property in the &lt;code&gt;bsconfig.json&lt;/code&gt;, the &lt;code&gt;"bsc-flags"&lt;/code&gt;, those are the parameters with which the &lt;code&gt;bsc&lt;/code&gt; compiler is invoked by default. Most of them have pretty sane defaults, but it is still nice to know that there are lots of knobs to finetune the behaviour of the compiler. As it is the case with warnings, there are also flags derived from OCaml as well as BuckleScript-specific ones, which are prefixed with &lt;code&gt;-bs&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;bsc --help&lt;/code&gt; lists all the possible options (a load of them!), so check them out if you are interested.&lt;/p&gt;

&lt;p&gt;Personally, I only scratched the surface of all those possibilities, but for instance you can deactivate the &lt;code&gt;bs&lt;/code&gt; header in the compiled &lt;code&gt;.bs.js&lt;/code&gt; files via &lt;code&gt;-bs-no-version-header&lt;/code&gt;.&lt;br&gt;
It looks like that at the top of every generated file, by default:&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;// Generated by BUCKLESCRIPT VERSION 5.0.4, PLEASE EDIT WITH CARE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We omit them to be able to compare output of different compiler versions (useful for beta-testing of new BS releases), and other than that, we do not feel that it's very necessary for an app you want to ship. It may be a different story for libraries which get consumed by JS.&lt;/p&gt;

&lt;p&gt;Another useful flag is &lt;code&gt;-open&lt;/code&gt; which requires a module name, e.g. &lt;code&gt;-open Belt&lt;/code&gt;. This opens the given module in every Reason (or OCaml) file you are editing, so there is no need to put an&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;open&lt;/span&gt; &lt;span class="nc"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;at the top of most files. This is especially useful, if you have a common module you want to share over the whole codebase, like some utility functions. In the case of &lt;code&gt;Belt&lt;/code&gt;, you also cannot make the mistake anymore to use a built-in &lt;code&gt;List&lt;/code&gt; or &lt;code&gt;Array&lt;/code&gt; method, instead of the more idiomatic, pipe-first and camelCase &lt;code&gt;Belt&lt;/code&gt; counterparts. This is only recommended if you are sure that you will never use the (OCaml-ish) built-ins. Personally, I don't do that yet, but I also don't really use the built-ins and could easily do the jump any time.&lt;/p&gt;

&lt;p&gt;Speaking of &lt;code&gt;Belt&lt;/code&gt;, let's head to the next chapter...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Belt stdlib
&lt;/h2&gt;

&lt;p&gt;When I started with Reason, I was overwhelmed by the possibilities of both the OCaml stdlib and the Belt one (Belt was also less extensive at that time). It also did not help, that you are often forced to read interface files as documentation in the OCaml world. It may be efficient, because types need to be correct which is not always the case for documentation, but if you want to lure aspiring JS devs on your type-safe boat, nothing is nicer than a pretty, tidied documentation, possibly with examples which let you dive in directly.&lt;/p&gt;

&lt;p&gt;Luckily, the &lt;a href="https://www.reason-association.org/projects/better-learning-materials-and-tools" rel="noopener noreferrer"&gt;Reason Association started a big project&lt;/a&gt; where, among other things, the Belt documentation will be overhauled and vastly improved, extended with examples, et cetera. If you are interested, you can have a look at the current status over at the future home of ReasonML, &lt;a href="https://reasonml.org" rel="noopener noreferrer"&gt;reasonml.org&lt;/a&gt; or even help out and submit a PR (there are some &lt;a href="https://github.com/reason-association/reasonml.org/issues" rel="noopener noreferrer"&gt;good first issues&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Also, here on dev.to, &lt;a href="https://dev.to/johnridesabike"&gt;John Jackson&lt;/a&gt; already wrote &lt;a href="https://dev.to/johnridesabike/introduction-to-bucklescript-s-belt-containers-map-hashmap-set-3b5l"&gt;a pretty good series about Belt's containers&lt;/a&gt;, which can also help at least until the docs are finished.&lt;/p&gt;

&lt;h3&gt;
  
  
  The SortArray module
&lt;/h3&gt;

&lt;p&gt;There is one tidbit I want to share here, and that is about how to sort Arrays with Belt. Becaues you may wonder where the sort method is (spoiler: it's not in the &lt;code&gt;Belt.Array&lt;/code&gt; module). To keep it short: it is right in the root of the &lt;code&gt;Belt&lt;/code&gt; module, namely &lt;code&gt;Belt.SortArray&lt;/code&gt;. If you have an array of records, for instance users you want to sort by their last name, the idiomatic way is to provide a compare function for the &lt;code&gt;User&lt;/code&gt; record type. The simplest compare function is a &lt;code&gt;-&lt;/code&gt; for &lt;code&gt;int&lt;/code&gt;, but as you learned above, a stricter approach is preferable:&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;module&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&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="n"&gt;firstName&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;lastName&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;id&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="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;compare&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&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;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastName&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;In the above case, we just use a simpler part of the record (the &lt;code&gt;lastName&lt;/code&gt;, which is a &lt;code&gt;string&lt;/code&gt;), to compare the whole user record, for instance to view it in a table sorted by last name. The &lt;code&gt;String.compare&lt;/code&gt; function is out of the &lt;code&gt;Pervasives&lt;/code&gt;, so it is available by default. Compare functions have to have the same signature as &lt;code&gt;Pervasives.compare&lt;/code&gt; and return &lt;code&gt;-1&lt;/code&gt; (or any negative integer) when &lt;code&gt;a &amp;lt; b&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; (or any positive integer greater than 0) when &lt;code&gt;a &amp;gt; b&lt;/code&gt;, and &lt;code&gt;0&lt;/code&gt; when they are equal.&lt;/p&gt;

&lt;p&gt;This is also the kind of function which can be consumed by &lt;code&gt;SortArray&lt;/code&gt;, like so:&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;sortUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;User&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;SortArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stableSortBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we use stableSortBy, which is one of the most common methods of the module, but there are many more, like &lt;code&gt;intersect&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, &lt;code&gt;union&lt;/code&gt; or &lt;code&gt;binarySearch&lt;/code&gt;.&lt;br&gt;
Feel free to try this on an array of users in the &lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=PYBwpgdgBAQmA2AXA3AKFQW2AEwK7zCgFUBnMAJygF4oBvVKKRAT3CerocagDMBLciUQA5AIYYwALihDyfCAHMANF0bxRQsROmz5y1VD7YdiOYpWMAvmi4FEUAMbAMIUeUI0AFKOmIlUACNfAEpqAD4oAGVTPQA6Jxc3MG9Y9U1xMH8A1I0RDOC0a3Q7GWByRFIKEg5PXDJBaTdyUWZPSvJYxGDQqgi6qoBaMMiyxABBcmbmWKFRAIIR8phW9vjnV3cC4rB7fsEOAG0AHy5aVf5BPO0oACIAUXh4PmBEG-80q6lbsfhsKuAIG9DMZbgBmACcABYABw3SwWOgXdLXG4AFWY7keQI+Wi+NwA6ggng4ANZAozSG6QgBM4IADHCEbQkZ9KWNFAhRNjcrjKQBZYAkEjkkE3ACM1LpAHZGagjgBdGx7EhDEijdoqsIAKRIqWACmQQA" rel="noopener noreferrer"&gt;Reason Try playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And that's all for this issue of my Reason(React) Best Practices blog. Next time I will shed some light on how to write zero-cost bindings to JS modules with BuckleScript.&lt;/p&gt;

</description>
      <category>reason</category>
      <category>reasonreact</category>
      <category>bucklescript</category>
    </item>
    <item>
      <title>Reason(React) Best Practices - Part 1</title>
      <dc:creator>Florian Hammerschmidt</dc:creator>
      <pubDate>Fri, 20 Sep 2019 19:21:23 +0000</pubDate>
      <link>https://dev.to/fhammerschmidt/reason-react-best-practices-2cb7</link>
      <guid>https://dev.to/fhammerschmidt/reason-react-best-practices-2cb7</guid>
      <description>&lt;p&gt;After using Reason with React for nearly 2 years, I decided to hold a talk about best practices with Reason and ReasonReact at the ReasonML meetup in Vienna (&lt;a href="https://twitter.com/reasonvienna" rel="noopener noreferrer"&gt;@reasonvienna&lt;/a&gt;). Given that it was my first tech talk in a tech meetup, it went pretty well. I published the slides that same day on Twitter, but slides unfortunately do not tell the full story. So I decided to give it a go and put it here in a more descriptive form. I also split it up a bit, as the talk took about one hour and I prefer to keep blog posts short and to the point.&lt;/p&gt;

&lt;p&gt;But enough waffling, let's get into it:&lt;/p&gt;

&lt;h2&gt;
  
  
  The identity trick
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Zero-cost React.strings!
&lt;/h3&gt;

&lt;p&gt;With Reason being a 100 % type-safe language, there are some peculiarities about writing JSX in Reason which make life for beginners hard, especially when they come from JS and are used to write strings directly into a &lt;code&gt;&amp;lt;div /&amp;gt;&lt;/code&gt; or any other React element which allows children. In Reason, the &lt;code&gt;React.string&lt;/code&gt; method is needed everywhere where you want to render text in your app, so it makes sense to create a binding for it to a one-letter function.&lt;/p&gt;

&lt;p&gt;You could do that by writing&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;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;React&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but you can utilize the compiler to optimize all unnecessary parts away, by using the &lt;code&gt;external&lt;/code&gt; keyword:&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;/* Shorter replacement for React.string */&lt;/span&gt;
&lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;s&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="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"%identity"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compare the methods, check out this example in the ReasonML playground: &lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=LYewJgrgNgpgBAMQJYCcDOAXOBeOBvAKDjlizRzgCUYBDAYwwDpMUkA7AcwG4Ci4BtAAIpaDRnRDAADiDYw2GALp9ScYDQDW8XAAoAlDgB8+PsWIAeMEgBuxvGh0AiZOgyO9AXzjmA9Fdt8HjxBvKCQsHAAyjASbGAUhMQwAB4YMChsNFBwaABcORisnEZUokwwsMDyWLiOAKRIYNVIGACejjzEfEIi9EwS0rLVysSq6loU+iWJZhb+dg6O0bFg7l6+84HBXEA" rel="noopener noreferrer"&gt;ReasonML Try - 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you can see, there is still a function &lt;code&gt;s&lt;/code&gt; being created in the first example, whereas the second one is nowhere to be found. It's probably a very very small runtime improvement, but it gives a good idea of how the BuckleScript compiler works. And if you look at the sources, it is actually the same thing as the provided &lt;code&gt;React.string&lt;/code&gt; from &lt;a href="https://github.com/reasonml/reason-react/blob/v0.7.0/src/React.re#L5" rel="noopener noreferrer"&gt;ReasonReact&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In either way, you probably should put the helper function in a utilities module which you can &lt;code&gt;open&lt;/code&gt; everywhere you need those precious strings in react elements, like so:&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;open&lt;/span&gt; &lt;span class="nc"&gt;ReactUtils&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;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&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="bp"&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="n"&gt;div&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;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, dev.to!"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I named the module &lt;code&gt;ReactUtils&lt;/code&gt;, because it is specifically meant for working with React elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep your codebase free of magic!
&lt;/h3&gt;

&lt;p&gt;Sometimes the type system is just too strict, and in a heterogenous software system there may exist types which are completely the same thing, only with different names. With the &lt;code&gt;identity&lt;/code&gt; trick you can convert types when they would be actually the same, for instance &lt;code&gt;Js.Dict.t(string)&lt;/code&gt; and &lt;code&gt;Js.Json.t&lt;/code&gt;:&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;apples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Dict&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="kt"&gt;string&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;oranges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Json&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apples&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;apples&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromArray&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="s2"&gt;"taste"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sweet"&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;eatFruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Json&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Eating fruits"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;eatFruits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apples&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, we have apples and oranges here. Both are fruits, as commonly known, but only oranges are actually also defined as &lt;code&gt;Js.Json.t&lt;/code&gt;. Apples however are defined as &lt;code&gt;Js.Dict.t(string)&lt;/code&gt; which makes the compiler throw an error (see &lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=C4TwDgpgBAhmYBsIGcoF4oClkDoAiAlgMbA7AAUywATgQHYDmAlANwBQokUA9tTIynRZc2bnTLs2SYFHJxEKAFyx4SZEyHZ8xUgDNq3ALYBBanxDkA2gB9yAImAwqEOwBood5AHcIEYHaZrAF1WNik-KAgYYAAxagBXAmBUDHJ9ROTlLVFxYA00AD5hHARuBgAmewBRaPoGKHSk5DcGhKbQtijYtuS5VRRQoA" rel="noopener noreferrer"&gt;ReasonML Try - 2&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The easiest way to make this code compile is to use &lt;code&gt;Obj.magic&lt;/code&gt;. It basically switches the type checker off and lets the compiler do his job.&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="n"&gt;eatFruits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apples&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=C4TwDgpgBAhmYBsIGcoF4oClkDoAiAlgMbA7AAUywATgQHYDmAlANwBQokUA9tTIynRZc2bnTLs2SYFHJxEKAFyx4SZEyHZ8xUgDNq3ALYBBanxDkA2gB9yAImAwqEOwBood5AHcIEYHaZrAF1WNik-KAgYYAAxagBXAmBUDHJ9ROTlLVFxYA00AD5hHARuBgAmewBRaPoGKHSk5DcGhKbQtijYtuS5VRQAWgKAeQAjACscQxgGYlCgA" rel="noopener noreferrer"&gt;ReasonML Try - 3&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Obj.magic&lt;/code&gt; is actually also implemented by using the identity trick:&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;external&lt;/span&gt; &lt;span class="n"&gt;magic&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"%identity"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(see the &lt;a href="https://github.com/BuckleScript/ocaml/blob/698e60f3cd2f442f2013e79860ce2f7b0a9624cb/stdlib/obj.ml#L20" rel="noopener noreferrer"&gt;source code&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;But it is both more idiomatic (and less risky) to write a conversion function for the two specific 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;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Json&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;external&lt;/span&gt; &lt;span class="n"&gt;applesToFruits&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;apples&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"%identity"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;eatFruits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apples&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;applesToFruits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets your code compile and still ensures that there is only one distinct type consumed by the function and not &lt;em&gt;everything&lt;/em&gt;. It still may make sense to use &lt;code&gt;Obj.magic&lt;/code&gt; sometimes, especially when you just want to create a quick prototype (see &lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=C4TwDgpgBAhmYBsIGcoF4oClkDoAiAlgMbA7AAUywATgQHYDmAlANwBQokUA9tTIynRZc2bnTLs2SYFHJxEKAFyx4SZEyHZ8xUgDNq3ALYBBanxDkA2gB9yAImAwqEOwBood5AHcIEYHaZrAF1WNik-KAgYYAAxagBXAmBUDHJ9ROTlLVFxYA00AD5hHARuBgAmewBRaPoGKHSk5DcGhKbQjnBoRuTNEWQxCTYIAA9gCGo6GAQVBWQAFW44jORleTV0Ip6UjwBSAgATCDpgJJA7SSjYtuS5VRQAWgL1lEXl9vYgA" rel="noopener noreferrer"&gt;ReasonML Try - 4&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use the Pipes like Mario!
&lt;/h3&gt;

&lt;p&gt;As many (functional) languages do, also Reason provides us with a special pipe operator (&lt;code&gt;-&amp;gt;&lt;/code&gt;), which essentially flips the code inside out, e.g. &lt;code&gt;eatFruits(apple)&lt;/code&gt; becomes &lt;code&gt;apple-&amp;gt;eatFruits&lt;/code&gt;. At first it was hard for me to read and comprehend longer pipe chains, but I got used to it after some days of using them. Now they are one of the most indispensable features to me.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keeps you from needing to find a name for in-between variables.&lt;/li&gt;
&lt;li&gt;Keeps code tidy.&lt;/li&gt;
&lt;li&gt;Especially useful with &lt;code&gt;Belt&lt;/code&gt; (BuckleScript's standard library) and its &lt;code&gt;Option&lt;/code&gt; module which you will encounter very often as we have no &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; here in Reason land.&lt;/li&gt;
&lt;li&gt;When using pipe-first (&lt;code&gt;-&amp;gt;&lt;/code&gt;) with, say &lt;code&gt;Array.map&lt;/code&gt;it makes the code look pretty similar to Js, e.g.: &lt;code&gt;[|1, 2, 3|]-&amp;gt;Array.map(x =&amp;gt; x * 2)&lt;/code&gt; which would be &lt;code&gt;[1, 2, 3].map(x =&amp;gt; x * 2)&lt;/code&gt; in plain JS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But just compare the two examples below, first one without using pipes:&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;vehicle&lt;/span&gt; &lt;span class="o"&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;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optionalId&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;vehicles&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;vehicleName&lt;/span&gt; &lt;span class="o"&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;mapWithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"–"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vehicleName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vs.&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="n"&gt;member&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optionalId&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;flatMap&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;vehicles&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&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="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapWithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"–"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&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;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pipe parameter position paranoia!
&lt;/h3&gt;

&lt;p&gt;I know there is some war going on between the last-pipers (mostly native Reason and OCaml developers) and the first-pipers (BuckleScript developers), but in BuckleScript, because you have JS as the target language, pipe-first is the way to go. The type inference also works better that way.&lt;/p&gt;

&lt;p&gt;If you really want to pipe into a function which is not idiomatic to BS (i.e. the positional parameter is not the first one), you can use the &lt;code&gt;_&lt;/code&gt; character to substitute where the piped parameter should go:&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="s2"&gt;"ReasonReact"&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Reason"&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;but rather use the pipe-first version of a function preferably, as long as it exists:&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="s2"&gt;"ReasonReact"&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;String2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Reason"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as mentioned earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Labels to the rescue!
&lt;/h2&gt;

&lt;p&gt;When you have a function like &lt;code&gt;String.includes&lt;/code&gt; where multiple parameters have the same type, it would be much better to label them directly, otherwise you won't know which of the parameters is the source string, and which one is the search string:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpvwg2ghrj29rudh94dh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpvwg2ghrj29rudh94dh.png" alt="string.includes" width="800" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even worse, if you use the wrong pipe (&lt;code&gt;|&amp;gt;&lt;/code&gt;) and are unsure which parameter it takes, you can get confused easily. And the compiler cannot save you from that case, as the types are totally correct.&lt;/p&gt;

&lt;p&gt;Here is a &lt;code&gt;String.includes&lt;/code&gt; function binding with labels to keep you from guessing which one the positional parameter is:&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;module&lt;/span&gt; &lt;span class="nc"&gt;BetterString&lt;/span&gt; &lt;span class="o"&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;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;includes&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;searchString&lt;/span&gt;&lt;span class="o"&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;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"includes"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="s2"&gt;"ReasonReact"&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;BetterString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;searchString&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Reason"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;a href="https://reasonml.github.io/en/try?rrjsx=true&amp;amp;reason=LYewJgrgNgpgBAIRgF2TATgZWeglgOwHM4BeOAbwCg44BtAAQCMBnAOmZnzAF04YAPNOnwBDKHAIBjKBDAxmcAFxwAFMxwFCAGjgA-DiPSSAFtjxFl684QCUpAHxxGIEOLIAiKTLnN3AbkoAXwDKdwAlGBFmEHwIkUlkdwBaeyRUDDNNVi9ZeRVwyOj8dxsUgCk2KBBCPyA" rel="noopener noreferrer"&gt;ReasonML Try - 5&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;To be fair, we now need to type a bit more, but we gain some doubtlessness and do not have to check MDN to be sure. Also, when you ignore warnings or deactivate the corresponding compiler warning (it's number 6), you could still call the function without labelling the parameter. I would still advise you to not do that, though.&lt;/p&gt;

&lt;p&gt;That's all for the first part of &lt;em&gt;Reason(React) Best Practices&lt;/em&gt;, our next topic will be about &lt;a href="https://dev.to/fhammerschmidt/reason-react-best-practices-part-2-2opc"&gt;BuckleScript's compiler configuration and Belt&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>reason</category>
      <category>reasonreact</category>
      <category>bucklescript</category>
    </item>
  </channel>
</rss>
