<?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: Vitaliy Akimov</title>
    <description>The latest articles on DEV Community by Vitaliy Akimov (@awto).</description>
    <link>https://dev.to/awto</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%2F53448%2Fcdb7b203-9c80-4049-9ef8-ebf6a4f2e302.jpeg</url>
      <title>DEV Community: Vitaliy Akimov</title>
      <link>https://dev.to/awto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/awto"/>
    <language>en</language>
    <item>
      <title>Productivity-boosting JavaScript debugger</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Wed, 02 Sep 2020 10:59:55 +0000</pubDate>
      <link>https://dev.to/awto/js-ts-debugger-with-time-traveling-persistent-state-api-and-more-5cn2</link>
      <guid>https://dev.to/awto/js-ts-debugger-with-time-traveling-persistent-state-api-and-more-5cn2</guid>
      <description>&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=effectful.debugger"&gt;Effectful Debugger&lt;/a&gt; is a VSCode plugin for JavaScript/TypeScript debugging. Besides the typical debugger's features, it offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time-traveling&lt;/li&gt;
&lt;li&gt;Persistent state&lt;/li&gt;
&lt;li&gt;Platform independence (one debugger for node, all browsers, embedded engines etc)&lt;/li&gt;
&lt;li&gt;Programmable API&lt;/li&gt;
&lt;li&gt;Hot mocking of functions or even parts of a function&lt;/li&gt;
&lt;li&gt;Hot code swapping&lt;/li&gt;
&lt;li&gt;Data breakpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you debug a lot, you often encounter a situation when you need to go a few steps backward to see your program's state before. These include variable values, object properties value, DOM, and so on.&lt;/p&gt;

&lt;p&gt;If your debugger supports time-traveling, you can stop execution at any time and step backward. The feature helps a lot, especially if this particular application state is hard to reach. For example, you may need to re-press the necessary combination of keys, reset the DB state to some specific values, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aS7iduSR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qo6z68d7orflalavxht.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aS7iduSR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3qo6z68d7orflalavxht.gif" alt="Time Traveling Simple"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All operations changing state are stored in a trace. The trace is used for restoring some past states. This looks like running an application in a reverse direction, including breakpoints.&lt;/p&gt;

&lt;p&gt;The whole application state can be saved and loaded back. And the application can even continue execution from the point where it was saved.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EDBG.capture&lt;/code&gt; API function return &lt;code&gt;JSON.stringify&lt;/code&gt; serializable object. The same object passed to &lt;code&gt;EDBG.restore&lt;/code&gt; resets the application to the captured state. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T6tUefOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1bjf2tobytbxp3k5me6o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T6tUefOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1bjf2tobytbxp3k5me6o.gif" alt="Persistent State Simple Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can even duplicate the state, opening another clone of the application, while the old is still running. The two applications are displayed as threads in VSCode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tQUHZiJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9dbkmqibz81koau9m22w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tQUHZiJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9dbkmqibz81koau9m22w.gif" alt="Persistent State Threads Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the variables, including the closure captured ones, are stored and restored too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tiiUVpAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/26r4zdrga9tz9hm1fec2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tiiUVpAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/26r4zdrga9tz9hm1fec2.gif" alt="Persistent State Variables Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The time-traveling trace is stored/restored with &lt;code&gt;EDBG.capture&lt;/code&gt;/&lt;code&gt;EDBG.restore&lt;/code&gt; functions too. We can use this for post-mortem analysis, and we can even resurrect the program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3DUfLewR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b3059jxgws22bl1zwnz7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3DUfLewR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b3059jxgws22bl1zwnz7.gif" alt="Time Traveling Persistent Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code can be changed while the application runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JzSETxF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mo2u8qib4w7iabbfhsv5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JzSETxF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mo2u8qib4w7iabbfhsv5.gif" alt="Hot Swapping Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hot swapping will work better in some next version. Now, only small changes will be updated without a problem. A better solution is just re-run a chunk of code from some point. It is also possible to set up some more complex strategies using APIs.&lt;/p&gt;

&lt;p&gt;Here I develop while the debugger runs. I get results immediately after any file is changed in case of any problem, I just set a breakpoint and run backward and fix a problem, getting results immediately again. In this demo, it was missed &lt;code&gt;case&lt;/code&gt; in &lt;code&gt;switch&lt;/code&gt;. It took a few seconds to go to the exact execution location, with correct variable values. This increases productivity a lot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xsYhFZgV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6q1jduqb1akihh8lx1cy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xsYhFZgV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6q1jduqb1akihh8lx1cy.gif" alt="Fast Restart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you ever wondered what changed your program state (including variables of objects fields, arrays elements, etc.). If your debugger has data breakpoints and time-traveling, it is enough to add a breakpoint and execute it backward.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xYWqdBTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ojalk1ce46tvnah2owev.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xYWqdBTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ojalk1ce46tvnah2owev.gif" alt="Data Breakpoints"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How it works
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/awto/effectfuljs"&gt;EffectfulJS&lt;/a&gt; is a JavaScript transpiler for adding any computational effect into the language without changing its syntax. We can use this for debugging applications only if they don't use EffectfulJS. It transpiles all the sources (including dependencies) and injects debugging instructions. They implement VSCode debugging protocol and also collect traces with current variable values, DOM and external function calls.&lt;/p&gt;

&lt;p&gt;Since the debugger transpiling sources, this adds extra code. It is slower than executing without the debugger. However, using debuggers speed ups development a lot. There is no need to restart anything. Programs can be debugged even after it returned some results. With fast-restart, only a necessary part of the program will be re-executed and so on.&lt;/p&gt;




&lt;p&gt;I already use this debugger in my React, NextJS and Node projects and it helps a lot, but it is in an early stage. Some JavaScript standard edge cases don't work correctly, and it could have better performance. &lt;/p&gt;

&lt;p&gt;Please let me know if you are willing to contribute. These might be anything from its &lt;a href="https://github.com/awto/effectfuljs/issues?q=is%3Aissue+is%3Aopen+label%3Adebugger"&gt;issues list with debugger tag&lt;/a&gt; or anything else you think is more useful.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>contributorswanted</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Async Generators as an alternative to State Management</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Tue, 01 Sep 2020 07:31:35 +0000</pubDate>
      <link>https://dev.to/awto/async-generators-as-an-alternative-to-state-management-1e3d</link>
      <guid>https://dev.to/awto/async-generators-as-an-alternative-to-state-management-1e3d</guid>
      <description>&lt;p&gt;Async Generators is a simple but powerful feature that is now a part of JavaScript. Applying Transducers approach from Functional Programming with Async Generators is a simple and powerful tool for improving software architecture, making it more agile, simplifying extension and composition.&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;With Async Generators there is no longer need for components state, state management tools, component lifecycle methods, and even the latest React Context and Suspense APIs. It is much simpler to develop, maintain, and test.&lt;/li&gt;
&lt;li&gt;Unlike a state management approach, async generators tame asynchronicity leaving mutations harmless (if visible only in the generator’s scope).&lt;/li&gt;
&lt;li&gt;This approach has a functional programming background too.
State persistence for things like time traveling, universal apps is also available.&lt;/li&gt;
&lt;li&gt;The article uses React and JavaScript, but the technique is applicable in any other framework or programming language with generators (coroutines).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;I’m advertising my tool only at the end and very briefly. Most of the article is about async generators without any dependency.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start with a statement from &lt;a href="https://redux.js.org/introduction/motivation"&gt;Redux motivation page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This complexity is difficult to handle as we’re mixing two concepts that are very hard for the human mind to reason about: mutation and asynchronicity. I call them Mentos and Coke. Both can be great in separation, but together they create a mess.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Redux and other state management tools are mostly focusing on restricting or controlling data mutations. Async generators can handle asynchronicity. This makes mutation safe if it is visible only within a particular generator scope.&lt;/p&gt;

&lt;p&gt;All the common state management techniques can be split into two big classes.&lt;/p&gt;

&lt;p&gt;The first class maintaining data dependencies graph to propagate changes through handlers — React Component State, MobX, RxJS. Maintaining these dependencies is a complex task. The underlying libraries are taking charge of part of this complexity by managing subscriptions, optimizing the order of handlers execution, batching them, but it is still confusing to use sometimes, often requires hard fine-tuning, e.g., with shouldComponentUpdatemethod.&lt;/p&gt;

&lt;p&gt;Another approach limits mutation to only a single cell (storage) (e.g., Redux). This needs much smaller libraries, with less magic in them. It is more a pattern than a library. Unfortunately, the programs are more verbose, and this breaks data encapsulation. There are many patterns, wrappers to solve this though, but they make a single cell approach to be more similar to the graph based one.&lt;/p&gt;

&lt;p&gt;The technique in this story and Redux are both based on Event Sourcing pattern, and they have many similarities. It also offers encapsulated data and synchronous deterministic order of executions for operations with side effects.&lt;/p&gt;

&lt;p&gt;This approach can be abstractly viewed as a dependency graph as well, but the changes are propagated in reverse direction, from its root to towards leaves of its spanning tree. In each node we check should the propagation proceed to children or not. This makes the scheduling algorithm very lightweight and easy to control. It doesn’t require any library, basing only on JavaScript built-in features.&lt;/p&gt;

&lt;p&gt;Let’s first port &lt;a href="https://github.com/reduxjs/redux/blob/master/examples/counter-vanilla/index.html"&gt;Redux VanillaJS counters&lt;/a&gt; example to illustrate the idea.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/uo8yvfhk//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The original reducer is replaced with async generator function. The function calculates and stores its state in a local variable. It also yields the calculated value, the new value is stored in the singleton storage, and it is visible from event handlers. I’ll remove that singleton storage in the next steps.&lt;/p&gt;

&lt;p&gt;This version doesn’t look much different from Redux. The async generator there could be Redux storage middleware. This violates one of &lt;a href="https://redux.js.org/introduction/three-principles"&gt;Redux principles&lt;/a&gt; though, namely storing all application state only in the storage. Even if the generator doesn’t have any local variables, it still has its execution state — the position in the code where the execution is suspended in &lt;code&gt;yield&lt;/code&gt; or &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Turning components inside-out
&lt;/h1&gt;

&lt;p&gt;Generator functions are functions returning iterators. We can do with them everything we can do with plain functions. For example, by composing generator functions, we can split computation into a few independent stages. Each stage has own encapsulated state. Each stage receives messages which were yielded on the previous stage, handles them yielding another messaging and passing them to the next stage.&lt;/p&gt;

&lt;p&gt;The payload of the messages can contain VDOM elements. Instead of having a monolithic components tree we emit parts of it and send them to the next stage, where they can be assembled or transformed. Here is the same Counters example with React.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/y3x6L9wu//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;There &lt;code&gt;pipe&lt;/code&gt; function is a function composition. The functions take two arguments. The first is async iterable for messages from the former stage. And the second is to send a message into the start of the pipe. It should be called only from event handlers.&lt;/p&gt;

&lt;p&gt;The example above briefly shows extensibility by decoupling a few menu buttons from the root component into a separate stage. Instead of abstracting menu buttons into a separate component it maintains a placeholder where it injects components it receives in messages with &lt;code&gt;“MENU_ITEM”&lt;/code&gt; type. It is an Inversion of Control for components. Both techniques React Components and these Inverted Components can be used together of course.&lt;/p&gt;

&lt;h1&gt;
  
  
  Extension
&lt;/h1&gt;

&lt;p&gt;An exciting point of this technique is nothing should be preliminary designed to make the program reusable and decoupled. Nowadays premature abstraction is probably a bigger evil than premature optimization. It almost definitely leads to an overdesigned mess impossible to use. Using abstract generators, it is easy to keep calm and implement the required features, splitting when needed, without thinking about future extensions, easy to refactor or abstract some common parts after more details are available.&lt;/p&gt;

&lt;p&gt;Redux is famous for making programs simpler to extend and reuse. The approach in this story is also based on Event Sourcing, but it is much simpler to run async operations and it doesn’t have a single store bottleneck, nothing should be designed prematurely.&lt;/p&gt;

&lt;p&gt;Many developers like single storage because it is easy to control. The control is not a free thing though. One of the widely accepted advantages of Event Sourcing pattern is an absence of a central DB. It is simpler to change one part without danger of breaking something else. There is another problem of single storage discussed in Persistence section below.&lt;/p&gt;

&lt;p&gt;There is &lt;a href="https://dev.to/awto/decouple-business-logic-using-async-generators-1kho"&gt;Decouple Business Logic&lt;/a&gt; article with more detailed cases study. At some step there, I added a multi-select feature to drag and drop without changing anything in single element handling. With a single store, this would mean changing its model from storing a single currently dragging element to a list.&lt;/p&gt;

&lt;p&gt;There are similar solutions in Redux, namely applying higher order reducer. It could take a reducer working with a single element and translate into reducer working for a list. The generators solution uses higher order async generators instead, taking a function for a single element and generating the one for a list. It is similar but much less verbose, as the generator encapsulates data and implicit control state.&lt;/p&gt;

&lt;p&gt;As an illustration, let’s make a list of counters. This step is covered in “Decouple Business Logic” article, I’m not giving many details here. The forkfunction is the async iterators transforming function, running its argument in threads per item. It is a not simple, but it is a generic one, works in many contexts as is. In the next section, for example, I apply it recursively to get a tree view.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/0payhjvw//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Performance
&lt;/h1&gt;

&lt;p&gt;Async generators overhead is much smaller than for state management libraries. But there are a lot of ways to get performance problems here too, e.g. over flooding with messages. But there are also a lot of almost effortless ways to improve performance.&lt;/p&gt;

&lt;p&gt;In the former example, there are useless calls to &lt;code&gt;ReactDom.render&lt;/code&gt;. This is obviously a performance problem, and there is a simple solution. Solving it quickly by sending another message with type &lt;code&gt;“FLUSH”&lt;/code&gt; after each dispatched event. React render runs only after it receives this message. The intermediate steps can yield whatever they need in between.&lt;/p&gt;

&lt;p&gt;Another awesome side of this approach is you may not worry about performance until it is a problem. Everything is structured in small autonomous stages. They are easy to refactor, or even without refactoring — many performance problems can be solved by adding another generic state in the pipe of steps, e.g., batching, prioritizing, saving intermediate data, etc.&lt;/p&gt;

&lt;p&gt;For example, in the demo constructed React elements are saved in local variables and React can re-use them. Changes are propagated from the root towards leaves, so optimizations like overridingshouldComponentUpdate aren’t needed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing
&lt;/h1&gt;

&lt;p&gt;Comparing to Redux reducer tests, generators fit a bit darker box testing strategy. The tests don’t have access to the current state. Though still, they are very simple to write. With Jest snapshots, the test can be a list of input messages with comparing output using snapshots.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;counterControl&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainControl&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MENU&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Menu&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VALUE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&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="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CONTROL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Control&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FLUSH&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VALUE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FLUSH&lt;/span&gt;&lt;span class="dl"&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;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;CONTROL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;toJSON&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toMatchSnapshot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you prefer unit-tests as documentation policy, there are many ways to make a self-documenting API for testing. Say, a function &lt;code&gt;eventually&lt;/code&gt;/&lt;code&gt;until&lt;/code&gt; as an addition to traditional BDD expressions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Persistent state
&lt;/h1&gt;

&lt;p&gt;There is another motivation for Redux described in &lt;a href="https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367"&gt;You Might Not Need Redux&lt;/a&gt; article by Dan Abramov — namely providing access to the state and it can be serialized, cloned, diffed, patched, etc. This can be used for time travel, hot reloading, universal applications and more.&lt;/p&gt;

&lt;p&gt;For this to work, the whole application state should be kept in Redux storage. Many Redux applications(even Redux samples) have some part of state stored outside of their store. These are components state, closures, generators or async functions state. Redux based tools can not persist this state.&lt;/p&gt;

&lt;p&gt;Having a single source of truth as a single storage Redux, of course, makes programs simpler. Unfortunately, it is often impossible. Consider for example distributed application, e.g., data are shared between frontend and backend.&lt;/p&gt;


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

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7UPOvbsA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1027631659296780289/81jHcOL9_normal.jpg" alt="Lindsey Kuper profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Lindsey Kuper
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @lindsey
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      "Oh, you wanted to *increment a counter*?! Good luck with that!" -- the distributed systems literature
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      18:55 PM - 09 Mar 2015
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=575006945213485056" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=575006945213485056" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      376
      &lt;a href="https://twitter.com/intent/like?tweet_id=575006945213485056" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      583
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Event Sourcing is very successful for distributed applications. With generators, we can write a proxy sending all incoming messages to the remote side and yielding all received messages. There can be separate pipelines on each peer, or it can be the same application but a few running processes. Many configurations are easy to set up, use and re-use.&lt;/p&gt;

&lt;p&gt;For example &lt;code&gt;pipe(task1, remoteTask2, task3)&lt;/code&gt;. Here &lt;code&gt;remoteTask2&lt;/code&gt; may be either proxy or, it may be defined here, say, for debugging purposes.&lt;/p&gt;

&lt;p&gt;Each part maintains its own state, it doesn’t need to be persistent. Say if each task is implemented by a separate team they are free to use any model for the state, change it any time without worrying about the other team’s work is broken.&lt;/p&gt;

&lt;p&gt;This fits well for Server Side Rendering too. Say, there can be a particular higher order function to cache resulting values depending on inputs on the back-end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="o"&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;commonTask1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;memo&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;renderTask1&lt;/span&gt;
         &lt;span class="nx"&gt;renderTask2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="nx"&gt;commonTask2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;memo&lt;/code&gt; higher order function examines incoming messages and may find out some calculation may be reused. This may be a server-side rendered string, and some next stage builds HTTP response with it.&lt;/p&gt;

&lt;p&gt;The render tasks can run async operations, requesting something remote. For better user experience we want pages to load fast. To increase initial page load time applications can load components lazily displaying some loading placeholder instead of the component until it is ready. Having a few such components on a page with a bit different loading time causes page re-layouts worsening user experience.&lt;/p&gt;

&lt;p&gt;React team recently announced Suspense API to solve this problem. It is an extension of React embedded into its renderer. With the Inverted Components like in this article, Suspense API isn’t needed, the solution is much simpler and not a part of UI framework.&lt;/p&gt;

&lt;p&gt;Say the application uses dynamic imports to load lazy controls, this can be done with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LAZY_CONTROL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CONTROL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./lazy_component&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;There is another generic next stage. It collects all &lt;code&gt;"LAZY_CONTROL"&lt;/code&gt; messages, and awaits either all &lt;code&gt;"CONTROL"&lt;/code&gt; messages are received after or a threshold time interval. After, it emits &lt;code&gt;"CONTROL"&lt;/code&gt; messages either with the loaded control or with loading indicator placeholder. All the next updates can be batched as well using some specific timeout to minimize re-layouts.&lt;/p&gt;

&lt;p&gt;Some generator can also reorder messages to give animation a bigger priority than server data updates. I’m not even sure there are needs for a server-side framework. A tiny generator could transform initial HTTP request into messages or threads depending on URL, auth session, etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Functional Programming
&lt;/h1&gt;

&lt;p&gt;Commonly used state management tools have FP background. The code from the article doesn’t look like FP in JavaScript because of imperative &lt;code&gt;for-of&lt;/code&gt;/&lt;code&gt;switch&lt;/code&gt;/&lt;code&gt;break&lt;/code&gt; statements. It has a corresponding concept in FP too. It is so called Monads do-notation. For example one of their use in Haskell is to resolve problems like React components property drilling.&lt;/p&gt;

&lt;p&gt;To keep this story practical I don’t digress from the main subject here, there is another article — &lt;a href="https://dev.to/awto/using-generators-as-syntax-sugar-for-side-effects-2c4e"&gt;Using Generators as syntax sugar for side effects&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Effectful.js
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://effectful.js.org"&gt;Effectful.js&lt;/a&gt; is a babel preset implementing do-notation working for any monad without any JavaScript syntax extension. It also supports state persistence with a reference implementation in es-persist library. For example, this may be used to convert all async generators example above into pure functions.&lt;/p&gt;

&lt;p&gt;State persistence is not the primary goal of the tool. It is for higher level business logic description. Nevertheless, the tool is abstract and has many purposes. I’ll write about them more soon.&lt;/p&gt;

&lt;p&gt;Here is &lt;a href="https://github.com/awto/effectfuljs"&gt;the summary sample&lt;/a&gt; on GitHub with all the feature above plus automatic Undo/Redo and storing its full state in &lt;code&gt;localStorage&lt;/code&gt;. And here is running &lt;a href="https://effectful.js.org/demo/alternative/"&gt;transpiled version&lt;/a&gt; (it writes to your browsers local storage but no information is sent to the server side). I’m not giving many details in this article, it is about async generators without dependency, but I suppose the code is straightforward to read. Check for example &lt;a href="https://github.com/awto/effectfuljs/blob/master/samples/persist-counters/undoredo.js"&gt;undoredo.js&lt;/a&gt; for easy time traveling implementation details.&lt;/p&gt;

&lt;p&gt;The original sample requires almost no changes, I only replaced not serializable Promises, with corresponding functions from “es-persist” and replaced closures with invocations of R.bindfunction from the same library. EffectfulJS toolchain has another transpiler to make all the functions, including closures serializable, but not used in this example to keep it simpler.&lt;/p&gt;




&lt;p&gt;The story is just a brief description of the technique. I’m using it for a couple of years already, and happy because of improvements it provides. Try it, and I’m sure you’ll enjoy it too. There are many things to describe in depth. Stay tuned!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>functional</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Suspense is to a Monad as Hooks are to Applicative Notation</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Tue, 01 Sep 2020 07:29:14 +0000</pubDate>
      <link>https://dev.to/awto/react-suspense-is-to-a-monad-as-hooks-are-to-applicative-notation-4c8h</link>
      <guid>https://dev.to/awto/react-suspense-is-to-a-monad-as-hooks-are-to-applicative-notation-4c8h</guid>
      <description>&lt;p&gt;Monads and Applicative Functors are extensively used in functional programming. There is a relationship between them and React Suspense for Data Fetching and React Hooks APIs. This is a quick and simple introduction to Monads and Applicatives along with a description of their similarities.&lt;/p&gt;

&lt;p&gt;The post is about experimental &lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html"&gt;React Suspense for Data Fetching&lt;/a&gt;, not about recently released React Suspense for Code Splitting (&lt;code&gt;React.Suspense&lt;/code&gt; and &lt;code&gt;React.lazy&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;No prior knowledge of Monads, Applicatives and the experimental Suspense is required to read this article. It explains the essence of them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Monad do-notation
&lt;/h1&gt;

&lt;p&gt;The React framework approach encourages developers to use functional programming techniques. At least component render functions should not have observable side effects. JavaScript has no way to ensure this, but there are programming languages which can. For example, Haskell doesn’t accept side effects at all.&lt;/p&gt;

&lt;p&gt;Pure functions make the code modular, predictable and easier to verify. But they also significantly increase verbosity. Here is a statement from &lt;a href="https://en.wikipedia.org/wiki/Philip_Wadler"&gt;Phil Walder&lt;/a&gt;’s &lt;a href="https://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf"&gt;Monads for functional programming&lt;/a&gt;(1995) tutorial:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is with regard to modularity that explicit data flow becomes both a blessing and a curse. On the one hand, it is the ultimate in modularity. All data in and all data out are rendered manifest and accessible, providing a maximum of flexibility. On the other hand, it is the nadir of modularity. The essence of an algorithm can become buried under the plumbing required to carry data from its point of creation to its point of use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Monads solve this problem for Haskell. And Suspense/Hooks solve the same problem in React.&lt;/p&gt;

&lt;p&gt;So what is a Monad? It is a simple abstract interface which has two functions, let’s call them of and chain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;of&lt;/code&gt; — takes any value and returns some monadic (effectful) value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chain&lt;/code&gt; — takes an effectful value and a function from any value to an effectful one and returns another effectful value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The effectful values there may encapsulate any concrete implementation-specific information. There are no requirements what exactly it should be, it is some opaque data. The interface’s concrete implementations should follow a set of laws, and this is it.&lt;/p&gt;

&lt;p&gt;There is nothing to say more about monads since they are abstract. They don’t necessarily store anything, wrap or unwrap anything or even chain anything.&lt;/p&gt;

&lt;p&gt;But why do we need this if it is so abstract and defines almost nothing? The interface provides an abstract mean to compose computations with side effects.&lt;/p&gt;

&lt;p&gt;If you write code in JavaScript, you may wonder now. You’ve already composed a lot of computations with side effects without seeing any Monad. But in fact, you can consider you’ve already used them there.&lt;/p&gt;

&lt;p&gt;In computer science, Monads first appeared for studying side effects in imperative languages. They are a tool to embed imperative worlds into a pure math world for further studying.&lt;/p&gt;

&lt;p&gt;This way if you want to convert your imperative program into math formulas representing it, doing this with Monad expressions would be the simplest and the most straightforward way. It is so straightforward what you don’t even need to do it manually, there are tools that do it for you.&lt;/p&gt;

&lt;p&gt;Haskell has a syntax sugar called do-notation exactly for this. This makes writing imperative programs in Haskell possible. There is a special tool in its compiler. It converts such imperative programs into a Monadic pure Haskell expressions. The expressions are close to math you see in textbooks.&lt;/p&gt;

&lt;p&gt;JavaScript is an imperative language. We can consider any imperative code to be a do-notation already. But unlike the one in Haskell’s, it is not abstract. It works only for built-in side effects. There is no way to add support of any new one except extending the language.&lt;/p&gt;

&lt;p&gt;There are such extensions, namely generators, async and async generator functions. JavaScript JIT compiler converts async and generator functions into concrete built-in API calls. Haskell doesn’t need such extensions. Its compiler converts do-notation into abstract Monads interface function calls.&lt;/p&gt;

&lt;p&gt;For this post, we need only two JavaScript built-in effects. Let’s call them Mutation and Exception. They have clear meanings. Mutations allow changing values of some references. JavaScript has the Exceptions effect embedded using &lt;code&gt;throw&lt;/code&gt;/ &lt;code&gt;try-catch&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;We can convert some effects into others. This way we can write async code using Generators.&lt;/p&gt;

&lt;p&gt;This conversion trick can be applied to other effects too. And apparently, just Mutation and Exception are enough to get any other effect. This means we can turn any plain function into an abstract do-notation already. And this is exactly what Suspense does.&lt;/p&gt;

&lt;p&gt;When the code encounters some effectful operation and requires suspension it throws an exception. It contains some details (for example a Promise object). One of its callers catches the exception, waits while the promise in the argument is settled, stores the resulting value in a cache, and re-runs the effectful function from the beginning.&lt;/p&gt;

&lt;p&gt;After the Promise is resolved the engine calls the function again. The execution goes from its start, and when it encounters the same operations it returns its value from the cache. It doesn’t throw an exception and continues execution until the next suspension request or the function’s exit. If the function doesn’t have any other side effects its execution should go the same paths and all pure expressions are recalculated producing the same values.&lt;/p&gt;

&lt;p&gt;Let’s re-implement Suspense. Unlike React, this one works with the abstract Monads interface. For simplicity, my implementation also hides a resource cache. Instead, the runner function counts invoked effects and uses the current counter value as a key for the internal cache. Here is the runner for the abstract interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** effectful expression throws this object if it requires suspension */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="cm"&gt;/** Pointer to mutable data used to record effectful computations */&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/** Runs `thunk()` as an effectful expression with `of` and `chain` as Monad's definition */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chain&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;thunk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/** here it caches effects requests */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trace&lt;/span&gt; &lt;span class="o"&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;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;trace&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;step&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;step&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;savedContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thunk&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="cm"&gt;/** re-throwing other exceptions */&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;e&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;e&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;pos&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&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;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                     &lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                     &lt;span class="cm"&gt;/* recording the resolved value */&lt;/span&gt;
                     &lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pos&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="cm"&gt;/** replay */&lt;/span&gt;
                     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;step&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;savedContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/** marks effectful expression */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eff&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* if the execution is in a replay stage the value will be cached */&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="cm"&gt;/* saving the expression to resolve in `run` */&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;effect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;token&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 let’s add a concrete Async effects implementation. Promises, unfortunately, aren’t exactly monads since one Monad law doesn’t hold for them, and it is a source of subtle problems, but they are still fine for our do-notation to work.&lt;/p&gt;

&lt;p&gt;Here is concrete Async effect implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runPromise&lt;/span&gt; &lt;span class="o"&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;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&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;arg&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;f&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And here’s a simple example, it waits for delayed values before rendering proceeds:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/714n51l6mq"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The sandbox also contains &lt;code&gt;Component&lt;/code&gt; wrapper. It turns an effectful functional component into a React component. It simply adds chain callback and updates the state accordingly. This version doesn’t have a fallback on threshold feature yet, but the last example here does have it.&lt;/p&gt;

&lt;p&gt;The runner is abstract, so we can apply it for something else. Let’s try this for the &lt;code&gt;useState&lt;/code&gt; hook. It is a Continuation monad, not a State monad as its name may suggest.&lt;/p&gt;

&lt;p&gt;Effectful value here is a function which takes a callback as an argument. This callback is called when the runner has some value to pass further. For example when the callback returned from &lt;code&gt;useState&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;Here, for simplicity, I use single callback continuations. Promises have one more continuation for failure propagation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runCont&lt;/span&gt; &lt;span class="o"&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;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;cont&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;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;cont&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="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;cont&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;useState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initial&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;initial&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;next&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;cont&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;next&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 here is a working usage example, with most of “kit.js” copy-pasted, except the monad’s definition.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/j79mv6yv0v"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Unfortunately, this is not exactly the &lt;code&gt;useState&lt;/code&gt; hook from React yet, and the next section shows why.&lt;/p&gt;

&lt;h1&gt;
  
  
  Applicative do-notation
&lt;/h1&gt;

&lt;p&gt;There is another extension for do-notation in Haskell. It targets not only Monad abstract interface calls but also calls of Applicative Functors abstract interface.&lt;/p&gt;

&lt;p&gt;Applicative interfaces shares the &lt;code&gt;of&lt;/code&gt; function with Monads and there is another function, let’s call it &lt;code&gt;join&lt;/code&gt;. It takes an array of effectful values and returns a single effectful value resolving to an array. The resulting array contains all the values to which each element of the argument array was resolved.&lt;/p&gt;

&lt;p&gt;I use a different one from Haskell’s interface. Both are equal though — it is simple to convert Haskell’s interface into the one used here and back. I do this because this basis is much simpler to use in JavaScript, it doesn’t need any higher-order functions, and there is already its instance in the standard runtime.&lt;/p&gt;

&lt;p&gt;In Haskell and in JavaScript any Monad is immediately an Applicative Functor. This means we don’t need to write a concrete implementation of Applicative interface, we can generate it automatically.&lt;/p&gt;

&lt;p&gt;If there is a default implementation, why do we need Applicative Functors? There are two reasons. The first one is not all Applicative Functors are Monads, so there is no &lt;code&gt;chain&lt;/code&gt; method from which we can generate &lt;code&gt;join&lt;/code&gt;. Another reason is, even if there is &lt;code&gt;chain&lt;/code&gt;, custom &lt;code&gt;join&lt;/code&gt; implementation can do the same thing in a different way, probably more efficiently. For example, fetching resources in parallel rather than sequentially.&lt;/p&gt;

&lt;p&gt;There is an instance of this interface for Promises in the standard runtime. It is &lt;code&gt;Promise.all&lt;/code&gt;(ignoring some details here for simplicity again).&lt;/p&gt;

&lt;p&gt;Let’s now return to the state example. What if we add another counter in the component?&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/3k0j3olk61"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The second counter now resets its value when the first one is incremented. It is not how Hooks are supposed to work. Both counters should keep their values and work in parallel.&lt;/p&gt;

&lt;p&gt;This happens because each continuation invocation erases everything after it in the code. When the first counter changes its value the whole next continuation is re-started from the beginning. And there, the second counter value is 0 again.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://medium.com/dailyjs/react-suspense-as-a-monad-notation-and-hooks-as-an-applicative-notation-f66ef94cb54f"&gt;run function implementation&lt;/a&gt;, the invalidation happens at line 26 — &lt;code&gt;trace.length = pos&lt;/code&gt; — this removes all the memorized values after the current one (at &lt;code&gt;pos&lt;/code&gt;). Instead, we could try to diff/patch the trace instead. It would be an instance of Adaptive Monad used for incremental computations. MobX and similar libraries are very similar to this.&lt;/p&gt;

&lt;p&gt;If we invoke effectful operations only from a function’s top level, there are no branches or loops. Everything will be merged well overwriting the values on the corresponding positions, and this is exactly what Hooks do. Try to remove the line in the code sandbox for two counters above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Transpiler alternative
&lt;/h1&gt;

&lt;p&gt;Using Hooks already makes programs more succinct, reusable and readable. Imagine what you could do if there were no limitations (Rules of Hooks). The limitations are due to runtime-only embedding. We can remove these limitations by means of a transpiler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/awto/effectfuljs"&gt;Effectful.JS&lt;/a&gt; is a transpiler for embedding effectful into JavaScipt. It supports both Monadic and Applicative targets. It greatly simplifies programs in the designing, implementing, testing, and maintaining stages.&lt;/p&gt;

&lt;p&gt;Unlike React Hooks and Suspense, the transpiler doesn’t need to follow any rules. It works for any JavaScript statement (branches, loops, exceptions etc). It never re-plays functions from the beginning. This is faster. Plus the functions can use any JavaScript built-in side effect.&lt;/p&gt;

&lt;p&gt;Effectful.JS is not exactly a transpiler but rather a tool to create transpilers. There are also a few predefined ones and a lot of options for tuning. It supports double-level syntax, with special markers for effectful values (like &lt;code&gt;await&lt;/code&gt; expressions in async functions, or Haskell’s do). And it also supports a single level syntax where this information is implicit (like Suspense, Hooks or languages with Algebraic Effects).&lt;/p&gt;

&lt;p&gt;I’ve quickly built a Hooks-like transpiler for demo-purposes — &lt;a href="https://github.com/awto/effectfuljs/tree/master/samples/react-do"&gt;@effectful/react-do&lt;/a&gt;. Calling a function with names starting with “use” is considered effectful. Functions are transpiled only if their name starts with “use” or they have “component” or “effectful” block directive (a string at the beginning of the function).&lt;/p&gt;

&lt;p&gt;There are also “par” and “seq” block-level directives to switch between applicative and monadic targets. With “par” mode enabled the compiler analyzes variable dependencies and injects &lt;code&gt;join&lt;/code&gt; instead of &lt;code&gt;chain&lt;/code&gt; if possible.&lt;/p&gt;

&lt;p&gt;Here is the example with two counters, but now adapted with the transpiler:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/mzp619y8wj"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;For demo purposes, it also implements Suspense for Code Splitting. The whole function is six lines long. Check it out in the runtime implementation &lt;a href="https://github.com/awto/effectfuljs/blob/master/samples/react-do/main.js"&gt;@effectful/react-do/main.js&lt;/a&gt;. In the next example, I’ve added another counter which rendering is artificially delayed for demo purposes.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/mzp619y8wj"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Algebraic Effects
&lt;/h1&gt;

&lt;p&gt;Algebraic Effects are often mentioned along with Suspense and Hooks. These may be internals details or a modeling tool, but React doesn’t ship Algebraic Effects to its userland anyway.&lt;/p&gt;

&lt;p&gt;With access to Algebraic Effects, users could override operations behavior by using own Effect Handler. This works like exceptions with an ability to resume a computation after &lt;code&gt;throw&lt;/code&gt;. Say, some library function throws an exception if some file doesn’t exist. Any caller function can override how it can handle it, either ignore or exit process, etc.&lt;/p&gt;

&lt;p&gt;EffectfulJS doesn’t have built-in Algebraic Effects. But their implementation is a tiny runtime library on top of continuations or free monads.&lt;/p&gt;

&lt;p&gt;Invoking a continuation also erases everything after the corresponding &lt;code&gt;throw&lt;/code&gt;. There is also special syntax and typing rules to get Applicative (and Arrows) API — &lt;a href="http://homepages.inf.ed.ac.uk/slindley/papers/aeia.pdf"&gt;Algebraic Effects and Effect Handlers for Idioms and Arrows&lt;/a&gt;. Unline Applicative-do this prohibits using any anything which requires Monad operations.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generators
&lt;/h1&gt;

&lt;p&gt;For monadic notation, we can use Generators, but with some limitations. There are more details in &lt;a href="https://dev.to/awto/using-generators-as-syntax-sugar-for-side-effects-2c4e"&gt;Using Generators as syntax sugar for side effects&lt;/a&gt; article. &lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;The transpiler is a burden, and it has its own usage cost. Like for any other tool, use it only if this cost is smaller than the value you get.&lt;/p&gt;

&lt;p&gt;And you can achieve a lot with EffectfulJS. It is a new way to write JavaScript programs. It is useful for projects with complex business logic. Any complex workflow can be a simple maintainable script.&lt;/p&gt;

&lt;p&gt;As an example, Effectful.JS can replace Suspense, Hooks, Context, and Components State with tiny functions. Error Boundaries are the usual &lt;code&gt;try-catch&lt;/code&gt; statements. Async rendering is an async scheduler. But we can use it for any computations, not only for rendering.&lt;/p&gt;

&lt;p&gt;There are a lot of other awesome application-specific uses, and I’m going to write more about them soon. Stay tuned!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>computerscience</category>
      <category>functional</category>
    </item>
    <item>
      <title>Using Generators as syntax sugar for side effects
</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Mon, 31 Aug 2020 11:17:45 +0000</pubDate>
      <link>https://dev.to/awto/using-generators-as-syntax-sugar-for-side-effects-2c4e</link>
      <guid>https://dev.to/awto/using-generators-as-syntax-sugar-for-side-effects-2c4e</guid>
      <description>&lt;p&gt;This story shows Generators as an explicit but seamless syntax for programs with asynchronous operations, shared mutable state and other side effects. The conversion is based on so-called Monads.&lt;/p&gt;

&lt;p&gt;In spite of the scary name, Monads are a very simple concept. You already use them when you change some variable value or output anything or throw/catch an exception. Monads first appeared in Computer Science to support mathematical reasoning about side-effects in imperative languages such as JavaScript.&lt;/p&gt;

&lt;p&gt;Other researchers were designing practical languages with only pure functions. Using only pure functions makes programs more verbose and harder to read. Monads were applied as a practical tool for converting programs with effects into pure ones. Here is a citation from one of the best monads tutorial — Monads for functional programming by &lt;a href="https://en.wikipedia.org/wiki/Philip_Wadler"&gt;Philip Wadler&lt;/a&gt; (1995):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is with regard to modularity that explicit data flow becomes both a blessing and a curse. On the one hand, it is the ultimate in modularity. All data in and all data out are rendered manifest and accessible, providing a maximum of flexibility. On the other hand, it is the nadir of modularity. The essence of an algorithm can become buried under the plumbing required to carry data from its point of creation to its point of use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Doesn’t it sound familiar? E.g., property drilling for React Components and one of the reasons for state management to solve it.&lt;/p&gt;

&lt;p&gt;Original abstract do-notation is a macro converting programs looking like imperative one into abstract API calls. The concrete implementations of that APIs can construct an Iterable object, or a Promise or many other things. This way the same syntax (and the same programs) can be reused in different contexts.&lt;/p&gt;

&lt;p&gt;JavaScript has syntax extensions similar to do-notation. They are async and/or generator functions. Unlike original do-notation they are converted to concrete API calls ( &lt;code&gt;Promise#then&lt;/code&gt;, and Iterable constructors) by JavaScript compiler or some transpiler (e.g. regenerator). These concrete functions are almost instances of abstract monad API.&lt;/p&gt;

&lt;p&gt;Async and generator functions are based on Coroutine monad. It can be converted into many other monads, but not all. There is a well-known fact in JavaScript community — generator functions can replace async functions. Asynchronous functions written using generators syntax can be canceled, unlike standard async functions. The only overhead is the need to call a wrapper function, which converts Iterable into a Promise.&lt;/p&gt;

&lt;p&gt;There are many examples of using generators for async code so I’ll illustrate the idea on another case instead. It is maybe not so practical, but we can turn a generator function with a mutable state into a pure function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;incr&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="k"&gt;yield&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;incrX2&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="k"&gt;yield&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;incr&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;incr&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;main&lt;/span&gt; &lt;span class="o"&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;incrX2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// framework&lt;/span&gt;
&lt;span class="kd"&gt;function&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;iter&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&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;walk&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;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&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;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&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;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
      &lt;span class="nx"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;step&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;state&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;next&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;step&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;state&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;walk&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;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;_&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;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&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;Here both functions &lt;code&gt;incr&lt;/code&gt; and &lt;code&gt;incrX2&lt;/code&gt; have side effects. They change and read shared data. But the resulting function &lt;code&gt;state(incrX2)&lt;/code&gt; is pure. The function state does actual conversion between Iterable into a State monad.&lt;br&gt;
This is how it looks with inlined framework functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;incr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;ns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ns&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;incrX2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;incr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;s2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;incr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s1&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;s2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;r2&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;The example skips abstract API layer. There are quite a few options to chose its basis, but the most simple one is two functions: of and chain. They both return monadic(effectful) value. It is an abstract thing and can be anything depending on the concrete API implementation. For the abstract interface, the values of this type are entirely opaque.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;of&lt;/code&gt; — takes any value and returns effectful value, what it does exactly with the argument is defined by interface implementation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chain&lt;/code&gt; — takes some effectful value and a function mapping anything to another effectful value, returns some other effectful value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concrete implementations of the function can do anything if this conforms to so-called monadic laws. In fact, my choice of chainname is typical for JavaScript libraries but a bit misleading. It suggests some concrete implementation, chaining of something. But, again, it is some abstract thing, and the only requirement is monad laws conformance.&lt;/p&gt;

&lt;p&gt;Here are the laws:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(f, x) =&amp;gt; chain(of(x), f)&lt;/code&gt; should be equal to &lt;code&gt;(f, x) =&amp;gt; f(x)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;m =&amp;gt; chain(m, x =&amp;gt; of(x))&lt;/code&gt; should be equal to &lt;code&gt;m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(m, f, g) =&amp;gt; chain(chain(m, f), g)&lt;/code&gt; should be equal to &lt;code&gt;(m, f, g) =&amp;gt; chain(m, x =&amp;gt; chain(f(x), g))&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the laws hold we can use the API in do-notation, or in some abstract functions working for any monad.&lt;/p&gt;

&lt;p&gt;For example, the first law means the value of &lt;code&gt;x&lt;/code&gt; should be stored somewhere by &lt;code&gt;of&lt;/code&gt; until processing by &lt;code&gt;chain&lt;/code&gt;. This is why monads are often explained as something wrapping some value (burrito). However, in the general case, monad values aren't required to wrap anything (if they are constructed by something but not &lt;code&gt;of&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Let’s convert Iterable into this abstract interface. It is almost the same like for State except the functions are replaced with abstracted calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chain&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;fun&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&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;walk&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;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&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;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&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;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&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;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&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;walk&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 State, effectful value is a function taking some original state and returning a pair of a resulting value and a new state value. Here is State monad definition using the abstract intermediate layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&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;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&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;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&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;s&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;nextArg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextArg&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;nextState&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="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;_&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;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&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 Promises:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&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;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&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;arg&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;fun&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first monad law doesn’t work for Promises if &lt;code&gt;x&lt;/code&gt; is another object with &lt;code&gt;then&lt;/code&gt; method (Thenable). This &lt;code&gt;then&lt;/code&gt; method will be called, but the law requires it to be returned as is. &lt;/p&gt;

&lt;p&gt;It is okay for practical purposes. However, sometimes this leads to unwanted consequences. For example, dynamic importing a module that exports any &lt;code&gt;then&lt;/code&gt; function will call it and do something unpredictable. &lt;/p&gt;

&lt;p&gt;Considering generators are enough for Promises and Iterators one may wonder why we need Async Generators. Indeed it is pretty easy to convert monad combining the two effects from plain generators. However, there won’t be any replacement &lt;code&gt;for await-of&lt;/code&gt; statement. It is yet another syntax sugar for traversal.&lt;/p&gt;

&lt;p&gt;Coroutines/Iterables cannot define be converted to any monad. For example, Observable is a monad, but generators cannot be used as a do-notation for them.&lt;/p&gt;

&lt;p&gt;Another useful example is non-determinism. I.e. a computation returning several values. This can be used for embedding logical programming into JavaScript. It is simple to make an implementation for the abstract interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nonDet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&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;yield&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are libraries defining abstract APIs with a few concrete implementations in JavaScript, e.g. &lt;a href="https://github.com/fantasyland/fantasy-land"&gt;fantasy-land&lt;/a&gt;. There are also a few do notation as generators implementations trying to simulate multiple resumes by restarting and replaying iterators for the beginning example - &lt;a href="https://github.com/pelotom/burrido"&gt;burrido&lt;/a&gt;. The approach is not safe and not efficient.&lt;/p&gt;

&lt;p&gt;There is an alternative single-layered way. React uses it for Suspense for data fetching and Hooks. I described this in more details in &lt;a href="https://dev.to/awto/react-suspense-is-to-a-monad-as-hooks-are-to-applicative-notation-4c8h"&gt;React Suspense is to a Monad as Hooks are to Applicative Notation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I now work on a babel plugin based implementation for do-syntax working for any Monad — &lt;a href="https://github.com/awto/effectfuljs"&gt;EffectfulJS&lt;/a&gt;. It offers many options, like persistent state, concrete implementation inlining, implicit parallelization. This may significantly simplify JavaScript code. I’m going to write more about it soon, stay tuned!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
      <category>programming</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Why abstract interface for effects matters</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Mon, 31 Aug 2020 10:26:13 +0000</pubDate>
      <link>https://dev.to/awto/why-abstract-interface-for-effects-matters-ddp</link>
      <guid>https://dev.to/awto/why-abstract-interface-for-effects-matters-ddp</guid>
      <description>&lt;p&gt;JavaScript recently received three new computational effects kinds. There are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generator functions&lt;/li&gt;
&lt;li&gt;async functions&lt;/li&gt;
&lt;li&gt;async generator functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latest is a combination of the first two. If at some point JavaScript gets some other effect extension in syntax it will have to have seven language extensions for each combination, and so on. This may be, for example, recently added in runtime Observable effects for reactive programming. It may get own syntax extension sooner or later.&lt;/p&gt;

&lt;p&gt;Async generators extension, isn’t without problems. There is no way now to cancel async computation in JS now. This means it is impossible to combine async iterators as easily as Observables without introducing leaks. There is a proposal to add the cancellation, but it is still on too early stage and will probably take years. Alternatively, you may use &lt;a href="https://effectful.js.org/"&gt;Effectful.js&lt;/a&gt; immediately without waiting.&lt;/p&gt;

&lt;p&gt;Libraries should be ready for abstract interface too. For example, higher order functions, like Array traversal functions (&lt;code&gt;Array#map&lt;/code&gt;, &lt;code&gt;Array#forEach&lt;/code&gt;, etc.). Say, we have a function duplicating elements implemented as a simple generator function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&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;We cannot just copy-paste the body of the loop into, say, &lt;code&gt;forEach&lt;/code&gt; body like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&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;To make a fully general library we need four versions of &lt;code&gt;Array#forEach&lt;/code&gt;, and each other higher order function: &lt;code&gt;Array#map&lt;/code&gt;, &lt;code&gt;Array#filter&lt;/code&gt;, etc. Say, filter predicate may need to consult some remote service and so it should be async.&lt;br&gt;
It is even worse if the task like AST transforms with a significant number of nodes and Visitors written for traversal. To make a generic library there should be four versions of visitor types again.&lt;/p&gt;

&lt;p&gt;There is an abstract interfaces for effects, for example Monads. Only one implementation for the functions above is needed if it uses such abstract interface to build result.&lt;/p&gt;

&lt;p&gt;The Monad interface came from math, namely category theory. &lt;br&gt;
Its only purpose was an abstraction. Theorems proved using abstract monads interface may be immediately applied to likely also abstract but more concrete interface instances, like some structures from universal algebra or topology. Mathematicians refactored math frameworks by abstracting common things into Category Theory and Monad as a part of it.&lt;/p&gt;

&lt;p&gt;Later the interface was utilized to describe and reason about programming languages with effects in domains theory. The same purpose again, simplifying reasoning about programming languages and programs.&lt;/p&gt;

&lt;p&gt;After, Monads reached practical programming languages. Other researchers worked on programming languages with only pure functions to simplify reasoning about programs. Unfortunately having only pure function requires threading functions parameters and results, result statuses, etc. This makes programs very verbose and hard to read. The problem was solved by applying Monads. Imperative code with a mutable state, exceptions can be converted into a pure function.&lt;/p&gt;

&lt;p&gt;Applying &lt;a href="https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence"&gt;Curry–Howard correspondence&lt;/a&gt;, where programming language types are theorems, and programs are their proofs, Monads are abstract API. So like in math, proved theorems with some general math structure may be applied to any concrete realization of that structure. In programming languages, a function using abstract type for arguments objects may be invoked with any concrete implementation of that object.&lt;/p&gt;

&lt;p&gt;There are many different options in choosing names for interface functions, or a set of basis functions, or split it into a hierarchy of other abstract notions somehow. There are a few libraries in JavaScript already defining the interface and providing a few of its implementations. Like fantasy-land.&lt;br&gt;
&lt;a href="https://effectful.js.org/"&gt;Effectful.js&lt;/a&gt; compiler uses own interface, but it may be adapted to any other either by implementing wrappers or inlining calls to other methods. It doesn’t introduce any syntax extensions, but can overload JavaScript ones, e.g., generators or await/async syntax to generalize them.&lt;/p&gt;

&lt;p&gt;Many custom effects or changes/fixes for ECMAScript can be applied immediately without awaiting committee for years. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cancelation to async functions, thus making async iterators compasable&lt;/li&gt;
&lt;li&gt;improve performance (drop some not-efficient and useless standard feature, remove JavaScript engine scheduler from async iterator)&lt;/li&gt;
&lt;li&gt;persistent state (time traveling, distributed apps, workflows)&lt;/li&gt;
&lt;li&gt;non-deterministic programming (bind form’s data as logical formulas, reactive programming)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
    <item>
      <title>Decouple Business Logic using Async Generators</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Mon, 31 Aug 2020 10:10:46 +0000</pubDate>
      <link>https://dev.to/awto/decouple-business-logic-using-async-generators-1kho</link>
      <guid>https://dev.to/awto/decouple-business-logic-using-async-generators-1kho</guid>
      <description>&lt;p&gt;Async generators are new in JavaScript, and I believe it is a very remarkable extension. It provides a simple but powerful tool for splitting programs into smaller parts, making sources easier to write, read, maintain and test.&lt;/p&gt;

&lt;p&gt;The article shows this using an example. It implements a typical front-end component, namely drag and drop operations. The same technique is not limited to front-ends. It is hard to find where it cannot be applied. I use the same in two big compiler projects, and I’m very excited how much it simplifies there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hspoK9ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x2ah35d4tnah38dbteaf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hspoK9ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x2ah35d4tnah38dbteaf.gif" alt="Drag and Drop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can drag boxes from a palette in the top and drop into any of gray areas. Each drop area has its specific actions. A few items can be selected. Yellow ones have inertial movement.&lt;br&gt;
All the features are independent there. They are split into stages. Some stages compute information shared by a few features. This does introduce some dependency, but can be surely avoided or controlled. All the features are simple to enable, disable, develop, test and debug separately. A few developers or teams could work on it in parallel very efficiently.&lt;/p&gt;

&lt;p&gt;I assume some basic knowledge of async generators (or at least of async functions and generators separately) and some fundamentals of HTML DOM (at least knowing what it is). There are no dependencies on third-party JavaScript libraries&lt;br&gt;
For the demo, let’s pretend we don’t know full requirements set and add new a feature only after we finish something and it works. Playing with already working software on intermediate stages typically boosts creativity. It is one of the main components of the agile software development core. I’d better write something not perfectly designed but working first. We can improve it using refactoring any time. Async generators will help.&lt;/p&gt;

&lt;p&gt;Typically, at the beginning of any project, I don’t want to spend time on choosing the right framework, library or even an architecture. I don’t want to overdesign. With the help of async iterators, I can delay the hard decisions to a point where I have enough knowledge to make a choice. The earlier I take some option, the more chances there are for mistakes. Maybe I won’t need anything at all.&lt;/p&gt;

&lt;p&gt;I’ll describe a couple of steps only here. The other steps are small and can be read directly from code effortlessly. They are just a matter of working with DOM, not a subject of the article. Unlike the transpiled final demo above, the demos in fiddles below work only in a browser supporting async generators. These are, for example, Chrome 63, Firefox 57. First examples also use pointer events polyfill, replaced in the last example.&lt;/p&gt;
&lt;h1&gt;
  
  
  Async generators
&lt;/h1&gt;

&lt;p&gt;All the samples share nano-framework sources. It is developed once, at the beginning and copy-pasted without any change. In the real project, these are separate modules, imported into other modules if needed. The framework does one thing. It converts DOM events into async iterator elements.&lt;br&gt;
Async iterator has the same next method like ECMAScript plain iterator, but it returns a Promise resolving to Objects with value, done fields.&lt;/p&gt;

&lt;p&gt;Async generator functions is an extended function returning an async iterator. Like original non-async generator is a function returning a non-async iterator.&lt;/p&gt;

&lt;p&gt;Async generators combine async functions and generator functionality. In the bodies of such functions, we can use await together with yield expressions, and they do exactly what these expressions do in async functions and generators respectively. Namely suspends execution control until Promise in await argument is resolved and for yield outputs value and suspends until caller requests next value.&lt;/p&gt;

&lt;p&gt;Here’s preliminary framework implementation, with the first version of business logic:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/afjs2467//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;It is a working sample, press &lt;em&gt;Result&lt;/em&gt; there to see it in action. There are four elements you can drag within the page. The main components are &lt;code&gt;send&lt;/code&gt;, &lt;code&gt;produce&lt;/code&gt; and &lt;code&gt;consume&lt;/code&gt; transducers. The application subscribes to DOM events and redirects them into the framework using send function. The function converts the arguments into elements of async iterator returned by &lt;code&gt;produce&lt;/code&gt; call. The iterator never ends and called at a module’s top level.&lt;/p&gt;

&lt;p&gt;There is &lt;code&gt;for(;;)&lt;/code&gt; loop in &lt;code&gt;produce&lt;/code&gt;. I know it looks suspicious, you may even have it denied in your team code review checklist or event by some lint rule, since for code readability we want exit condition for loops to be obvious. This loop should never exit, it is supposed to be infinite. But it doesn’t consume CPU cycles since most of the time it will sleep in awaitand yield expressions there.&lt;/p&gt;

&lt;p&gt;There is also &lt;code&gt;consume&lt;/code&gt; function. It reads any async iterator in its argument, doing nothing with the elements, never returning. We need it to keep our framework running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&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;It is an async function (not generator), but it uses new &lt;code&gt;for-await-of&lt;/code&gt; statement, an extension of &lt;code&gt;for-of&lt;/code&gt; statement. It reads async iterators, rather than original ECMAScript iterator, and awaits each element. Its simplified implementation could transpile the original &lt;code&gt;consume&lt;/code&gt; code into something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncIterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;
    &lt;span class="k"&gt;for&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;i&lt;/span&gt;&lt;span class="p"&gt;;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;iter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;done&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;The &lt;code&gt;main&lt;/code&gt; function is an entry point of the application’s business logic. The function is called between &lt;code&gt;produce&lt;/code&gt; and &lt;code&gt;consume&lt;/code&gt; in the module’s top level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is also a small share function. We need it to use the same iterator in a few &lt;code&gt;for-await-of&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;The first monolithic version of business logic is fully defined in &lt;code&gt;main&lt;/code&gt;. With the example, you can already see the power of async generators. The application state (where we started dragging — &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; variables) are local variables, encapsulated inside the function. Besides data state, there is also execution control state. It is a kind of implicit local variable storing position where the generator is suspended (either on &lt;code&gt;await&lt;/code&gt; or &lt;code&gt;yield&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The same function could be rewritten without generators, for example into something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;main&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="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&lt;/span&gt;&lt;span class="dl"&gt;"&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;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;read&lt;/span&gt;&lt;span class="dl"&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;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop1&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;i&lt;/span&gt; &lt;span class="o"&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;value&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;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;pointerdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&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;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&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;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.draggable&lt;/span&gt;&lt;span class="dl"&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;element&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;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBoundingClientRect&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageXOffset&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageYOffset&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&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;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop2&lt;/span&gt;&lt;span class="dl"&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;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;read&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&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;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop1&lt;/span&gt;&lt;span class="dl"&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;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;yield&lt;/span&gt;&lt;span class="dl"&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop2&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;j&lt;/span&gt; &lt;span class="o"&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;value&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;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;pointerup&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;pointermove&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&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;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&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;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&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;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&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;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;yield&lt;/span&gt;&lt;span class="dl"&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;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop1&lt;/span&gt;&lt;span class="dl"&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;
      &lt;span class="k"&gt;return&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;It is much more verbose comparing to &lt;code&gt;main&lt;/code&gt; function in the original version, isn’t it? It is also less readable, the execution control isn’t clear. It is not immediately seen how execution control reaches some state.&lt;/p&gt;

&lt;p&gt;There are quite a few other implementation options. For example, instead of switch statement we could use callbacks for the control state, we also could use closures to store the state, but that won’t change much. To run the function, we also need a framework. It interprets the action the function demands to execute (&lt;code&gt;"read"&lt;/code&gt;, &lt;code&gt;"yield"&lt;/code&gt; in the example), compose the stages, etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Splitting
&lt;/h1&gt;

&lt;p&gt;The size of the function and no framework requirements are not the only advantages of async generators. The real magic begins when we combine them.&lt;/p&gt;

&lt;p&gt;The most often used function combination is their composition, say for function &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; this is &lt;code&gt;a =&amp;gt; f(g(a))&lt;/code&gt;. The composition doesn’t need any framework. It is a JavaScript expression.&lt;/p&gt;

&lt;p&gt;If we compose two plain functions, the second function starts doing its job only after the first one exists. If they are generators, both functions run simultaneously.&lt;/p&gt;

&lt;p&gt;A few composed generator functions make a pipeline. Like in any manufacture, say cars, splitting jobs into a few steps using an assembly line significantly increases productivity. Similarly, in the pipeline based on async generators, some function may send messages to the next using values its result iterator yields. The following function may do something application specific depending on a content of the message or pass it to the next stage.&lt;/p&gt;

&lt;p&gt;These functions are the component of business logic. More formally it is any JavaScript function, taking async iterator as its parameter and returning another async iterator as a result. In most cases, this will be async generator function, but not necessary. Someone may create some combinator functions building resulting object with async iterator interface manually.&lt;/p&gt;

&lt;p&gt;There are many names commonly in use for such functions now. For example Middleware, Epic, etc., I like name Transducer more and will use it in the article.&lt;/p&gt;

&lt;p&gt;Transducers are free to do whatever they want with the input stream. Here are examples of what transducers can do on some message arrival:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pass through to the next step (with &lt;code&gt;yield i&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;change something in it and pass next (&lt;code&gt;yield {…i,one:1}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;generate a new message (yield {type:”two”,two:2})&lt;/li&gt;
&lt;li&gt;don’t yield anything at all thus filtering the message out&lt;/li&gt;
&lt;li&gt;update encapsulated state (local variables) based on the message field values&lt;/li&gt;
&lt;li&gt;buffer the messages in some array and output on some condition (&lt;code&gt;yield* buf&lt;/code&gt;), e.g., delaying drag start to avoid false response&lt;/li&gt;
&lt;li&gt;do some async operations (&lt;code&gt;await query()&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Transducers mostly listen for incoming messages on &lt;code&gt;for-await-of&lt;/code&gt; loops. There may be a few of such loops in a single transducer body. This utilizes execution control state to implement some business logic requirements.&lt;/p&gt;

&lt;p&gt;Let’s see how it works. Let’s split the monolithic &lt;code&gt;main&lt;/code&gt; function from the above sample into two stages. One convert DOM events into drag and drop messages — &lt;code&gt;makeDragMessages&lt;/code&gt; (types &lt;code&gt;"dragstart"&lt;/code&gt;, &lt;code&gt;"dragging"&lt;/code&gt;, &lt;code&gt;"drop"&lt;/code&gt;) and other updates DOM positions — &lt;code&gt;setPositions&lt;/code&gt;. The &lt;code&gt;main&lt;/code&gt; function is just a composition of them two.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/ms9txpuq//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I split the program here because I want to insert some new message handlers between them. The same way when writing new software I wouldn’t focus too much on how to split the code correctly before I understand why I need this. It should satisfy some reasonable size constraint. They also must be separated on logically different features.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function there is actually a transducer too (takes async iterators returns async iterator). It is an example of a transducer which is not an async generator itself. Some larger application may inject &lt;code&gt;main&lt;/code&gt; from this module into other pipelines.&lt;/p&gt;

&lt;p&gt;This is the final version of the nano-framework. Nothing is to be changed there regardless what new features we add. The new features are function specified somewhere in the chain in &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  First features
&lt;/h1&gt;

&lt;p&gt;Now back to the new features. We want to do something else. Not just dragging something on a page. We have special message names for dragging (&lt;code&gt;"dragstart"&lt;/code&gt;, &lt;code&gt;"dragging"&lt;/code&gt;, &lt;code&gt;"drop"&lt;/code&gt;). Next transducers can use them instead of mouse/touch events. For example, anytime next we can add a keyboard support, changing nothing for this.&lt;/p&gt;

&lt;p&gt;Let’s make some mean to create new draggable items, some area where we can drag them from, and something to remove them. We’ll also flavor it with animation on dropping an item on trash area or outside of any area.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/Lrn10smc//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;First, everything starts with palette transducer. It detects drag start on one of its element, clones it into a new element and replaces all the original dragging event after with the clone. It is absolutely transparent for all the next transducers. They know nothing about the palette. For them, this is like another drag operations of existing element.&lt;br&gt;
Next &lt;code&gt;assignOver&lt;/code&gt; transducer does nothing visible for end-user, but it helps next transducers. It detects HTML element a user drags an item over adds it to all messages using over property. The information is used in trash and in &lt;code&gt;validateOver&lt;/code&gt; transducers to decide if we need to remove the element or cancel drag. The transducers don’t do that themselves but rather send &lt;code&gt;"remove"&lt;/code&gt; or &lt;code&gt;"dragcancel"&lt;/code&gt; messages to be handled by something next. Cancel message is converted to &lt;code&gt;"remove"&lt;/code&gt; by &lt;code&gt;removeCancelled&lt;/code&gt;. And &lt;code&gt;"remove"&lt;/code&gt; messages are finally handled in &lt;code&gt;applyRemove&lt;/code&gt; by removing them from DOM.&lt;/p&gt;

&lt;p&gt;By introducing another message types, we can inject new features implementations in the middle without replacing anything in the original code. In this example it is animation. On &lt;code&gt;"dragcancel"&lt;/code&gt; the item moves back to original position, and on &lt;code&gt;"remove"&lt;/code&gt; its size is reduced to zero. Disabling/enabling animation is just a matter of removing/inserting transducers at some specific position.&lt;br&gt;
The animation will continue to work if something else generates &lt;code&gt;"dragcancel"&lt;/code&gt; or &lt;code&gt;"remove"&lt;/code&gt;. We may stop thinking about where to apply it. Our business logic becomes more and higher level.&lt;/p&gt;

&lt;p&gt;The animation implementation also utilizes async generators but not in the form of transducers. This is a function returning values from zero to one in animation frames with specified delay, default to 200ms. And the caller function uses it in whatever way it likes. Check for the demo &lt;code&gt;animRemove&lt;/code&gt; function in the fiddle above.&lt;/p&gt;

&lt;p&gt;Many other animation options are simple to add. The values may be not linear but output with some spline function. Or it may be based not on delay but on velocity. This is not significant for functions invoking &lt;code&gt;anim&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Multi-select
&lt;/h1&gt;

&lt;p&gt;Now let’s add incrementally another feature. We start from scratch, from the nano-framework. We will merge all the steps in the end effortlessly. This way the code from the previous step will not interfere with the new development. It is much easier to debug and write tests for it. There are no unwanted dependencies as well.&lt;/p&gt;

&lt;p&gt;The next feature is a multi-select. I highlight it here because it requires another higher order function combination. But at first, it is apparently straightforward to implement. The idea is to simulate drag messages for all selected elements when a user drags one of it.&lt;/p&gt;

&lt;p&gt;Implementation is very simple but it breaks the next steps in the pipeline. Some transducers (like &lt;code&gt;setPosition&lt;/code&gt;) expect exact messages sequence. For a single item, there should be &lt;code&gt;"dragstart"&lt;/code&gt; followed by a few &lt;code&gt;"dragging"&lt;/code&gt; and a &lt;code&gt;"drop"&lt;/code&gt; in the end. This is no longer true.&lt;/p&gt;

&lt;p&gt;A user drags a few elements at the same time. So there’ll be messages now for several elements simultaneously. There is only one start coordinate in &lt;code&gt;setPosition&lt;/code&gt; &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; local variables. And its control flow is defined only for one element. After &lt;code&gt;"dragstart"&lt;/code&gt; it is in the nested loop. It doesn’t recognize any next &lt;code&gt;"dragstart"&lt;/code&gt; until exiting that loop on &lt;code&gt;"drop"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem can be solved by resorting to storing state, including a control state, in some map for each element currently dragging. This would obviously break all async generator advantages. I have also promised there are no changes to the nano-framework. So it is not the solution.&lt;/p&gt;

&lt;p&gt;What we need here is to run transducers expecting to work with a single element in a kind of a separate thread. There is a &lt;code&gt;byElement&lt;/code&gt; function for this. It multiplexes input into a few instances of a transducer passed as its argument. The instances are created by calling the transducer in argument supplying it filtered source iterator. Each source for each instance outputs only messages with the same element field. The outputs of all the instances are merged back into one stream. All we need to do is to wrap transducers with &lt;code&gt;byElement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/pykuduLf//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;First, it converts DOM events into application-specific messages in &lt;code&gt;makeSelectMessages&lt;/code&gt;. The second step adds selection indicator and highlight selected items after selection ended in selectMark. Nothing is new in the first two. The third transducer checks if a user drags a highlighted item, it gets all other highlighted items and generates drag and drop messages for each of them in &lt;code&gt;propagateSelection&lt;/code&gt;. Next &lt;code&gt;setPosition&lt;/code&gt; runs in a thread per each element.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final result
&lt;/h1&gt;

&lt;p&gt;After the multi-selection feature is implemented it is implemented once and for everything. All we need to change is to add it to &lt;code&gt;main&lt;/code&gt; and correctly wrap other transducers with &lt;code&gt;byElement&lt;/code&gt; if needed. This may be done either in &lt;code&gt;main&lt;/code&gt; or in a module where the transducers are imported from.&lt;/p&gt;

&lt;p&gt;Here is the fiddle with the final demo with all the features merged:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/awto/up398xzh//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;All the transducers are in fact very lightweight thread. Unlike real threads they are deterministic but they use non-deterministic DOM events as a source. So they must be considered non-deterministic as well.&lt;/p&gt;

&lt;p&gt;This makes all the typical problems of multi-threaded environments possible, unfortunately. These are racings, deadlocks, serializations, etc. Fortunately, they are simple to avoid. Just don’t use mutable shared data.&lt;/p&gt;

&lt;p&gt;I violate this constraint in the demo by querying and updating DOM tree. It doesn’t lead to problems here, but in the real application, it is something to care about. For fixing this, some initial stage may read everything needed from a DOM and pack into messages. The final step may perform some DOM updates based on messages received. This may be some virtual DOM render, for example.&lt;/p&gt;

&lt;p&gt;Communicating with the messages only allows isolating the thread even more. This may be Web Worker, or even a remote server.&lt;/p&gt;

&lt;p&gt;But again, I wouldn’t worry before it became a problem. Thanks to async iterators, the program is a set of small, isolated and self-contained components. It is straightforward to change anything when (if) there is any problem.&lt;/p&gt;

&lt;p&gt;The technique is compatible with other design techniques. It will work for OOP or FP. Any classic design pattern applies. When &lt;code&gt;main&lt;/code&gt; function grows big, we can add some dependency injection to manage the pipeline, for example.&lt;/p&gt;

&lt;p&gt;In the example &lt;code&gt;byElement&lt;/code&gt; calls abstract &lt;code&gt;threadBy&lt;/code&gt;. In practice, you’ll have more and more such abstract utilities. I wrote a concrete implementation for grouping streams by element, and only after abstracted it. It was very simple, as the concrete implementation was very small.&lt;/p&gt;

&lt;p&gt;The technique reduces worrying about application’s architectures. Only write a specific transducer for each feature you need to implement. Abstract common parts into stand-alone transducers. Split it into a few if something else is to be done in the middle. Generalize some parts into abstract reusable combinators only when(if) you have enough knowledge for this.&lt;/p&gt;

&lt;h1&gt;
  
  
  Relation to other libraries
&lt;/h1&gt;

&lt;p&gt;If you are familiar with node-streams or functional reactive libraries such as &lt;a href="http://reactivex.io/rxjs/"&gt;RxJS&lt;/a&gt;, you could already spot many similarities. They use different stream interfaces.&lt;/p&gt;

&lt;p&gt;Transducers don’t require to be async generators as well. It is just a function taking a stream and returning another stream regardless of what interface the stream has. Same technique to split business logic may be applied to any other stream interfaces. Async generators just provide excellent syntax extension for them.&lt;/p&gt;

&lt;p&gt;Someone familiar with &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt; may notice messages handlers are very similar to middlewares or reducers composition. Async iterator can be converted into Redux middleware as well. Something like, for example, is done in &lt;a href="https://github.com/redux-observable/redux-observable"&gt;redux-observable&lt;/a&gt; library but for different stream interface.&lt;/p&gt;

&lt;p&gt;Though, this violates &lt;a href="https://redux.js.org/docs/introduction/ThreePrinciples.html"&gt;Redux principles&lt;/a&gt;. There is no longer a single storage now. Each async generator has its own encapsulated state. Even if it doesn’t use local variables the state is still there, it is the current control state, position in the code where the generator was suspended. The state is also not serializable.&lt;/p&gt;

&lt;p&gt;The framework fits nicely with the Redux underlying patterns though, say, &lt;a href="https://martinfowler.com/eaaDev/EventSourcing.html"&gt;Event Sourcing&lt;/a&gt;. We can have a specific kind of messages propagating some global state diffs. And transducers can react accordingly, probably updating their local variables if needed.&lt;/p&gt;

&lt;p&gt;The name, transducer, is typically associated with &lt;a href="https://clojure.org/reference/transducers"&gt;Clojure style transducers&lt;/a&gt; in JavaScript world. Both are the same things on a higher level. They are again just transformers of stream objects with different interfaces. Though Clojure transducers transform stream consumers, async iterator transducers from this article transform stream producers. A bit more details are in &lt;a href="https://dev.to/awto/simpler-transducers-for-javascript-3ibl"&gt;Simpler Transducers for JavaScript&lt;/a&gt; article.&lt;/p&gt;

&lt;p&gt;We could transform consumer in async iterators as well, by transforming arguments arrived in &lt;code&gt;next&lt;/code&gt;/&lt;code&gt;throw&lt;/code&gt;/&lt;code&gt;return&lt;/code&gt; methods of iterators. In this case, we won’t be able to utilize &lt;code&gt;for-await-of&lt;/code&gt; though, and there are no evident benefits.&lt;/p&gt;

&lt;h1&gt;
  
  
  Extensions
&lt;/h1&gt;

&lt;p&gt;I now work on &lt;a href="https://github.com/awto/effectfuljs"&gt;a transpiler for embedding effects&lt;/a&gt; in JavaScript. It can handle ECMAScript async, generators and async generators function syntax extensions to overload default behavior.&lt;/p&gt;

&lt;p&gt;In fact, the transpiled demo above was built with it. Unlike similar tools like regenerator, it is abstract. Any other effect can be seamlessly embedded in the language using a library implementing its abstract interface. This can significantly simplify JavaScript programs.&lt;/p&gt;

&lt;p&gt;At the moment there are libraries only for standard effects implementation. There’ll be more soon.&lt;/p&gt;

&lt;p&gt;For example, possible applications are faster standard effects, saving current execution to a file or DB and restore on a different server or recover after hardware failure, move control between front-end and back-end, on changing input data re-execute only relevant part of the program, use transactions, apply logical programming techniques, even Redux principles for async generators may be recovered.&lt;/p&gt;

&lt;p&gt;The compiler implementation itself uses the technique described in the article. It uses non-async generators since it doesn’t have any async messages source. The approach significantly simplified the previous compiler version done with Visitors. It now has almost a hundred options. Their implementation is almost independent, it is still simple to read and extend.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>architecture</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Simpler Transducers for JavaScript</title>
      <dc:creator>Vitaliy Akimov</dc:creator>
      <pubDate>Mon, 31 Aug 2020 10:10:30 +0000</pubDate>
      <link>https://dev.to/awto/simpler-transducers-for-javascript-3ibl</link>
      <guid>https://dev.to/awto/simpler-transducers-for-javascript-3ibl</guid>
      <description>&lt;p&gt;Developers often want to split computations into several separate stages. The smaller the stage, the easier it is to reason, develop and maintain. For example we split some computation into 3 stages in functions &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt; with resulting one is &lt;code&gt;input =&amp;gt; f(g(k(input)))&lt;/code&gt; or using &lt;a href="https://ramdajs.com"&gt;Ramda&lt;/a&gt; &lt;code&gt;R.comp(f,g,k)&lt;/code&gt; or any other library with function composition operator.&lt;/p&gt;

&lt;p&gt;The problem with this approach is intermediate data passed between functions, and each sub-stage should finish its computation completely before passing the result to next stage. The data size they operate with may be large or even infinite if it is some server requests stream. In a case of unlimited data k will never return control. As it is often occurring task, there are many solutions, like nodejs streams with their &lt;code&gt;.pipe()&lt;/code&gt; operation adding stream transformer to the chain.&lt;/p&gt;

&lt;p&gt;The worse approach would be to pass a single value between the stages and mutate it. It is very difficult to reason about shared data mutation especially if it is some recursive structure, like programming language abstract syntax tree.&lt;br&gt;
Transducers described in this post may be seen as a simpler solution to the problem, working simultaneously, no intermediate data, no data mutations.&lt;/p&gt;

&lt;p&gt;Transducers are easy to compose. In fact they are just functions and function composition is just enough, the expressions above (&lt;code&gt;input =&amp;gt; f(g(k(input)))&lt;/code&gt; and &lt;code&gt;R.comp(f,g,k)&lt;/code&gt;) are the same for transducers. The resulting transducer is a pipeline of computations receiving data from producer and passing it to consumer. Producer and consumer may do many things, read/write network data, file, DB, or just in-memory array.&lt;/p&gt;

&lt;p&gt;The term transducers became popular after introducing them in Clojure in &lt;a href="http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming"&gt;Transducers are coming&lt;/a&gt; blog post and ported to JavaScript by a few libraries including Ramda. Clojure style transducers are different to the ones described in this post. They transform consumers, which are called reducers in Clojure. Unlike these transducers which transform producers. This distinction makes them much simpler to define in use in ES6 because of generator functions.&lt;/p&gt;

&lt;p&gt;Clojure transducers type from the original blog post is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="c1"&gt;;;reducing function signature&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;whatever,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whatever&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;;;transducer signature&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;whatever,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whatever&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;whatever,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whatever&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;There is an earlier paper with the example of transducers transforming producers instead of consumers: &lt;a href="http://okmij.org/ftp/continuations/PPYield/yield-pp.pdf"&gt;Lazy v. Yield: Incremental, Linear Pretty-printing in Haskell&lt;/a&gt;. And data types there are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;GenT&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ReaderT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="nb"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Producer&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;GenT&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Consumer&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Transducer&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Producer&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Producer&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To see Consumer there is a reducer from Clojure substitute &lt;code&gt;State e a = s -&amp;gt; m (a, s)&lt;/code&gt; into Consumer definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Consumer (State whatever) input
= input -&amp;gt; State whatever ()
= input -&amp;gt; whatever -&amp;gt; ((), whatever)
= whatever, input -&amp;gt; whatever
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Producer in the paper has a more complex type. Haskell doesn’t have embedded generators. &lt;/p&gt;

&lt;p&gt;Fortunately, JavaScript now has. Producers are just any Iterable value. It may be some in-memory array or any generator function. Consumer is a function taking Iterable value and interpreting it somehow, for example by saving results to file, or JavaScript standard &lt;code&gt;Array.from&lt;/code&gt; function stores result in in-memory Array. The approach will work even if the sequence is infinite.&lt;/p&gt;

&lt;p&gt;Transducers take input Producer (Iterator) along with other optional parameters and return another Producer-iterator with another computation stacked on top of it.&lt;/p&gt;

&lt;p&gt;A typical pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;myFun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// local variable storing this transducer's internal state&lt;/span&gt;
  &lt;span class="c1"&gt;// state with initial values&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// use the current value of `i` along with the current&lt;/span&gt;
    &lt;span class="c1"&gt;// state `sum` to compute its next output value `o`&lt;/span&gt;
    &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&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;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;o&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 example map function applying a function to each element is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;Or &lt;code&gt;filter&lt;/code&gt;, passing further only elements satisfying some predicate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&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;Taking first &lt;code&gt;num&lt;/code&gt; element is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;num&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next is a more complex &lt;code&gt;chunk&lt;/code&gt; function. It receives stream of arrays of arbitrary length, and partition them into arrays of fixed &lt;code&gt;size&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;buf&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="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Hierarchical data may be handled as well; an example is &lt;a href="https://github.com/awto/effectfuljs/tree/master/packages/transducers"&gt;@effectful/transducer&lt;/a&gt; project for JavaScript syntax transformation.&lt;/p&gt;

&lt;p&gt;But everything is not this simple if there is an asynchronous code at some stage. Likely this is required in Producer because IO in JavaScript is typically asynchronous. It is possible to call &lt;code&gt;next&lt;/code&gt; of an iterator in an asynchronous callback, but not &lt;code&gt;yield&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Recently EMCAScript has got async generators and &lt;code&gt;for await-of&lt;/code&gt; syntax extension for this. Everything in this story works for async generators too, except &lt;code&gt;for-of&lt;/code&gt; is replaced by &lt;code&gt;for await-of&lt;/code&gt;. There is a more detailed case study for async generators as transducers in &lt;a href="https://dev.to/awto/decouple-business-logic-using-async-generators-1kho"&gt;“Decouple Business Logic Using Async Generators”&lt;/a&gt; article.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>computerscience</category>
      <category>functional</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
