<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Liu</title>
    <description>The latest articles on DEV Community by James Liu (@jamesliudotcc).</description>
    <link>https://dev.to/jamesliudotcc</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%2F264351%2F4395eec2-423c-4469-b31f-43c1620cdcf5.jpeg</url>
      <title>DEV Community: James Liu</title>
      <link>https://dev.to/jamesliudotcc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jamesliudotcc"/>
    <language>en</language>
    <item>
      <title>Symbolic logic and programming</title>
      <dc:creator>James Liu</dc:creator>
      <pubDate>Sun, 13 Sep 2020 00:19:10 +0000</pubDate>
      <link>https://dev.to/jamesliudotcc/symbolic-logic-and-programming-382p</link>
      <guid>https://dev.to/jamesliudotcc/symbolic-logic-and-programming-382p</guid>
      <description>&lt;p&gt;I am &lt;a href="https://github.com/jamesliudotcc/discrete-math-and-func-prog"&gt;working my way&lt;/a&gt; through VanDrunen's Discrete Math and Functional Programming. Symbolic logic is dealt with in a single chapter from beginning through multiple quantification. Here are some thoughts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It took a quarter-long course, Logic I, in college to get through that material. It was a long time ago, and I am glad it has stuck as well as it did. I am breezing through the chapter as if through well-trodden ground.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This chapter is 1/7 of what the author thinks should be covered in a semester-long class with "bright" math and CS undergrads. So I guess about 2 weeks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The book, as the title suggests, also covers programming. I think the programming aspect helps with the comprehension of logic, so that partly explains how it is squeezed into so much less space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All the extra how-to-prove-it material would have been really helpful when I got to Logic II. Logic I was way too slow, Logic II, which proved the soundness and consistency of first-order logic, was much too fast.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ocaml</category>
      <category>logic</category>
    </item>
    <item>
      <title>Use Dr. Racket for Reading The Little Schemer (or the missing setup instructions for The Little Schemer)</title>
      <dc:creator>James Liu</dc:creator>
      <pubDate>Sun, 26 Jul 2020 04:38:31 +0000</pubDate>
      <link>https://dev.to/jamesliudotcc/use-dr-racket-for-reading-the-little-schemer-or-the-missing-setup-instructions-for-the-little-schemer-40gh</link>
      <guid>https://dev.to/jamesliudotcc/use-dr-racket-for-reading-the-little-schemer-or-the-missing-setup-instructions-for-the-little-schemer-40gh</guid>
      <description>&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mostly, note cards and pencil is fine.&lt;/li&gt;
&lt;li&gt;Use Racket, and in fact, use the Dr. Racket IDE.&lt;/li&gt;
&lt;li&gt;Wrap strings in &lt;code&gt;""&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Quote list literals, so &lt;code&gt;'(a b c)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use Dr. Racket's testing capabilities to save yourself work&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Use Dr. Racket for Reading The Little Schemer (the missing setup instructions)
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Why The Little Schemer
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The Little Schemer&lt;/em&gt; is a classic Lisp book, which often comes recommended for newbies to Lisp who need an easier on-ramp to &lt;em&gt;Structure and Interpretation of Computer Programs&lt;/em&gt;. Personally, I tried working my way through &lt;em&gt;SICP&lt;/em&gt; on my own, made it some way in, and decided learning how to program in Scheme and understanding &lt;em&gt;SICP&lt;/em&gt; was too much all at once.&lt;/p&gt;

&lt;p&gt;In the preface, the authors write that "The Little Schemer is based on lecture notes from a two-week 'quickie' introduction to Scheme for students with no previous programming experience and an admitted dislike for anything mathematical." Great. I definitely have at least as much programming and math aptitude as that.&lt;/p&gt;

&lt;p&gt;Mostly, I have been working on it with note cards with pencil. The advantage is that I can cover the answer while I read the question, and I get the benefit of working out the question before I see the answer. But sometimes, I want to run the code to check my work before revealing the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up Scheme 💾
&lt;/h3&gt;

&lt;p&gt;Unfortunately, there are not setup instructions. Since the book was published in 1996, it seems unlikely setup instructions are going to do much good--it being the era of Windows 95 and Mac System 7. Back then, the internet came in the form of AOL CD-ROMs! 💽&lt;/p&gt;

&lt;p&gt;At the time of writing, the first Google result for "install scheme" points to &lt;a href="http://www.shido.info/lisp/scheme1_e.html" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;, which is for installing MIT Scheme on Windows. Unfortunately, MIT Scheme no longer even supports Windows. But don't worry, if you want, you can get a dialect called Chez Scheme with a Windows installer, as an apt package, or even using Homebrew.&lt;/p&gt;

&lt;h3&gt;
  
  
  Really, just get Racket 🏸
&lt;/h3&gt;

&lt;p&gt;But don't do any of that. Instead, get Racket. &lt;a href="https://racket-lang.org/new-name.html" rel="noopener noreferrer"&gt;Racket is a descendant of Scheme&lt;/a&gt;, and as far as I can tell it stopped calling itself a Scheme because it stopped being so purely minimalist (a sense I get mostly from &lt;a href="https://www.functionalgeekery.com/episode-24-matthew-flatt/" rel="noopener noreferrer"&gt;listening&lt;/a&gt; &lt;a href="https://cognitect.com/cognicast/061-matthew-flatt" rel="noopener noreferrer"&gt;to&lt;/a&gt; &lt;a href="https://cognitect.com/cognicast/084" rel="noopener noreferrer"&gt;podcasts&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Racket is nice enough to come with an &lt;a href="https://download.racket-lang.org/" rel="noopener noreferrer"&gt;installer&lt;/a&gt;. It also comes with an IDE, which, OK, I was skeptical at first because it looks a little outdated, but it is actually quite nice. Further, it comes with a book called &lt;a href="https://htdp.org/2020-5-6/Book/index.html" rel="noopener noreferrer"&gt;How to Design Programs&lt;/a&gt; (which comes with its own &lt;a href="http://cs.brown.edu/~sk/Publications/Papers/Published/fffk-htdp-vs-sicp-journal/paper.pdf" rel="noopener noreferrer"&gt;manifesto&lt;/a&gt; about how &lt;em&gt;SICP&lt;/em&gt; is too hard for beginners).&lt;/p&gt;

&lt;p&gt;For something simple, you can use Racket from the REPL, and type in the form in the preface for checking if something is an atom. What happens when we try typing this in?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;atom?&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;pair?&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;null?&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftffqe0ntd1r9exoxtbl1.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%2Fi%2Ftffqe0ntd1r9exoxtbl1.png" alt="Error message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uh oh.&lt;/p&gt;

&lt;p&gt;To correct that, try &lt;code&gt;(atom? "atom")&lt;/code&gt;. Ok, so string literals have to be wrapped in double quotes. But also take a look at what has to happen with lists:&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%2Fi%2Fu25v8bdehvfmme7yau34.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%2Fi%2Fu25v8bdehvfmme7yau34.png" alt="Quote strings. Quote lists too"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you need to quote lists so the interpreter knows the difference between a list, &lt;code&gt;(quote (a b c))&lt;/code&gt;, or &lt;code&gt;'(a b c)&lt;/code&gt; for short, and a function &lt;code&gt;a&lt;/code&gt; with arguments &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;(a b c)&lt;/code&gt;. When people say that in Lisp, code is data, it refers to being able to quote and unquote lists.&lt;/p&gt;

&lt;h3&gt;
  
  
  But really, use Dr. Racket
&lt;/h3&gt;

&lt;p&gt;Dr. Racket, despite looking like it is from the early 2000s, is great. It supports auto-indentation, auto-closing parens, and Unicode (so you can write λ instead of lambda, or use emoji). There are other nice features, like drawing lines to indicate the scope of variables.&lt;/p&gt;

&lt;p&gt;Use Dr. Racket by writing your definitions in the definition area. After you run them, you can interact with your functions in the interaction area. Since Dr. Racket supports many languages, you have to declare &lt;code&gt;#lang racket&lt;/code&gt; at the top, or select another language from the language dropdown at the bottom right. For &lt;em&gt;Little Schemer&lt;/em&gt;, just use Racket.&lt;/p&gt;

&lt;p&gt;Also, Racket includes a test-runner, so you can write tests to make sure that the code does what you expect. Some of the questions and answers give you test cases you can manually run to check the function you are writing. But that gets tiresome, and it is easy to write out your test cases as automated tests.&lt;/p&gt;

&lt;p&gt;You can begin your exploration like this:&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%2Fi%2Ftrp62mf53ttzg0ew3gjp.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%2Fi%2Ftrp62mf53ttzg0ew3gjp.png" alt="What Dr. Racket looks like"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the definition area as text:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt; &lt;span class="nv"&gt;racket&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;test-engine/racket-tests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;atom?&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;λ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;pair?&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;null?&lt;/span&gt; &lt;span class="nv"&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;define&lt;/span&gt; &lt;span class="nv"&gt;lat?&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;λ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;cond&lt;/span&gt;
    &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;null?&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nf"&gt;atom?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lat?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="no"&gt;#f&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;


&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;check-expect&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lat?&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;check-expect&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lat?&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="no"&gt;#t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;check-expect&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lat?&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="no"&gt;#f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And the interactions area:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;

&lt;span class="nv"&gt;Welcome&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;DrRacket,&lt;/span&gt; &lt;span class="nv"&gt;version&lt;/span&gt; &lt;span class="mf"&gt;7.7&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;3m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;Language:&lt;/span&gt; &lt;span class="nv"&gt;racket,&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;debugging&lt;/span&gt;&lt;span class="c1"&gt;; memory limit: 128 MB.&lt;/span&gt;
&lt;span class="nv"&gt;All&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nv"&gt;tests&lt;/span&gt; &lt;span class="nv"&gt;passed!&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lat?&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dr."&lt;/span&gt; &lt;span class="s"&gt;"Racket"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="no"&gt;#t&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;atom?&lt;/span&gt; &lt;span class="s"&gt;"️"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;#t&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>scheme</category>
      <category>racket</category>
      <category>lisp</category>
    </item>
    <item>
      <title>How to use async/await with map and Promise.all</title>
      <dc:creator>James Liu</dc:creator>
      <pubDate>Mon, 04 Nov 2019 03:44:27 +0000</pubDate>
      <link>https://dev.to/jamesliudotcc/how-to-use-async-await-with-map-and-promise-all-1gb5</link>
      <guid>https://dev.to/jamesliudotcc/how-to-use-async-await-with-map-and-promise-all-1gb5</guid>
      <description>&lt;p&gt;I found myself stuck on using the map function with async and await. It took me relearning how to work with promises to figure it out, but once I figured it out, the syntax turned out to be pretty nice and readable.&lt;/p&gt;

&lt;p&gt;JavaScript's async and await syntax is new as of ES2017. I think the syntax is really neat because it allows me to write shorter, easier to understand code than a pyramid of promises and thens, similar to how promises are an improvement on callback hell. There are more comprehensive explanations of async and await out there, like this one from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"&gt;MDN&lt;/a&gt;, from &lt;a href="https://javascript.info/async-await"&gt;Javascript.Info&lt;/a&gt;, and from &lt;a href="http://2ality.com/2016/10/async-function-tips.html"&gt;Dr. Axel R.&lt;/a&gt; Here is a &lt;a href="https://devchat.tv/js-jabber/jsj-329-promises-promise-finally-and-async-await-with-valeri-karpov/"&gt;JavaScript Jabber&lt;/a&gt; episode, super helpful.&lt;/p&gt;

&lt;p&gt;But what happens when you want to get back a bunch of data from a bunch of requests? There is no &lt;code&gt;await all&lt;/code&gt; in JavaScript. That's where &lt;code&gt;Promises.all()&lt;/code&gt; comes in. Promises.all() collects a bunch of promises, and rolls them up into a single promise. Once all of the inner promises resolve successfully, Promise.all() returns a resolved promise with all of the inner promises as resolved. To make things faster, once any of the inner promises rejects, Promise.all() rejects.&lt;/p&gt;

&lt;p&gt;The main point is that Promise.all() turns an array of promises into a single promise that, if things work, resolves into the array you want. Everything else is just details.&lt;/p&gt;

&lt;p&gt;Somehow, it took me a long time to get unstuck. Here is the code that I finally got working, and hopefully this helps with that explanation.&lt;/p&gt;

&lt;p&gt;Suppose you hit a REST endpoint and get an array of URLs for the REST endpoints which contain what you are ultimately after. For example, you know want to find some information about the movies R2-D2 was in from the Star Wars API. For whatever reason, you can't use the SWAPI GraphQL instead. We know that fetching from the network is an asynchronous operation, so we will have to use callbacks, promises, or the async and await keywords. Since R2-D2 was in several movies, will have several network calls to get all of them.&lt;/p&gt;

&lt;p&gt;So first, let's set up. Let's focus on just the smallest bit of functionality we're working on, so we'll use Node.js on the command line. Node.js doesn't come with fetch, so let's install it with npm or yarn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;node-fetch &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add node-fetch &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One gotcha with async/await is that an await keyword is only allowed inside an async function. In a real program, you're probably encapsulated enough so that you can just slap an async keyword on the function you're using the await keyword in, but inside of a scratch file, we want to abstract away from the enclosing context. But as Javascript programmers, we know how to get around that by wrapping what we want in an instantaneously invoked function expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// prettier-ignore&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// prettier-ignore&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://swapi.co/api/people/2/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterResponseJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;characterResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;characterResponseJson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we have the basic async/await syntax working, and we can inspect the response to see that we want the films field. It is an array of URLs.&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;let&lt;/span&gt; &lt;span class="nx"&gt;films&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characterResponseJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&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;filmUrl&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;let&lt;/span&gt; &lt;span class="nx"&gt;filmResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filmUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;filmResponseJSON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filmResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;filmResponseJSON&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this code, you get an array of pending promises. You need that new &lt;code&gt;async&lt;/code&gt;, otherwise the awaits inside the arrow function won't work. If you don't &lt;code&gt;await&lt;/code&gt; for the fetch, you get a bunch of rejected promises, and errors telling you to handle your promise rejections.&lt;/p&gt;

&lt;p&gt;But recall, a &lt;code&gt;Promise.all()&lt;/code&gt; takes an array of promises and wraps them into a single promise. So we wrap our &lt;code&gt;map&lt;/code&gt; function. And we already know some nice syntax for dealing with a single promise. We can &lt;code&gt;await&lt;/code&gt; it.&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;let&lt;/span&gt; &lt;span class="nx"&gt;characterResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://swapi.co/api/people/2/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterResponseJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;characterResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;films&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;characterResponseJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&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;filmUrl&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;let&lt;/span&gt; &lt;span class="nx"&gt;filmResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filmUrl&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;filmResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the sake of comparison, the equivalent code in promises looks like:&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="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://swapi.co/api/people/2/&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;characterResponse&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;characterResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;characterResponseJson&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;characterResponseJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filmUrl&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filmUrl&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filmResponse&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;filmResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;films&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For me, the first set of &lt;code&gt;.then().then()&lt;/code&gt; is pretty semantic, I can follow that almost as well as the async/await syntax. But once we're inside the &lt;code&gt;Promise.all()&lt;/code&gt;, things start getting hard to follow using only the promises syntax. Whatever action we are going to perform on the films will replace the &lt;code&gt;console.log&lt;/code&gt;, and in the &lt;code&gt;.then&lt;/code&gt; chaining syntax, that is already buried 3-levels of indentation deep. Shallow code is easy to understand code.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
