<?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>Forem: Gal Schlezinger</title>
    <description>The latest articles on Forem by Gal Schlezinger (@schniz).</description>
    <link>https://forem.com/schniz</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%2F2046%2Fprofile_pic.jpg</url>
      <title>Forem: Gal Schlezinger</title>
      <link>https://forem.com/schniz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/schniz"/>
    <language>en</language>
    <item>
      <title>Why fnm was rewritten in Rust</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Fri, 05 Mar 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/why-fnm-was-rewritten-in-rust-1bo2</link>
      <guid>https://forem.com/schniz/why-fnm-was-rewritten-in-rust-1bo2</guid>
      <description>&lt;p&gt;This blog post was in the “drawer” for a long time, so I thought it would be nice to just publish it.&lt;/p&gt;




&lt;p&gt;&lt;a href="//../windows-long-paths-in-rust"&gt;It wasn’t very long ago&lt;/a&gt;, when I mentioned I’m rewriting &lt;a href="https://github.com/Schniz/fnm"&gt;fnm&lt;/a&gt; in Rust. At first, I was just experimenting in order to learn the language: fnm is kinda wide in its scope — works with the file system, network and user input, and I know exactly what to test. After a couple of days experimenting with Rust I had some insights, comparing it to Reason.&lt;/p&gt;

&lt;p&gt;Reason and Rust feel very close, as if they were family. I guess that most of it comes from having ML-style type system with C-style syntax. Rust is usually treated as a lower-level language (it is), and as a very verbose one, because if you compare it to higher-level languages like Reason, you find yourself much more explicit about what you want, like passing references and static strings, etc. But seems that while you still think about memory more, Rust provides great ways to abstract knowledge and build higher-level components to your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trait System
&lt;/h2&gt;

&lt;p&gt;I think one of Rust’s biggest strengths is its trait system. AFAIK, it is very similar to Haskell’s typeclass, Swift’s protocol extensions, and they’re very similar to Java’s interfaces, with a unique superpower: You can implement your trait on 3rd party struct — including the standard library.&lt;/p&gt;

&lt;p&gt;That means you can implement a custom trait on &lt;code&gt;std::fs::File&lt;/code&gt;, or implement a standard library trait to your type, like &lt;code&gt;std::default::Default&lt;/code&gt; or &lt;code&gt;std::fmt::Debug&lt;/code&gt; (both can be simply derived, more on that in a bit).&lt;/p&gt;

&lt;p&gt;Reason and OCaml do not have anything like traits. You can use functors and almost get with it, but it’s not 100% there.&lt;/p&gt;

&lt;p&gt;Seems that using traits can get you very far and provide great higher-level APIs that preserve type safety. Check out &lt;a href="https://docs.rs/structopt"&gt;&lt;code&gt;structopt&lt;/code&gt;&lt;/a&gt;, a derive macro that allows you to use the &lt;a href="https://doc.rust-lang.org/std/str/trait.FromStr.html"&gt;&lt;code&gt;FromStr&lt;/code&gt;&lt;/a&gt; trait on any type and parse command line information from it. That means that you can declare ANY TYPE you want and use it as a CLI argument, parsing it from the user input. Do you want to use a URL? Luckily, &lt;code&gt;reqwest::Url&lt;/code&gt; is implementing &lt;code&gt;FromStr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In fnm, we also get &lt;code&gt;UserVersion&lt;/code&gt; which is some kind of a version requirement: it can be the system version (literal &lt;code&gt;system&lt;/code&gt;), it can be an alias or a semantic version &lt;code&gt;MAJOR.MINOR.PATCH&lt;/code&gt; optionally prefixed with &lt;code&gt;v&lt;/code&gt;, where MINOR and PATCH are optional too. In fnm, we implement &lt;code&gt;FromStr&lt;/code&gt; to &lt;code&gt;UserVersion&lt;/code&gt; and let &lt;code&gt;structopt&lt;/code&gt; to handle the parsing errors and print a nice message to the user.&lt;/p&gt;

&lt;p&gt;This is one of the ways the trait system allows to build better software simpler, comparing to &lt;a href="https://github.com/dbuenzli/cmdliner"&gt;Cmdliner&lt;/a&gt; which is a great utility but was VERY hard for me to use and reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deriving
&lt;/h2&gt;

&lt;p&gt;Another great Rust feature is the &lt;code&gt;#[derive()]&lt;/code&gt; annotation. Similar to some Reason/OCaml PPX extensions, when put on top of a data structure, it can generate code for you in compile time, &lt;em&gt;that will be type-checked&lt;/em&gt;. Rust comes with some deriving macros out of the box, like &lt;code&gt;Debug&lt;/code&gt; (which allows you to pretty-print with the &lt;code&gt;{:?}&lt;/code&gt; format string or &lt;code&gt;dbg!&lt;/code&gt; macro), &lt;code&gt;PartialEq&lt;/code&gt; and &lt;code&gt;Eq&lt;/code&gt; for equality checks, etc.&lt;/p&gt;

&lt;p&gt;The Rust crates embrace this type of macros, and awesome libraries use it to create higher-level abstractions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/serde"&gt;Serde&lt;/a&gt; allows you to derive a Serializer and Deserializer for your &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;enum&lt;/code&gt;, allowing you to serialize or de-serialize these data structures &lt;em&gt;safely&lt;/em&gt; into various formats, like JSON, YAML, TOML, RON…&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/structopt"&gt;StructOpt&lt;/a&gt; allows you to derive a &lt;a href="https://docs.rs"&gt;Clap&lt;/a&gt; configuration from your data structures. This is amazing, because it removes so much boilerplate, and co-locate the CLI definition with the data structures.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/snafu"&gt;Snafu&lt;/a&gt; allows you to get a great developer experience for error handling, by allowing you to create error &lt;code&gt;enum&lt;/code&gt;s and define the error messages next to their declaration. It also provides some nice macros to &lt;code&gt;ensure!&lt;/code&gt; that something works, and some extensions to data structures like &lt;code&gt;Option&lt;/code&gt; and &lt;code&gt;Result&lt;/code&gt; for converting them into the meaningful errors you have defined.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;Last year I visited Chicago to attend ReasonConf US. I talked there to great people like &lt;a href="https://twitter.com/jordwalke"&gt;Jordan&lt;/a&gt;, &lt;a href="https://twitter.com/sander_spies"&gt;Sander&lt;/a&gt;, &lt;a href="https://twitter.com/peterpme"&gt;Peter&lt;/a&gt; and &lt;a href="https://twitter.com/ryyppy"&gt;Patrick&lt;/a&gt;. It was tons of fun, but also made me realize something I didn’t understand before.&lt;/p&gt;

&lt;p&gt;The Reason community was divided — OCaml vs Reason, Native vs BuckleScript vs Js_of_ocaml. Being a small community, we should invest in providing the best tools and experience, and when we can’t provide the best experience if we’re not focused.&lt;/p&gt;

&lt;p&gt;When writing an HTTP server in native Reason you might lack a library for New Relic, or Bugsnag, or Sentry. Stack traces are not really a thing. Using Node as a mature VM is very appealing — and if you need something that performs better — you can write it in a different language. Realistically, people ship Node apps all the time, so the performance and safety guarantees Reason provides should be enough.&lt;/p&gt;

&lt;p&gt;In fnm, I couldn’t really understand how to use the &lt;code&gt;tar&lt;/code&gt; opam package. This is why fnm used to shell out to &lt;code&gt;tar&lt;/code&gt;, to extract the Node versions. This would obviously fail on Windows, but fnm didn’t work on Windows anyway, and I had no idea how to make it work in OCaml. In Rust, it is very easy to do conditional compilation for a specific configuration, so there are some differences in the Windows vs *nix versions of fnm now — especially regarding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The installation files: Node.js is distributed in &lt;code&gt;.tar.xz&lt;/code&gt; for *nix binaries, and &lt;code&gt;.zip&lt;/code&gt; for Windows binaries.&lt;/li&gt;
&lt;li&gt;The simple “shell inference” fnm has, to know on what shell type you’re using, is using &lt;code&gt;ps&lt;/code&gt; on *nix, and &lt;code&gt;wmic&lt;/code&gt; on Windows. Both share the same return types so the module abstracts away the differences.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Rust, being a newer language, has some niceities to it, like centralized documentation on &lt;a href="https://docs.rs"&gt;https://docs.rs&lt;/a&gt;. It’s an amazing experience, having all the documentation for every crate on one site with a familiar theme. I know both &lt;a href="https://twitter.com/ulrikstrid"&gt;Ulrik&lt;/a&gt; and Patrick are very into it and I hope they’ll succeed doing so.&lt;/p&gt;

&lt;p&gt;Another cool feature is the doctests which is something that I knew from Elixir and Rust supports it natively too. When you write code in your docs, &lt;code&gt;cargo test&lt;/code&gt; will test it. It’s that easy. No more unmaintained README or other documentation. This is the future.&lt;/p&gt;

&lt;p&gt;These are two things most languages should learn from.&lt;/p&gt;




&lt;p&gt;Overall, feels that since the (big) Rust community is focused around the native toolchains (and not compile-to-JS), makes it easier to build native, performant CLIs in Rust compared to Reason. I no longer have to find out environment variables to compile C libraries with specific flags, because Cargo has feature toggles and I use it instead. I build an ARM-compatible binary to distribute for those running fnm in their Raspberry Pi’s. We now fully support Windows, so no more gatekeeping for people with different OS choices.&lt;/p&gt;

&lt;p&gt;All without pounding my head against the wall.&lt;/p&gt;

&lt;p&gt;Except from the build time, which is much faster in Reason.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>fnm</category>
      <category>rewrite</category>
    </item>
    <item>
      <title>Mocking in TypeScript with `factoree`</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Tue, 02 Mar 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/mocking-in-typescript-with-factoree-ced</link>
      <guid>https://forem.com/schniz/mocking-in-typescript-with-factoree-ced</guid>
      <description>&lt;p&gt;A couple of days ago I had a fantastic experience. Two ambitious developers asked me to review an open source project they are working on in a short video chat. I was flattered and happily accepted the offer.&lt;/p&gt;

&lt;p&gt;We found ourselves talking about mocks in TypeScript. Since I started using TypeScript, I adopted a practice where I try to push as much as I can to the type system and use tools like &lt;a href="https://github.com/gcanti/io-ts"&gt;&lt;code&gt;io-ts&lt;/code&gt;&lt;/a&gt; to hook just enough runtime validations to ensure I can trust it.&lt;/p&gt;

&lt;p&gt;A couple of months ago I needed to mock something in one of our tests. We have a pretty big config, generated from a confirmation system, and I needed to use a property from it in my test.&lt;/p&gt;

&lt;p&gt;The first idea was to do something like &lt;code&gt;setAppConfig({ myKey: value } as any)&lt;/code&gt;. This worked well but it stinks from the &lt;code&gt;any&lt;/code&gt;, which also have a very big drawback: what if the test is implicitly using a property I did not set?&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://github.com/Schniz/factoree"&gt;&lt;code&gt;factoree&lt;/code&gt;&lt;/a&gt;. A simple factory generator function which will immediately throw an error when accessing a missing property. So, the previous example would be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;factory&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;factoree&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createAppConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;setAppConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createAppConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;myKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you see that we no longer have &lt;code&gt;as any&lt;/code&gt;? Instead of skipping the type system, we generate an object which will throw an error if we accessed a missing key. Instead of playing pretend — we specify rules for the computer to enforce at runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;factory&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;factoree&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createAppConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createAppConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;myKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 'hello'&lt;/span&gt;
&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;otherKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Error: Can't access key 'otherKey' in object { myKey: 'hello' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why does it matter?
&lt;/h2&gt;

&lt;p&gt;Imagine the following code under test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// more data&lt;/span&gt;
  &lt;span class="nl"&gt;website&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;printName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when we test it, we can use &lt;code&gt;as unknown as User&lt;/code&gt; to provide only the things that are in use in our function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`prints the name`&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Schlezinger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;printName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userDetails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the product manager asked us to add another feature: allow a user’s name to be written in reverse. So, our code changes into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;prefersReversedName&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="c1"&gt;// more data&lt;/span&gt;
  &lt;span class="nl"&gt;website&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;printName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prefersReversedName&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&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="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the code change, tests should still pass. This is a problem because we access a property (&lt;code&gt;prefersReversedName&lt;/code&gt;) which should be a non-null &lt;code&gt;boolean&lt;/code&gt;, but we don’t pass value into it, which is &lt;code&gt;undefined&lt;/code&gt;. This creates a blind spot in our test. When using factoree, this would not happen: if you forget to define a property, factoree will throw an error — ensuring you can trust your types.&lt;/p&gt;




&lt;p&gt;This tiny library helped us make more maintainable code with easier assertions and better tests. No more &lt;code&gt;undefined&lt;/code&gt; errors in tests if types have changed. Let the computer do the thinking for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Schniz/factoree"&gt;Try it&lt;/a&gt;, and let me know how that worked for you!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>HTML over the wire with Preact</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Sat, 30 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/html-over-the-wire-with-preact-1cj9</link>
      <guid>https://forem.com/schniz/html-over-the-wire-with-preact-1cj9</guid>
      <description>&lt;p&gt;I’m using Rails on a side project I’m playing with. Many of my peers would probably ask why would I do this to myself. The answer is simple: Rails helps me get stuff done quickly because it is super boring. It is so boring that it makes me excited.&lt;/p&gt;

&lt;p&gt;My app is split in two: a widget that every website can use — a JS bundle, and a back-office/API. For the back-office I mainly use Rails and the magnificent &lt;a href="https://github.com/alpinejs/alpine"&gt;Alpine.js&lt;/a&gt;. Authoring server-side rendered routes is so much easier to do with these two. Rails provides all the things I need in terms of back-end (even E-mailing comes built in!), and Alpine allows me to sprinkle JS as if my HTML was a React application: declarative, co-located JavaScript. For the widget, I use Preact. I originally started it as a React project, but I wanted to keep a minimal bundle size.&lt;/p&gt;

&lt;p&gt;I launched a new project, and I immediately installed &lt;a href="https://github.com/rmosolgo/graphql-ruby"&gt;&lt;code&gt;graphql-ruby&lt;/code&gt;&lt;/a&gt; as a GraphQL server implementation, to easily declare resources that can later be translated into type-safe data fetching from my widget. I mostly do TypeScript so it’s soothing me knowing that I can generate types and enforce them at runtime. I used &lt;a href="https://github.com/FormidableLabs/urql"&gt;&lt;code&gt;urql&lt;/code&gt;&lt;/a&gt; as a GraphQL client, because it looked like it would result in a smaller bundle (~4 times smaller than Apollo) and I wanted to experiment with it.&lt;/p&gt;

&lt;p&gt;By measuring the bundle size using tools like &lt;a href="https://chrisbateman.github.io/webpack-visualizer/"&gt;Webpack Visualizer&lt;/a&gt;, I found out that Urql bundles &lt;a href="https://github.com/graphql/graphql-js"&gt;&lt;code&gt;graphql.js&lt;/code&gt;&lt;/a&gt; to the client, and that’s something that I don’t really need — therefore, I do not want. Turned out, that Urql and its dependencies were more than 50% of my bundle size. I mean, this wasn’t very large and I was quite satisfied with Urql, but this is a &lt;em&gt;widget&lt;/em&gt;, not an entire application. The smaller - the better - and I want GraphQL for the amazing developer experience coming from the tight TypeScript integration, but that’s something I’m fine with sacrificing in favor of my production bundle size (or solve later). Therefore, I decided to drop GraphQL and migrate my data fetching to use simple REST endpoints, with &lt;a href="https://github.com/vercel/swr"&gt;&lt;code&gt;swr&lt;/code&gt;&lt;/a&gt; to hook up with Preact.&lt;/p&gt;

&lt;p&gt;As I started building a landing page, I wanted to make an animation to showcase the product — so I made one by myself with Tailwind CSS and Alpine. Eventually, I had a very clean animation with better looks than the current product. However, since my widget is a Preact app and my server is a Rails app, I couldn’t share the components between my backend and the widget.&lt;/p&gt;

&lt;p&gt;Or could I..?&lt;/p&gt;

&lt;p&gt;Most Preact and React apps use JSON to pass data between client and server. What if the server already knows how to render stuff? Well, instead of serving JSONs we can serve HTML — Exactly what &lt;a href="https://m.signalvnoise.com/html-over-the-wire/"&gt;DHH was preaching about lately&lt;/a&gt; when they introduced &lt;a href="https://hotwire.dev"&gt;Hotwire&lt;/a&gt;. So, instead of the following payload:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"abcd1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hey, friend!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Chandler Bing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"avatar_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://friends.com/chandler.jpg"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could return the following HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"message-abcd1234"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://friends.com/chandler.jpg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Hey, friend!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;— Chandler Bing&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; in Preact and React to show the message. Since I’m using Rails and &lt;em&gt;I know for sure&lt;/em&gt; that my HTML is sanitized, that’s not done dangerously at all. This way, I can keep my authorization and render specific layout for specific layouts and keep all his logic in my precious, well-tested back-end.&lt;/p&gt;

&lt;p&gt;The funny thing is, that it is not a new thing. The web did that before React was a thing! You don’t have to use JSON! But, since React and other SPA frameworks have taken the world by storm, I regularly meet people who don’t know about old-school frameworks like Rails and Django. And sometimes, the greatest solutions come from mixing modern and old solutions.&lt;/p&gt;

&lt;p&gt;Now, this path is not all gummy bears. If you’re into optimistic updates, that’s not the path for you — because it relies on the fact you want to keep as much of the business in your back-end. Rendering HTML is the cherry on top of everything.&lt;/p&gt;

&lt;p&gt;Personally, I think that most apps are either offline-centric or online-centric. Being somewhere in the middle is confusing. If you want to implement optimistic updates, you’re probably trying to do that by manually crafting an optimistic response. That can be very hard to maintain, and you can probably get better results if you architecture your app to work offline with tools like PouchDB.&lt;/p&gt;

&lt;p&gt;When working on my side-project, I don’t want to waste time on optimistic updates. If my server is down, I’d rather get an error. I want my project to be as simple as possible. It’s not a realtime chat application.&lt;/p&gt;

&lt;p&gt;It’s also harder to bind to event handlers, compared to Preact-rendered applications. How would you “rehydrate” the HTML coming from the server? How can you ensure the buttons whatever you need when they are being clicked? Consider the following HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"what_should_this_fn_be()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;what_should_this_fn_be()&lt;/code&gt; needs to be replaced with something in order for our button to be interactive. It can be inline JS, like the good ol’ days, but we won’t be able to bind it to functions in our bundle if we’re minifying them — or we would have to export them globally. Anyway, this ship has sailed. We need a better solution for event binding in our dynamic HTML sections:&lt;/p&gt;

&lt;h3&gt;
  
  
  Using event bubbling
&lt;/h3&gt;

&lt;p&gt;This is the “manual” or “explicit” way. It’s been in use for years.&lt;/p&gt;

&lt;p&gt;When adding &lt;code&gt;onClick={myFunction}&lt;/code&gt; in Preact and React, you will actually get events that bubbled from the children of the provided DOM node — not just events that happened on the specific DOM node. This is a great way to solve our issue — if you have dynamic HTML that can be clicked, you can lift the event handling to the container, which lives in Preact and renders the dynamic HTML. So instead of having just a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, you can add some hints like &lt;code&gt;&amp;lt;button data-action="doSomething"&amp;gt;&lt;/code&gt;, and reference this &lt;code&gt;data-action&lt;/code&gt; in your event handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;button data-action="showAnAlert"&amp;gt;click me&amp;lt;/button&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;showAnAlert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&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="s2"&gt;`Look at me, I'm doing something!`&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, the server can declaratively say what is the role of a button, and you can have the implementation in JS land.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using custom elements
&lt;/h3&gt;

&lt;p&gt;We can expose Preact elements as custom elements. So, instead of having the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;What should I do?&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use a custom component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-alert-button&amp;gt;&lt;/span&gt;Show an alert!&lt;span class="nt"&gt;&amp;lt;/my-alert-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would work kinda well with Preact, and can also be reused in our Rails backend. In fact, that’s what I do when rendering icons inside the Rails &lt;em&gt;and&lt;/em&gt; the widget app, &lt;a href="https://twitter.com/galstar/status/1354543473232375811"&gt;as I mentioned on this one tweet&lt;/a&gt;. That is somewhat a win, but when used heavily, it creates some issues.&lt;/p&gt;

&lt;p&gt;First, I will have to work with Shadow DOM and will go outside of Preact land just to go back using Preact using the custom element. So &lt;code&gt;Preact -&amp;gt; HTML -&amp;gt; Custom Element -&amp;gt; Preact&lt;/code&gt;. I can live with it but there is a better solution, that doesn’t have that massive accessibility issue:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; hurts accessibility
&lt;/h2&gt;

&lt;p&gt;The big issue for both the solutions mentioned before is the accessibility issue coming from &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;: when the HTML is replaced, the DOM elements will be &lt;em&gt;replaced&lt;/em&gt; by detaching them from the DOM and attaching new elements. That means that you lose focus and DOM state — So if you had &lt;code&gt;input&lt;/code&gt; fields or &lt;code&gt;details&lt;/code&gt; popovers, they will be reset.&lt;/p&gt;

&lt;p&gt;When using a library that does DOM diffing for you, doesn’t matter if it’s virtual or not, you want to use this diff. So in Preact, we would probably want to parse our HTML into Preact elements, so Preact will know how to diff them. In React, we would want to make them React elements. In Svelte, I’m pretty sure we wouldn’t have any way of doing so because all the diffing is compiled away — so we would need to use a library like &lt;code&gt;morphdom&lt;/code&gt; to do that.&lt;/p&gt;

&lt;p&gt;Let’s talk about Preact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;a href="https://github.com/developit/preact-markup"&gt;&lt;code&gt;preact-markup&lt;/code&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/developit/preact-markup"&gt;Preact Markup&lt;/a&gt; is a cool project that parses HTML to Preact elements, allowing you to render custom HTML elements using Preact components, without the real component boundary. It even lets you override standard HTML elements with your own components. Check out the following example, which has a &lt;code&gt;my-button&lt;/code&gt; element and overriding the standard &lt;code&gt;button&lt;/code&gt; one:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/preact-markup-demo-ijiw2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Preact Markup’s implementation is rather easy to understand. I suggest you to try building one yourself to fully grasp the ideas there. It can be translated to React very easily. Maybe that could be a future blog post, who knows?&lt;/p&gt;

&lt;h1&gt;
  
  
  Summing up
&lt;/h1&gt;

&lt;p&gt;Getting HTML back from the server and injecting that to our client-side apps is so nice. It works tremendously with SWR, and helped me building my side-project in a veeeeeery fast pace. The Server Components initiative by the React team is probably onto something — but you don’t need React to get the server magic. It’s all a question of trade-offs. If server-side rendering is mostly your jam, you could stick with it.&lt;/p&gt;

&lt;p&gt;Once you need a more complicated behaviors, you can always make a JSON response — and maybe you will find yourself embedding a server-generated HTML into it to sweeten the pill 😉&lt;/p&gt;

</description>
      <category>html</category>
      <category>javascript</category>
      <category>fetch</category>
      <category>data</category>
    </item>
    <item>
      <title>CLI Apps in TypeScript with `cmd-ts` (Part 1)</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Thu, 26 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/cli-apps-in-typescript-with-cmd-ts-part-1-2f0</link>
      <guid>https://forem.com/schniz/cli-apps-in-typescript-with-cmd-ts-part-1-2f0</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; — for a while now, I am using a custom module called &lt;a href="https://github.com/Schniz/cmd-ts"&gt;&lt;code&gt;cmd-ts&lt;/code&gt;&lt;/a&gt;, which is a type-first command line argument parser. Don’t know what it means? I’ll try to explain below! Anyway, give it a try, and let’s make it better together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WPRTbBPg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gal.hagever.com/static/227fcaae22e619bafa7b3e0c063590f3/c0255/nice-errors.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WPRTbBPg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gal.hagever.com/static/227fcaae22e619bafa7b3e0c063590f3/c0255/nice-errors.png" alt="cmd-ts provides the nicest UX and DX"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I write a lot of command line applications, both at work and for my own usage. Like many, my go-to toolkit for building them in Node.js was &lt;a href="https://npm.im/commander"&gt;&lt;code&gt;commander&lt;/code&gt;&lt;/a&gt; or similar packages. They’re great, but after using &lt;a href="https://docs.rs/structopt"&gt;&lt;code&gt;structopt&lt;/code&gt;&lt;/a&gt;, the struct-based derive macro for the &lt;a href="https://docs.rs/clap"&gt;&lt;code&gt;clap&lt;/code&gt;&lt;/a&gt; Rust crate, I felt something is missing.&lt;/p&gt;

&lt;p&gt;Let’s assume we’re building a powerful &lt;code&gt;cat&lt;/code&gt; clone. We want to read files, support reading from the standard input, and making HTTP calls. Check out the following code which implements it in a very simple fashion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use our &lt;code&gt;cat&lt;/code&gt; clone like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amazing! It can only read a file, and we need to add the rest of the features, but the code is very nice. but… this doesn’t scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We might want to have autogenerated &lt;code&gt;--help&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We might want to validate that we get a value in the file name&lt;/li&gt;
&lt;li&gt;We might want to add boolean &lt;code&gt;--flag&lt;/code&gt;s or &lt;code&gt;--option=value&lt;/code&gt; arguments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we need a nicer way to parse the command line arguments the user provides us.&lt;/p&gt;

&lt;p&gt;There are not a lot of big CLI apps that are using raw &lt;code&gt;process.argv&lt;/code&gt;. Most of them use &lt;code&gt;commander&lt;/code&gt; which is a high-level CLI parser, and some use &lt;code&gt;yargs&lt;/code&gt; or a similar package. If you’re familiar with Commander, you might find yourself writing something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Command&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;commander&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;path&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;path&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="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commander did satisfy our last requests, which is good:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can have an autogenerated &lt;code&gt;--help&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It validates that we get a value for &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It is very simple to add &lt;code&gt;--flag&lt;/code&gt;s or &lt;code&gt;--option=value&lt;/code&gt;s&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, it does not provide us any way of type safety. TypeScript obviously can’t identify what &lt;code&gt;path&lt;/code&gt; is. It is typed as &lt;code&gt;any&lt;/code&gt;. It is exactly the same as named &lt;code&gt;--option=value&lt;/code&gt; and boolean &lt;code&gt;--flag&lt;/code&gt;s. You’re in &lt;code&gt;any&lt;/code&gt; land. This is not something we want but Commander doesn’t let us declare types anywhere. Maybe with the template strings features of TS 4.1 the Commander team will write the description string parser in TypeScript and infer everything from the string.&lt;/p&gt;

&lt;p&gt;Commander does validate for presence of value in &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt;, and it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;missing&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="nx"&gt;argument&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, consider if you want to validate more stuff, and not just the presence of a value. What if you want to check if the provided path exists? What if we want different parsing/validation behavior, or in other words — &lt;em&gt;why do we treat all input as simple strings?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter &lt;a href="https://github.com/Schniz/cmd-ts"&gt;&lt;code&gt;cmd-ts&lt;/code&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Schniz/cmd-ts"&gt;&lt;code&gt;cmd-ts&lt;/code&gt;&lt;/a&gt; is a new command-line argument parser library that works kinda differently. It is influenced by Rust’s &lt;a href="http://docs.rs/structopt"&gt;&lt;code&gt;structopt&lt;/code&gt;&lt;/a&gt; and provides a “type-first” approach to command line argument parsing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything is type-safe&lt;/li&gt;
&lt;li&gt;Types are both in runtime and compile-time, for maximum confidence&lt;/li&gt;
&lt;li&gt;Parsing/validation are handled by the argument parser&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Extremely&lt;/em&gt; easy unit testing and code sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloning the previous example
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;cmd-ts&lt;/code&gt;’ syntax is very different from Commander’s. Instead of using a builder pattern, &lt;code&gt;cmd-ts&lt;/code&gt; favors building applications using simple function composition. This allows you to extract and share logic between applications, commands or modules — or even just to make your code shorter and more manageable. So, to replicate the exact behavior, which doesn’t show &lt;code&gt;cmd-ts&lt;/code&gt;’ superpowers, will be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;positional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;run&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;cmd-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;positional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&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 break it down:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cmd-ts.hagever.com/parsers/command.html"&gt;&lt;code&gt;command&lt;/code&gt;&lt;/a&gt; is a function that creates a command-line application. These applications can be later composed using the &lt;a href="https://cmd-ts.hagever.com/parsers/subcommands.html"&gt;&lt;code&gt;subcommands&lt;/code&gt;&lt;/a&gt; function. It expects a &lt;code&gt;name&lt;/code&gt; and an optional &lt;code&gt;version&lt;/code&gt; to be printed with &lt;code&gt;--help&lt;/code&gt; and &lt;code&gt;--version&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to declare arguments (like we do with &lt;code&gt;.arguments()&lt;/code&gt; in Commander), we provide the &lt;code&gt;args&lt;/code&gt; object to &lt;code&gt;command&lt;/code&gt;. Every key/value pair in &lt;code&gt;args&lt;/code&gt; is an argument definition. Arguments can be parsed in various ways, and one of them is &lt;a href="https://cmd-ts.hagever.com/parsers/positionals.html"&gt;&lt;code&gt;positional&lt;/code&gt;&lt;/a&gt;: taking a position-based argument from the user input.&lt;/p&gt;

&lt;p&gt;Each argument is parsed into a type. We provide the &lt;a href="https://cmd-ts.hagever.com/included_types.html#string"&gt;&lt;code&gt;string&lt;/code&gt;&lt;/a&gt; type (this is an object declared in &lt;code&gt;cmd-ts&lt;/code&gt;, not to be confused with TypeScript’s &lt;code&gt;string&lt;/code&gt; type). These types can be consumed via a 3rd party or be easily built for your custom validation/parsing needs. We’ll see an example in a bit.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;handler&lt;/code&gt; function receives all the arguments parsed by &lt;code&gt;args&lt;/code&gt;. The key/value pairs are statically typed into &lt;code&gt;handler&lt;/code&gt; - so you can destructure the value and be confident that you will get the type you expect. In our example, &lt;code&gt;path&lt;/code&gt; is not explicitly typed, so it uses the default one — &lt;code&gt;string&lt;/code&gt; — and if we provided a different type (like, &lt;a href="https://cmd-ts.hagever.com/included_types.html#number"&gt;&lt;code&gt;number&lt;/code&gt;&lt;/a&gt;), TypeScript could stop us from making mistakes in compile time.&lt;/p&gt;

&lt;p&gt;But again — this implementation doesn’t show the amazing capabilities you can have by using &lt;code&gt;cmd-ts&lt;/code&gt; types.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading an existing file
&lt;/h3&gt;

&lt;p&gt;Let’s try running our command, and try to print a non-existing file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ts-node cat.ts unknown-file
events.js:291
      throw er; // Unhandled 'error' event
      ^

Error: ENOENT: no such file or directory, open 'unknown-file'
Emitted 'error' event on ReadStream instance at:
    at internal/fs/streams.js:136:12
    at FSReqCallback.oncomplete (fs.js:156:23) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'unknown-file'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a nice error at all. It happens because &lt;code&gt;createReadStream&lt;/code&gt; creates a stream from a non-existing file, and when trying to read it we get an &lt;code&gt;error&lt;/code&gt; event which we didn’t handle. A common practice in Commander apps is to validate in your action, and therefore have a userland reporting mechanism.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cmd-ts&lt;/code&gt; pushes the validation and parsing into the “type”, which is a part of the parsing process. So, instead of using the default &lt;code&gt;string&lt;/code&gt; type, we can use another type. But which type should we use? &lt;code&gt;cmd-ts&lt;/code&gt; comes with optional &lt;a href="https://cmd-ts.hagever.com/batteries.html"&gt;“battery packs”&lt;/a&gt; you can use in your project. One of them is the &lt;a href="https://cmd-ts.hagever.com/batteries_file_system.html"&gt;file system pack&lt;/a&gt; which exports the &lt;code&gt;File&lt;/code&gt; type, which resolves into a path of an &lt;em&gt;existing&lt;/em&gt; file. Fails to parse if file doesn’t exist or the provided path is not a file.&lt;/p&gt;

&lt;p&gt;The change itself is very simple to do — adding the &lt;code&gt;File&lt;/code&gt; type to the positional argument definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;positional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;run&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;cmd-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;File&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;cmd-ts/dist/cjs/batteries/fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;positional&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing &lt;em&gt;really&lt;/em&gt; changed in our implementation detail (the &lt;code&gt;handler&lt;/code&gt; function) but we do declare that we expect a file. Check out the following error message for a non-existing file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;
&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;

  &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;
      &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nx"&gt;Path&lt;/span&gt; &lt;span class="nx"&gt;doesn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;t exist

hint: for more information, try &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A similar error would be if we try to pass a directory to our application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tmp&lt;/span&gt;
&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;

  &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tmp&lt;/span&gt;
      &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nx"&gt;Provided&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;

&lt;span class="nx"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;more&lt;/span&gt; &lt;span class="nx"&gt;information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cat --help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Roll Your Own Validations
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;cmd-ts&lt;/code&gt; allows you to create custom types and validate user input yourself, abstracting it from the implementation. These types can be shared across different applications, modules and even internally in different commands. There is no reason the actual handling code should verify path existence, or that the user input is a valid URL, or that the user input matches a list of strings. It can all be baked into the parsing and provide great errors with context to whatever was wrong in their input.&lt;/p&gt;

&lt;p&gt;Check out the implementation of &lt;a href="https://github.com/Schniz/cmd-ts/blob/master/src/batteries/fs.ts"&gt;&lt;code&gt;the filesystem pack&lt;/code&gt;&lt;/a&gt; or the simple &lt;a href="https://github.com/Schniz/cmd-ts/blob/master/src/types.ts"&gt;&lt;code&gt;number type&lt;/code&gt;&lt;/a&gt; to see how easy is to implement it yourself.&lt;/p&gt;

&lt;p&gt;The next part will be a step-by-step guide to build a custom type, which will make our code look even nicer and show how it affects testing and ergonomics.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;cmd-ts&lt;/code&gt; has some more gems baked into it, so you should probably &lt;a href="https://cmd-ts.hagever.com"&gt;take a look at the docs&lt;/a&gt;. I personally don’t use any other command line argument parser, and it’s not only because my righteous bias — other team members at Wix are already using it to distribute great developer experience across the organization.&lt;/p&gt;

&lt;p&gt;So you should definitely check it out, and contact me if you have any questions or issues.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>cli</category>
      <category>node</category>
    </item>
    <item>
      <title>Using Long Paths in Windows and Rust</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Mon, 17 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/using-long-paths-in-windows-and-rust-37hb</link>
      <guid>https://forem.com/schniz/using-long-paths-in-windows-and-rust-37hb</guid>
      <description>&lt;p&gt;Lately, I’ve been working on a Rust clone of &lt;a href="//../fnm"&gt;fnm&lt;/a&gt;. I like Rust and it is a great way to learn the language. Thanks to the Rust cross-platform tooling, I got a simple proof-of-concept for Windows support quickly.&lt;/p&gt;

&lt;p&gt;The first thing I got to do was a &lt;code&gt;install_node_dist&lt;/code&gt; method, which takes a borrowed &lt;code&gt;Version&lt;/code&gt; struct and a path to install into. I wrote a simple test to install Node 12.0.0 and it seemed to work on Linux, MacOS and even Windows! I was excited, but since I don’t really use Windows and fnm works perfectly well for me, I dropped it (no pun intended.)&lt;/p&gt;




&lt;p&gt;Not so long ago I saw some tweets by &lt;a href="http://twitter.com/zkat__"&gt;@zkat__&lt;/a&gt; regarding &lt;a href="https://github.com/orogene/orogene"&gt;a new package manager for Node written in Rust&lt;/a&gt;. It made me want to play with Rust again and I decided to copy the entire fnm end-to-end test suite into the Rust project. The E2E test suite was written in Bash (with some exception for Zsh and Fish), but I migrated it to a Rust DSL so I will be able to test the same code on Bash, Zsh and Fish — “write once, run everywhere”. Maybe I’ll write more about it in later posts.&lt;/p&gt;

&lt;p&gt;When I started migrating the tests to PowerShell, I saw that there are some versions I fail to install, because of a “path too long” error. It was weird. But since I haven’t used Windows in years, I decided to install a dev Windows VM in order to make it work. After some debugging, it seemed that the deep directory structure of the Node modules that come with Node v8.11.3 were too deep for Windows to handle with its default configurations, and I had to make some changes.&lt;/p&gt;

&lt;p&gt;I didn’t really know how to fix it, but while traversing the web (and &lt;a href="https://twitter.com/zkat__/status/1283223785592680449"&gt;finding this tweet by @zkat__&lt;/a&gt;) I saw a similar solution in a couple of repos, including Orogene — and applying it solved my issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the Long Paths Issue
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A Windows executable can have &lt;a href="https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests"&gt;an embedded manifest&lt;/a&gt; that tells Windows how to handle the executable!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is what I was missing. By embedding the following manifest to our binary we are able to use long paths freely. Let’s say this is &lt;code&gt;fnm.manifest&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version='1.0' encoding='utf-8' standalone='yes'?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;assembly&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"urn:schemas-microsoft-com:asm.v1"&lt;/span&gt; &lt;span class="na"&gt;manifestVersion=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;application&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"urn:schemas-microsoft-com:asm.v3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;windowsSettings&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;longPathAware&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.microsoft.com/SMI/2016/WindowsSettings"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        true
      &lt;span class="nt"&gt;&amp;lt;/longPathAware&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/windowsSettings&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/assembly&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now need to create a &lt;a href="https://docs.microsoft.com/en-us/cpp/windows/resource-files-visual-studio?view=vs-2019"&gt;resource file&lt;/a&gt; (I don’t really know what it is) with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define RT_MANIFEST 24
1 RT_MANIFEST "fnm.manifest"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last piece of the puzzle is to embed it into our Rust program. To do that, we need to install the following crate: &lt;a href="https://docs.rs/embed-resource"&gt;&lt;code&gt;embed-resource&lt;/code&gt;&lt;/a&gt; and create a &lt;a href="https://doc.rust-lang.org/cargo/reference/build-scripts.html"&gt;Cargo build script&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;embed_resource&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fnm-manifest.rc"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should hopefully make your path issues disappear. But maybe in the future it will be embedded into every Rust program, who knows?&lt;/p&gt;




&lt;p&gt;Again, thanks again for the code I copied from &lt;a href="https://github.com/orogene/orogene"&gt;Orogene&lt;/a&gt;. Speedy CLIs for Node development are making me excited: there’s no reason we have slow tools!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>windows</category>
      <category>fnm</category>
    </item>
    <item>
      <title>Preserving Form State in Refreshes and Navigation with React</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Tue, 07 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/preserving-form-state-in-refreshes-and-navigation-with-react-257j</link>
      <guid>https://forem.com/schniz/preserving-form-state-in-refreshes-and-navigation-with-react-257j</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; You probably witnessed it as well. You fill a form, you navigate somewhere else and then go back to realize all the form was cleared away. Maybe it was a search form or even a registration one. This shouldn’t be the case: you can write a simple hook to preserve state in the browser history. &lt;a href="https://55hye.csb.app/"&gt;Try it live here&lt;/a&gt;. Also, &lt;a href="https://codesandbox.io/s/usehistorystate-55hye"&gt;the code is live on CodeSandbox&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;These aren’t easy times. Ever since the COVID-19 pandemic stroke, I’ve been locked up to my apartment. Mainly working remotely and playing Overcooked 2 with my fiancée. Last week I had the chance to volunteer in a non-profit project, where I was writing some front-end code (forms!) in React. I haven’t written actual front-end code for a while, which was a fresh breeze.&lt;/p&gt;

&lt;p&gt;The form itself was split to 3 pages, or “stages”, to make filling it easier:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--21u4Owpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gal.hagever.com/static/782eb8e7577bf61064711857636e42d8/c0255/steps_excalidraw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--21u4Owpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gal.hagever.com/static/782eb8e7577bf61064711857636e42d8/c0255/steps_excalidraw.png" alt="The form was split to 3 different stages" title="The form was split to 3 different stages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started by coding every stage on its own. Adding navigation later should be easy and not a problem, thanks to &lt;a href="https://github.com/reacttraining/react-router"&gt;React Router&lt;/a&gt; v5. This made my coding experience REALLY fast. When I got to navigation, using RRv5 was kinda easy. I decided to use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/History/state"&gt;browser history state&lt;/a&gt; to pass the page results between pages. The browser history state is a way of passing data or storing data in the history stack itself, instead of adding a new global state to the app. So navigating looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useHistory&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-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useHistory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
      &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;onClick&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/next-page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;firstSectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;THE_VALUE_I_WANT_TO_PASS&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;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Next&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does it work? Well, if you long-press the “back” button on your browser, you’d probably see your history for this specific tab. Using &lt;code&gt;window.history.back()&lt;/code&gt; is a handy way to go back programmatically, but it’s not the entire API that the browser gives us. It also gives us the power to manipulate the history stack with pushing a new item and replacing the current item. Each item on the history has a path name and state that you can manage. Most project I witnessed don’t use the history state at all, despite it being a super powerful tool!&lt;/p&gt;

&lt;p&gt;I also provided a hook to read the value off the history state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useHistory&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-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useFirstSectionResult&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;FirstSectionResult&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useHistory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;firstSectionResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I could use the history state in the next page just by calling this hook. If I got &lt;code&gt;undefined&lt;/code&gt;, I could redirect the users back to the first section so they will complete it. I saw that this idea works, and I was excited to try pressing the browser’s “back” button to immediately press “next” to see that the state management actually works.&lt;/p&gt;

&lt;p&gt;So I hit the “back button”. The form that I just filled is empty. When I clicked “next” the second stage of the form worked as expected, but I was very annoyed by the fact that all the fields I filled is now completely empty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the State Preservation Problem
&lt;/h2&gt;

&lt;p&gt;This is a problem we have in modern front-end apps which we hadn’t when we were doing forms generated by some backend (like Rails or ASP) because the browsers do try to remember the values we filled in the forms! Because all the routing and rendering happens on the client side, way after the browser “rehydrates” its inputs, we lose all the state of the form.&lt;/p&gt;

&lt;p&gt;This is clearly unacceptable because it’s the worst user experience there is. I discussed with the people who volunteered with me regarding the issue and consulted Google. Seems like like most solutions are using &lt;code&gt;localStorage&lt;/code&gt;, &lt;code&gt;sessionStorage&lt;/code&gt; and &lt;code&gt;indexedDB&lt;/code&gt;. I decided to go with &lt;code&gt;sessionStorage&lt;/code&gt; because both &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;indexedDB&lt;/code&gt; sounded like a long-time cache and a session-long cache sounds appealing to me.&lt;/p&gt;

&lt;p&gt;I decided to go and make a custom hook (&lt;code&gt;useSessionState&lt;/code&gt;) that worked like &lt;code&gt;useState&lt;/code&gt;, only read the initial value from &lt;code&gt;sessionStorage&lt;/code&gt;, and wrote all changes to &lt;code&gt;sessionStorage&lt;/code&gt; as well. Then, I made all form elements controlled by specifying &lt;code&gt;onChange&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thinking about the solution again, I didn’t think it is good enough. The main problem I have with it, is that &lt;code&gt;sessionStorage&lt;/code&gt; is &lt;em&gt;consistent&lt;/em&gt; across different browser tabs/windows. &lt;em&gt;It is basically a global cache.&lt;/em&gt; That means that you can’t use the form in more than one tab(!). Not exactly what you expect from a web browser. Imagine you open multiple tabs and fill forms just to realize they override each other silently. Absurd!&lt;/p&gt;

&lt;p&gt;This would also happen in &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;indexedDB&lt;/code&gt; because they too work like a global cache. So how can I still make the form work across different tabs while supporting refreshes and navigations?&lt;/p&gt;

&lt;h3&gt;
  
  
  Altering the History State
&lt;/h3&gt;

&lt;p&gt;Remember the browser history state we have just used to provide state when navigating to a new page? We did it by calling the History &lt;code&gt;push&lt;/code&gt; function. What if we could change the current page’s navigation state? Apparently, this is possible using the &lt;code&gt;replace&lt;/code&gt; function, which &lt;em&gt;replaces&lt;/em&gt; the current item in the history stack instead of pushing a new one (which is the normal behavior of navigation). We can avoid altering the &lt;code&gt;pathname&lt;/code&gt; (or URL) part, and only alter the state, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;SOME_ITEM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SOME_VALUE&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be wrapped in a hook, to make it look and feel like the &lt;code&gt;useState&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useHistory&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-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useHistoryState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useHistory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rawState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rawSetState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;rawSetState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rawState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we don’t have any plain &lt;code&gt;useState&lt;/code&gt; in our form, every form input (and even complex JSON objects) will be preserved across refreshes and page navigations without further thinking. This solution isn’t just for people who use React Router. The attached CodeSandbox has a native implementation you can use anywhere. Make sure to open the preview in a new window because CodeSandbox’s preview pane does not preserve history state.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/usehistorystate-55hye"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You see, making forms didn’t use to be hard. Making them work like they did while using modern front-end frameworks shouldn’t be either. Implementing this simple &lt;code&gt;setHistoryState&lt;/code&gt; makes us stop thinking about how to manage forms’ state and lets us just write forms with a great experience. All thanks to the History API, which doesn’t only allow us to do magnificent client-side routing, it also helps us preserve meaningful state for our pages. 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pcYIXeiO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://gal.hagever.com/2eb5d33581d74419e317374370c12955/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pcYIXeiO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://gal.hagever.com/2eb5d33581d74419e317374370c12955/demo.gif" alt="A demo of using the browser history to preserve state"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stringly and Strongly typed TypeScript</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Tue, 26 Nov 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/schniz/stringly-and-strongly-typed-typescript-2a5k</link>
      <guid>https://forem.com/schniz/stringly-and-strongly-typed-typescript-2a5k</guid>
      <description>&lt;p&gt;There’s a rational fear coming from JavaScript to TypeScript. The thought of having to mess with static types instead of focusing on runtime code sounds annoying. For coders who know static typings from languages with inferior type systems, like Java, or languages with awesome, yet different type systems, like Reason, OCaml, Rust and Swift (which are all examples to the &lt;a href="https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system"&gt;Hindley–Milner type system&lt;/a&gt;), static typings might sound very off from the standard way of JavaScript-ing.&lt;/p&gt;

&lt;p&gt;In turns out, that TypeScript can express very complicated types, thanks to its conditional types, literals and generics. In this short post we’re going to explore how to use typed string literals to have a safe interfaces to objects. This approach is the underlying mechanism of wrapping libraries like &lt;a href="https://github.com/lodash/lodash"&gt;&lt;code&gt;lodash&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://github.com/ramda/ramda"&gt;&lt;code&gt;ramda&lt;/code&gt;&lt;/a&gt; and my recent &lt;a href="https://github.com/Schniz/soundtype-commander"&gt;&lt;code&gt;@soundtype/commander&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/Schniz/soundtype-eventemitter"&gt;&lt;code&gt;@soundtype/eventemitter&lt;/code&gt;&lt;/a&gt;, all in a type safe manner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stringly-typed
&lt;/h2&gt;

&lt;p&gt;Consider the following JavaScript 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="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage:&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Schlezinger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&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;The &lt;code&gt;prop&lt;/code&gt; function above looks like something we can’t type in a static type system. It takes an object, and then a string, which is the property name, and returns an object. A naive implementation in TypeScript would be probably something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is, of course, a very unsafe function. How can we make it better? Let’s look at a simpler function, and try to type it first. We’ll talk about the &lt;code&gt;identity&lt;/code&gt; function, that gets an object and returns the same object. Or in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&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;Such a simple function! How would we write it in TypeScript? The naive approach, again, would look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&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;But now, once we use &lt;code&gt;identity(10)&lt;/code&gt;, we get the &lt;code&gt;any&lt;/code&gt; type back. This is not what we want. To ensure we get the same type as we provided, we need to make the function &lt;em&gt;generic&lt;/em&gt;. Now, whenever we call the &lt;code&gt;identity&lt;/code&gt; function, TypeScript will also provide the type of the argument, whether by inference or explicitly by usage. This is how it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// by inference&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inferred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;

&lt;span class="c1"&gt;// explicitly&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;explicit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in conclusion, generics can help us leverage the underlying types whenever for type safety.&lt;/p&gt;

&lt;p&gt;How do we use generics in a function like &lt;code&gt;prop&lt;/code&gt;? Let’s start by adding a generic to the object we want to take data from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This won't compile in strict mode!&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implementation won’t compile, because we can’t index an unknown object (just a generic &lt;code&gt;T&lt;/code&gt;) over a string. Maybe that’s an array? Also, we don’t know what the result type might be, so this is not good enough. A good utility TypeScript provides us is the way to ask the type of the keys of an object. This is done by using &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types"&gt;&lt;code&gt;keyof Type&lt;/code&gt;&lt;/a&gt;, so &lt;code&gt;keyof { hello: number, world: string }&lt;/code&gt; would result in the &lt;code&gt;'hello' | 'world'&lt;/code&gt; type, which is a union of 2 string literals.&lt;/p&gt;

&lt;p&gt;We can leverage this by using it instead of asking for a &lt;code&gt;string&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, our function compiles, but we still don’t know what type we will get in return, and as we said before, returning an &lt;code&gt;any&lt;/code&gt; is not acceptable.&lt;/p&gt;

&lt;p&gt;The cool trick we can do, is to add &lt;em&gt;another&lt;/em&gt; generic, that will extend the &lt;code&gt;keyof T&lt;/code&gt;, let’s call it &lt;code&gt;Key&lt;/code&gt;. Then, we can access the return type by returning &lt;code&gt;T[Key]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Key&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the function is truly generic, and will work as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;year&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;missing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// compilation error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assures us we won’t have any runtime &lt;code&gt;undefined&lt;/code&gt;s, by letting our compiler be smarter and look for mistakes we might do. This tiny example can be used all over the place to provide great developer experience for library users.&lt;/p&gt;

&lt;p&gt;The TypeScript type system also allows recursive types, conditional types and much more awesome shenanigans, we might explore in the future.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>guide</category>
    </item>
    <item>
      <title>fnm: Fast and Simple Node.js Version Manager</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Tue, 12 Feb 2019 16:50:47 +0000</pubDate>
      <link>https://forem.com/schniz/fnm-fast-and-simple-node-js-version-manager-189j</link>
      <guid>https://forem.com/schniz/fnm-fast-and-simple-node-js-version-manager-189j</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;fnm&lt;/a&gt; is a very fast Node.js version manager, ~40x faster than NVM. It supports &lt;code&gt;.nvmrc&lt;/code&gt; files and &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;Fish shell&lt;/a&gt; out of the box. It works on Linux and Mac and distributed as a single executable - and it is &lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;open source on GitHub&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  So,
&lt;/h3&gt;

&lt;p&gt;Two weeks ago, I had opened a new tab on my terminal and complained in agony: “Oh dear god! Every time I open a new terminal it takes like &lt;em&gt;one second!&lt;/em&gt;”. My teammates looked at me funny. “This is clearly sub-optimal and hurts my focus, and I believe it’s NVM’s fault.”&lt;/p&gt;

&lt;p&gt;I found it’s NVM that is at fault after I did a search around my &lt;code&gt;.zshrc&lt;/code&gt; file, checking which line takes the most time. It was NVM’s initialization. I have been using NVM for years, and I always wanted to write a simple replacement, because my use cases are pretty simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to be able to download any Node version (like &lt;code&gt;nvm install&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;I want to be able to switch between them easily (like &lt;code&gt;nvm use&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tasks aren’t hard to solve. Node.js binaries are distributed in tarballs on their website, and switching versions shouldn’t be more than just changing a symbolic link around. So, why is NVM so slow?&lt;/p&gt;

&lt;p&gt;I thought about writing it as a simple Bash script, just like NVM, but I wanted it to be interesting and fun. Also, not all machines have Bash installed, or there might be problems integrating with Bash. I have used &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;Fish shell&lt;/a&gt; for years, and in order to use NVM, I had to use a wrapper that fixes things. It wasn’t easy. Using a real executable, on the other hand, would work on every shell!&lt;/p&gt;

&lt;h3&gt;
  
  
  The first prototype
&lt;/h3&gt;

&lt;p&gt;My first prototype was a TypeScript app. I packaged it with &lt;a href="https://github.com/zeit/pkg" rel="noopener noreferrer"&gt;Zeit’s pkg&lt;/a&gt;, making it a self-contained executable, because I didn’t want to have dependency on Node. I wanted it to work on a system without Node installed (so the first version of Node would be installed using fnm!)&lt;/p&gt;

&lt;p&gt;Node’s startup time wasn’t good enough for me. Just spawning a “hello world” takes around 200ms, which is good for servers, and for command line utilities that you don’t use frequently, maybe, but some people use &lt;code&gt;nvm&lt;/code&gt; on every cd, so their Node version will always be in sync. 200ms penalty for every &lt;code&gt;cd&lt;/code&gt; is madness and would make the tool unusable.&lt;/p&gt;

&lt;p&gt;So it seems like I need to write it in a language that is compiled (so no dependencies on the host system), and with fast boot time. Four languages came to mind: Go, Rust, Crystal and Reason/OCaml.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Native Reason App
&lt;/h3&gt;

&lt;p&gt;I chose Reason for many Reasons (hehe), &lt;a href="https://dev.to/schniz/the-programming-language-im-looking-for-4olb-temp-slug-7649698"&gt;some of them are written in another post&lt;/a&gt;. I had used &lt;a href="https://esy.sh/" rel="noopener noreferrer"&gt;&lt;code&gt;esy&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/jordwalke/pesy" rel="noopener noreferrer"&gt;&lt;code&gt;pesy&lt;/code&gt;&lt;/a&gt;, two awesome packages that make the development workflow for native Reason/OCaml apps easy-peasy for Node.js developers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;esy&lt;/code&gt; works like a super-powered &lt;a href="https://yarnpkg.com/" rel="noopener noreferrer"&gt;&lt;code&gt;yarn&lt;/code&gt;&lt;/a&gt;: it installs packages from npm or OPAM (OCaml package manager) and &lt;a href="https://esy.sh/docs/en/how-it-works.html" rel="noopener noreferrer"&gt;stores it in a global cache&lt;/a&gt;. It also manages a sandbox for the OCaml runtime/dependencies for you, so different OCaml installations won’t interrupt each other. &lt;code&gt;pesy&lt;/code&gt; generates build configurations for &lt;a href="https://dune.build/" rel="noopener noreferrer"&gt;Dune&lt;/a&gt;, OCaml’s build tool, right from the &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;When using both packages, it feels just like Node development — everything works with a single &lt;code&gt;package.json&lt;/code&gt; file, with minimum configurations. It can also help other Node devs, just like it helped me, to contribute to the project, because Reason syntax is very close to JS’, and the toolchain feels &lt;em&gt;very&lt;/em&gt; JavaScript-ish.&lt;/p&gt;

&lt;p&gt;I had built the first prototype, and tested its performance. I had two test files, one using NVM and one using fnm. Both tests spawned a plain Bash, called the “initialization” of the target (NVM/fnm), and then switched to the Node version specified in &lt;code&gt;.nvmrc&lt;/code&gt; file in the directory using the target. I ran it 10 times for each binary, and the results were amazing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NVM’s test case was around 600ms on my machine&lt;/li&gt;
&lt;li&gt;fnm’s test case was around 15ms on my machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in that test, on my MacBook Pro, &lt;strong&gt;fnm was 40 times faster than NVM&lt;/strong&gt;. That’s pretty huge, despite not being very scientific.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgh5u19u7ioja1swcmtr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgh5u19u7ioja1swcmtr2.png" alt="How it looks"&gt;&lt;/a&gt;&lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;A real-time animated video is on the repo’s README&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Releasing to Public
&lt;/h3&gt;

&lt;p&gt;When I had started working on fnm, I joined the Reason Discord server, and asked some help from people. I found that community is &lt;em&gt;so nice&lt;/em&gt;. When I decided to release, I wrote a short message on the &lt;code&gt;#native-development&lt;/code&gt; channel and immediately got great feedback, telling me it’s a great idea.&lt;/p&gt;

&lt;p&gt;The community aspect is such an important part of JavaScript, and Reason’s community feels even nicer than JS’ — maybe because the community is still small, but it is &lt;em&gt;very&lt;/em&gt; welcoming.&lt;/p&gt;

&lt;p&gt;I released fnm to GitHub as open source, tweeted about it and went to bed. When I woke up,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My twitter notifications were on fire 🔥&lt;/li&gt;
&lt;li&gt;The repo had more than 500 stars 💯💯💯💯💯&lt;/li&gt;
&lt;li&gt;fnm was #1 on HackerNews 🏆&lt;/li&gt;
&lt;li&gt;No one on Reddit/HackerNews called me an idiot! 🤡 (a rare sight)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s a big deal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F93js376evh59lopebjnr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F93js376evh59lopebjnr.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Now?
&lt;/h3&gt;

&lt;p&gt;fnm has some features still missing. Here are only a few things we want to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows support&lt;/li&gt;
&lt;li&gt;Version aliases&lt;/li&gt;
&lt;li&gt;Support downloading latest LTS&lt;/li&gt;
&lt;li&gt;Per-shell usage&lt;/li&gt;
&lt;li&gt;Drop dependency on &lt;code&gt;tar&lt;/code&gt; and &lt;code&gt;curl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;… and more!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you feel like you’re ready to use it and start working faster, or you’re a JS/Reason developer willing to contribute to an open source project, &lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;download fnm and join us on GitHub&lt;/a&gt;!&lt;/p&gt;




</description>
      <category>commandline</category>
      <category>reason</category>
      <category>javascript</category>
      <category>ocaml</category>
    </item>
    <item>
      <title>Fun with Functors and ReasonML</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Sat, 24 Mar 2018 20:57:20 +0000</pubDate>
      <link>https://forem.com/schniz/fun-with-functors-and-reasonml-iim</link>
      <guid>https://forem.com/schniz/fun-with-functors-and-reasonml-iim</guid>
      <description>

&lt;blockquote&gt;
&lt;p&gt;Or: Reasonable functional programming with Reason, part 1:&lt;br&gt;
A short introduction to ReasonML types and functor types from a beginner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started to learn some functional patterns after reading &lt;a href="https://medium.com/u/a3129fead82b"&gt;Brian Lonsdorf&lt;/a&gt;’s amazing book &lt;a href="https://github.com/MostlyAdequate/mostly-adequate-guide"&gt;“Mostly Adequate Guide to Functional Programming in JavaScript”&lt;/a&gt;. This book made me crazy about this new paradigm, that I never learned, and made me want to practice these patterns somewhere.&lt;/p&gt;

&lt;p&gt;I found myself using it in my fun projects but never in my real-work projects — it always fell in the “most javascript programmers don’t code like this” territory. My colleagues were right, so I decided to learn a different language. Originally, it was Haskell. I started to learn it, but it was too theoretical (or “academic”) for me: I’m a very practical guy, and I like to be able to use and build software with the paradigms and languages I learn first.&lt;/p&gt;

&lt;p&gt;So… for the last couple of days, I’ve been learning &lt;a href="https://reasonml.github.io/"&gt;Reason&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Reason?
&lt;/h3&gt;

&lt;p&gt;Reason, or ReasonML, is a new syntax of OCaml. It looks more like JavaScript so it is easier to get started with. And the OCaml part doesn’t need to tell you much, other than that you have a big community behind you, in a language that is here for years. OCaml has opam as their package management tool, and the community is active. Check out &lt;a href="https://github.com/rizo/awesome-ocaml"&gt;awesome-ocaml&lt;/a&gt; to see some cool stuff from the OCaml community.&lt;/p&gt;

&lt;p&gt;What does “a new syntax” mean? Having a new syntax for OCaml is like using CoffeeScript or transpiling newer JS syntax to older JS syntax using Babel — writing in one syntax, then compiling it to another syntax. Reason “compiles” to OCaml, and along with BuckleScript, a tool that compiles OCaml to very efficient JavaScript, you can see the chain: Reason ➡ OCaml ➡ JavaScript.&lt;/p&gt;

&lt;p&gt;Both OCaml and Reason have a full sound (and inferred) type system, so 100% of your code is covered with types on compile time. That means fewer bugs. The inference part is amazing too; it means that you don’t have to write the types yourself. The compiler understands your code and does that for you.&lt;/p&gt;

&lt;p&gt;For developers coming with Java-like type systems, to type systems like Reason has — note that in Reason, nulls aren’t a thing. You can’t send null as an argument for a function which wants to get a string. It’s just not possible. &lt;em&gt;It’s not that the whole concept of absence isn’t baked into Reason&lt;/em&gt;, it is just that you have a special way of doing so. That way is called &lt;code&gt;option&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;option&lt;/code&gt; type
&lt;/h3&gt;

&lt;p&gt;In Reason, you can declare types as constructors. Constructors &lt;em&gt;can&lt;/em&gt; have data in them, but it is not mandatory. Let’s take the &lt;code&gt;option&lt;/code&gt; type, for instance, its declaration looks like the following:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Woohoo, there’s a lot going on here for first comers. Let’s go over this definition together.&lt;/p&gt;

&lt;p&gt;First, we declare a &lt;code&gt;type&lt;/code&gt;, called &lt;code&gt;option&lt;/code&gt;. Then, there are the &lt;em&gt;type parameters&lt;/em&gt;: that &lt;code&gt;'a&lt;/code&gt; thing is called “type parameter” — it is used like Generics or Templates in languages like Java, C++, etc. This is so option can “wrap” many different types: you can have &lt;code&gt;option(int)&lt;/code&gt; if you have a nullable integer, or &lt;code&gt;option(string)&lt;/code&gt; if you have a nullable string! Type parameters are always prefixed with a tick (&lt;code&gt;'&lt;/code&gt;), so you can’t unsee it in examples. You can have more than one type parameter — more on that later.&lt;/p&gt;

&lt;p&gt;Then, we say that our type is a union of 2 constructors: &lt;code&gt;None&lt;/code&gt;, which receives nothing as data, and &lt;code&gt;Some&lt;/code&gt;, which receives data with the type &lt;code&gt;'a&lt;/code&gt;, as the type parameter says.&lt;/p&gt;

&lt;p&gt;The built-in &lt;code&gt;option&lt;/code&gt; type is the way we handle absence in Reason. In Haskell, it is called &lt;code&gt;Maybe&lt;/code&gt;. We always know that we receive an &lt;code&gt;option&lt;/code&gt; type, and when we have an &lt;code&gt;option&lt;/code&gt; type, we always have to unpack it before we use it. We unpack data with a cool feature called &lt;a href="https://reasonml.github.io/docs/en/pattern-matching.html"&gt;pattern matching&lt;/a&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optionalName&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="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;optionalName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&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="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="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Who are you?"&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;print_endline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Gal"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="n"&gt;prints&lt;/span&gt; &lt;span class="s2"&gt;"Hello, Gal"&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt; &lt;span class="n"&gt;print_endline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="n"&gt;prints&lt;/span&gt; &lt;span class="s2"&gt;"Who are you?"&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;See how I unpack the data with ease. When I get &lt;code&gt;None&lt;/code&gt;, I return a string that contains &lt;code&gt;Who are you?&lt;/code&gt;. When I get &lt;code&gt;Some&lt;/code&gt; with some name in it, I return &lt;code&gt;Hello, ${name}&lt;/code&gt;. It may look weird that it actually works like that, but it does! (&lt;a href="https://reasonml.github.io/en/try.html?reason=DYUwLgBA5gTi4QLwQBQHsAOYCWaB2AhsAHIEC2IAXBJjvigM5gzZ5QCU7E1TLbSAPgBQECAwDu2MAGMAFqlq5CJciC4BvERAA+EAMpoKKQhS6IBEAEQAJEMGBoANFYgBqVxBMgtu4vhCCVgDqsmgQBHAQAJ5oAK4A-JZaAL4A3EJCGHxgAPogeAAmwKwgKLDwYCgGRpYA4kSWnOypEAD0AFQQWaxgDFa29k4Q9cCWEO2tmdl5hcV4peXgKH7znC0dXdl9liFhEQExCWMTQA"&gt;you can click here to see what it compiles to in the Reason Try page&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Okay okay… an optional type. What is a functor?
&lt;/h3&gt;

&lt;p&gt;Now that we know what is the &lt;code&gt;option&lt;/code&gt; type, we can continue from here and use it as our example for the rest of the article.&lt;/p&gt;

&lt;p&gt;A functor is a data type that can be &lt;em&gt;mapped&lt;/em&gt;. That means that you can call the &lt;code&gt;map&lt;/code&gt; function on it. The &lt;code&gt;map&lt;/code&gt; function takes a functor and a function. Then, applies the provided function to the functor’s value (unwraps it), and wraps the result with an instance of the functor again.&lt;/p&gt;

&lt;p&gt;You may already be familiar with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;Array#map from ES5&lt;/a&gt;: array.map(fn). This is because &lt;em&gt;Array is a functor&lt;/em&gt; that has multiple values in it. The provided function is evaluated with every value in the array, and in return, you get a new Array! By the way, in Reason, you don’t call methods on a value — that’s OOP. The way of invoking methods is to invoke a function and pass the value to it:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&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="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The option type, Just like Array, is a functor too. To understand how it would work let’s split it into its two constructors: Some and None.&lt;/p&gt;

&lt;p&gt;What would happen if we map over &lt;code&gt;None&lt;/code&gt;? I’d suggest that it should have the same behavior as mapping over an empty array: it should do nothing, it shouldn’t execute the provided function at all — it should just return &lt;code&gt;None&lt;/code&gt;. For &lt;code&gt;Some&lt;/code&gt;, I’d suggest that it should have the same behavior as mapping over an array with a single value. So the single value will be applied to the function, then be packed again with &lt;code&gt;Some&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Implementing this map function is just a couple lines of code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapOption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&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;Reason’s amazing type system ensures that &lt;code&gt;fn&lt;/code&gt; is a function that receives the provided option value, and returns a new option. The full type declaration for mapOption is:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapOption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opt&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="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&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="p"&gt;)&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="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&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 go over it together: we first declare a function called &lt;code&gt;mapOption&lt;/code&gt; that receives an argument called &lt;code&gt;opt&lt;/code&gt;, with the type of &lt;code&gt;option('a)&lt;/code&gt;. As we already talked about, &lt;code&gt;'a&lt;/code&gt; is a type parameter, making this function get &lt;em&gt;any type of &lt;code&gt;option&lt;/code&gt;.&lt;/em&gt; then, we receive a function that receives &lt;code&gt;'a&lt;/code&gt; (the type parameter we had in the opt argument), and returns &lt;code&gt;'b&lt;/code&gt;, which is or isn’t a different type. Then, the function returns &lt;code&gt;option('b)&lt;/code&gt;, which is the same type as the inner function result type but wrapped in an &lt;code&gt;option&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In other words, we receive an &lt;code&gt;option('a)&lt;/code&gt;, then we receive a function that transforms a value from type &lt;code&gt;'a&lt;/code&gt; to &lt;code&gt;'b&lt;/code&gt;, and then we return &lt;code&gt;option('b)&lt;/code&gt;: we support transforming between the inner types, while we’re still in &lt;code&gt;option&lt;/code&gt; land:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;stringify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;string_of_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&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;=&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="n"&gt;mapOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="n"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;mapOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  More functor examples
&lt;/h3&gt;

&lt;p&gt;We can declare another type — the &lt;code&gt;result&lt;/code&gt; functor. The result functor will be almost like &lt;code&gt;option&lt;/code&gt;, but its negative side will have a value too. You can treat its value as a &lt;code&gt;reason&lt;/code&gt;, or &lt;code&gt;error&lt;/code&gt;, or just &lt;code&gt;failure&lt;/code&gt;. When you return the &lt;code&gt;result&lt;/code&gt; functor, you’re basically saying that “this method may fail”. You can use result in validations and for database queries, or for anything whose error is important:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The map behavior is almost identical to the &lt;code&gt;optionMap&lt;/code&gt; behavior. If we have &lt;code&gt;Success&lt;/code&gt;, we will take its data and apply it to the provided function. If we have a &lt;code&gt;Failure&lt;/code&gt;, we wouldn’t apply the value to the function, and just leave that &lt;code&gt;Failure&lt;/code&gt; as it is. The implementation, again, is a couple lines of code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&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;Failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&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;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This data structure helps us build our program as a tree. When we have a problem, we stop applying our logic to it. We basically stop going through the “happy path” until we handle the failure. &lt;em&gt;When we map over &lt;code&gt;Failure&lt;/code&gt;, we stay with the same failure we had, so no data transformation will happen once we have a &lt;code&gt;Failure&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the next article, I’m going to write about Monads, a special case of Functors, that can help you a lot while building data transformations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Up until then, what are your ideas of custom functors?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;





</description>
      <category>functional</category>
      <category>reason</category>
      <category>functors</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>“Sign up” and “Sign in” forms could (and should) be the same</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Fri, 05 May 2017 15:35:38 +0000</pubDate>
      <link>https://forem.com/schniz/sign-up-and-sign-in-forms-could-and-should-be-the-same</link>
      <guid>https://forem.com/schniz/sign-up-and-sign-in-forms-could-and-should-be-the-same</guid>
      <description>

&lt;h4&gt;
  
  
  After reading &lt;a href="http://inspr.co/2017/05/03/login-vs-signup/"&gt;Omri Lachman's article&lt;/a&gt; about hidden “log in” buttons. Suddenly, I understood my frustration with recent web apps. I DONT KNOW HOW TO USE THEM BECAUSE THEY WANT ME TO SIGN UP ALL THE TIME.
&lt;/h4&gt;

&lt;p&gt;I am clearly not a UX designer, but I had an idea: instead of having two forms: one for logging in and one for signing upâ€Š–â€Šwhy can’t we have both on the same form?&lt;/p&gt;

&lt;p&gt;Think about it. You can try logging in if you fail to log in because of a password you can retryâ€Š–â€Šbut if you fail because of the email provided? Why can’t you just resume to the registration process?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://signme.surge.sh"&gt;I built a simple mockup&lt;/a&gt; (&lt;a href="https://github.com/Schniz/signbox"&gt;source code is on GitHub&lt;/a&gt;) to show how a simple registration/logging in the process could work in practice: once you provide an email of an actual userâ€Š–â€Šit suggests that you need to sign in. Yes, it has some security vulnerabilities that we probably can solve or can actually care about. We can do that it won’t be automatically: once I clicked the “Continue” button, it will try to log in and if it fails due to unknown emailâ€Š–â€Šwe’ll ask to complete some details to sign up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Im_XEkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Af_VLGyD2fvGJ9gRcrOyo9g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Im_XEkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Af_VLGyD2fvGJ9gRcrOyo9g.gif" alt="A demo for combined solution for signing up and logging in"&gt;&lt;/a&gt;&lt;/p&gt;

You can try it online: &lt;a href="https://signme.surge.sh"&gt;https://signme.surge.sh&lt;/a&gt;

&lt;p&gt;I like that solution because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is very easy to implement (I guess most devs will say this is a joke)&lt;/li&gt;
&lt;li&gt;Less place for errorsâ€Š–â€ŠI log in where my credentials fit!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Still, I am not a UX designer, so I would really like to have some you all to say what do you think about this pattern. Thanks!&lt;/p&gt;


</description>
      <category>redesign</category>
      <category>softwaredevelopment</category>
      <category>design</category>
      <category>userexperience</category>
    </item>
    <item>
      <title>IFTTT Ideas for Software Development</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Tue, 11 Apr 2017 22:15:43 +0000</pubDate>
      <link>https://forem.com/schniz/ifttt-ideas-for-software-development</link>
      <guid>https://forem.com/schniz/ifttt-ideas-for-software-development</guid>
      <description>

&lt;p&gt;Recently, I started to use, or actuallyâ€Š–â€Šmisuse, a service called “If This, Then That” which is written and called mostly &lt;a href="https://ifttt.com"&gt;IFTTT&lt;/a&gt;. Modern tools and applications solve one problem very good, and I like it. The drawback from it is that connectivity is the worst problem we’re facing right now. IFTTT came to the rescue by providing an interface to connect all these services, and I’d like to use it well. However, I have no good use for applets right now. Most of what I tried, actually, annoyed me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When I like something on Twitter, it creates a new task in a Todoist project called “Liked Tweets”. Because most of the time I’d like to see it later.&lt;/li&gt;
&lt;li&gt;When I take a screenshot on my iPhone, it sends it to a Telegram group called “Screenshots”. I thought it’d be cool, but it is super annoying.&lt;/li&gt;
&lt;li&gt;When I create a task on Todoist, send it to a Telegram group called “Tasks”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bah. That sucks. I really want to use IFTTT, but I need to find a good use. I don’t hold a software engineer role for the next couple of months because &lt;a href="https://medium.com/@galstar/leaving-the-comfort-zone-edaf10f9e536"&gt;I volunteered to command in the tech officer training course&lt;/a&gt;. However, lately, I started to think about things I could do with IFTTT when I return to software engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dev Screenshot =&amp;gt; Slack:&lt;/strong&gt; Whenever I take a screenshot on a test/development phone, send it to a “Screenshots” Slack channel. or a Telegram group. Whatever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev Screenshot =&amp;gt; Todoist:&lt;/strong&gt; Whenever I take a screenshot on a test/development phone, add it as a task on a todo list app, so I would know I have to add it inside a pull-request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Todo Comment =&amp;gt; Todoist:&lt;/strong&gt; Whenever I push a code with a // TODO comment, create a new task in my todo list app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Todo Comment =&amp;gt; Slack:&lt;/strong&gt; Whenever I push a code with a Todo comment, send it to a slack channel so people can make fun of me (mention me and ask me to do it already)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated Mailbox =&amp;gt; Telegram:&lt;/strong&gt; Create a mailbox for reminders, so todo apps/calendars etc can send me notifications through Telegram. (Even though I have the native todo apps and calendars for Mac and iOS.. so it will probably just annoy me too)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telegram =&amp;gt; Facebook Group:&lt;/strong&gt; Whenever I add some kind of hashtag (let’s say, #fullstack_group), share the message with a dedicated Facebook group.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calendar + Photos =&amp;gt; Some photo management:&lt;/strong&gt; Whenever I take a photo, check on my calendar if I need to be somewhere. If I do need to be there, add the photo to the calendar meeting or something. I don’t use any photo management tools but it sounds cool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub/GitLab/BitBucket/Whatever =&amp;gt; Todoist:&lt;/strong&gt; whenever I’m mentioned at GitHub/GitLab, add a todo with the link. Two-way bind GitLab’s Todo’s to the todo list app can work as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Let's share applets!
&lt;/h1&gt;

&lt;p&gt;Software developers, artists, musicians, and just everybody: what cool IFTTT applets do you have and use regularly? I’d like to experiment with cool stuff!&lt;/p&gt;


</description>
      <category>productivity</category>
      <category>ifttt</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>I failed toÂ deliver.</title>
      <dc:creator>Gal Schlezinger</dc:creator>
      <pubDate>Wed, 18 Jan 2017 18:07:50 +0000</pubDate>
      <link>https://forem.com/schniz/i-failed-todeliver</link>
      <guid>https://forem.com/schniz/i-failed-todeliver</guid>
      <description>

&lt;p&gt;I used to be a development infrastructure team leader. Part of my job, as I decided it to be, was to provide tools for teams to communicate with their customers and provide tools to build better and more relevant software.&lt;br&gt;
The team itself worked like a startup company within the organization. We didn't force people to use any of our solutionsâ€Š–â€Šwe tried to make them thrilled and excited about them, so they would support our products and use them with their own will.&lt;/p&gt;

&lt;p&gt;While I had success in some cases, there are couple of failures I still carry with me in my head, and lately I figured out that they all share the same problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  I workedÂ alone
&lt;/h2&gt;

&lt;p&gt;Most of the time, I worked on these tools for too long, alone. They all began with me starting to hack at night, and evolved to real projects, with no one but myself writing them with me. Although it was very fun to begin with it, working alone on these tools wasn't rewarding because I had no one to be excited as me about the projects.&lt;/p&gt;

&lt;p&gt;It taught me that demo time is important. Make time to show your projects to your colleagues. Many team leaders, with me included, had this problem that we haven't asked for a demo. I just didn't wanted to interrupt my employees. Just agree on the demo on a specific time, and make it seven, eight, fifteen minutes long demo.&lt;br&gt;
It can be a fun thing to do, and the team can learn and get inspired from the act.&lt;/p&gt;

&lt;h2&gt;
  
  
  I had no realÂ users
&lt;/h2&gt;

&lt;p&gt;I always seen myself as the user, when I clearly wasn't. This is a basic rule in UX design: thinking about myself as the user makes me to make wrong assumptions about the tools and the way I solve the problems. Hell, I am sometimes wrong about the problems themselves, without consulting with a real (or another) user. One example is my love for command line utilities and VIM in particular, while other colleagues are terrified by it.&lt;/p&gt;

&lt;p&gt;Go out for a walk, think about your problem and characterize your users. Who are they? If they're your coworkers, talk to them. If they are 23 years old bartenders, go to a nice night out with a pen and a piece of paper and just talk to a bartender.&lt;/p&gt;

&lt;p&gt;The important thing here is to talk to another human being. Even if you are a future user for the app, you should understand what to address &lt;em&gt;first&lt;/em&gt;. Many times we see the big picture and we want to solve it from one end to the otherâ€Š–â€Šbut sometimes providing a really simple and basic tool is enough for start.&lt;/p&gt;

&lt;p&gt;Providing a good MVP to your users is the most important thing. It might feel like a simple CRUD application, but it might solve a tiny bit of the problem. The only way to have a good MVP is to understand what &lt;em&gt;HAS&lt;/em&gt; to be in the app and what is just &lt;em&gt;NICE TO HAVE&lt;/em&gt; for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  I tried to satisfyÂ others
&lt;/h2&gt;

&lt;p&gt;I showed one of the tools to my boss. The tool was a micro-blogging/blogging/mailing list tool, making teams interact with their customers. My boss took my demo and showed it to some department managers in our organization. They loved it, and asked for a couple of features. One of the features, was to create a “secret” mailing list, changing the solution surface and actually changing the problem that the tool solved.&lt;/p&gt;

&lt;p&gt;I just needed to say “no”. However, I'm not used to it, and I really hate to be a no-man, since I really believe in making people happy. Because I had no “real users” either, I thought that my vote doesn't count.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can't satisfy everyone, so most of the time, you better satisfy yourself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I know what the vision of the tool should have been: “Open communication between teams and their customers”. Providing this specific vision could make these department managers understand what the tool is for and what it isn't for.&lt;br&gt;
Making sure you address the right problems is an important part of your application. This way you can measure yourself against your competitors and have some agenda why you provide a better tool. You can also get more customers this way, and have people &lt;em&gt;believe&lt;/em&gt; in your way, and make FANS for your software. Which is pretty damn wicked.&lt;/p&gt;

&lt;h2&gt;
  
  
  I was more excited about the code than theÂ product
&lt;/h2&gt;

&lt;p&gt;I saved this one for last. Not that long ago, I worked on a kind-of a Medium clone. In this project, I used Draft.js for the first time, and spent most of the time trying to add images with drag and drop and making a great user experience. I actually wrote an article about &lt;a href="https://medium.com/@galstar/composable-sql-in-javascript-db51d9cae017"&gt;Composable SQL in JavaScript&lt;/a&gt; while working on this project because I was so thrilled about the way I queried the database.&lt;/p&gt;

&lt;p&gt;I'll say it again. &lt;strong&gt;I was thrilled about the way I queried the database&lt;/strong&gt;. I was thrilled how I queried a SQL database, I used for years with Rails, PHP and even plain ASP.&lt;/p&gt;

&lt;p&gt;You can't say it's a bad thing, because it is the opposite. Yet the fact that I tried to implement the things I read on Brian Lonsdorf's (drboolean) awesome and life-changing book about JavaScript made me put so much time and effort on the way my code looks and acts. This is awesome for a side project or just testing a feature inside your project, but it should not slow you down in a real project.&lt;/p&gt;

&lt;p&gt;If the only thing that excites you in a project is how you write it, well, let me tell you something, the product won't be as good as your code. Try to be &lt;a href="https://m.signalvnoise.com/i-m-a-boring-programmer-and-proud-of-it-d4ac3dd2defe"&gt;a boring programmer&lt;/a&gt;. Make decisions about your &lt;strong&gt;product&lt;/strong&gt; and not about your &lt;strong&gt;code&lt;/strong&gt;. Remember that you have to deliver a product. Your users probably don't care about your functional programming skills as long as your product works. They just want to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So,
&lt;/h2&gt;

&lt;p&gt;Is jQuery enough for this app or you should use React? Just build the damn thing, show it to your coworkers and give it to your real users already. That's how you deliver, and that's what you're paid to do basically. ðŸ’°&lt;/p&gt;


</description>
      <category>softwaredevelopment</category>
      <category>ux</category>
      <category>selfimprovement</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
