<?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: Ryo Hirayama</title>
    <description>The latest articles on DEV Community by Ryo Hirayama (@ryo33).</description>
    <link>https://dev.to/ryo33</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F41301%2Fe14bde4a-640e-4fe1-a63f-858a56f419fb.png</url>
      <title>DEV Community: Ryo Hirayama</title>
      <link>https://dev.to/ryo33</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ryo33"/>
    <language>en</language>
    <item>
      <title>For Macro Lovers: Could Tauto Have the World's Most Powerful Macro System?</title>
      <dc:creator>Ryo Hirayama</dc:creator>
      <pubDate>Tue, 03 Nov 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/ryo33/for-macro-lovers-could-tauto-have-the-worlds-most-powerful-macro-system-2ioh</link>
      <guid>https://dev.to/ryo33/for-macro-lovers-could-tauto-have-the-worlds-most-powerful-macro-system-2ioh</guid>
      <description>&lt;p&gt;Tauto combines a dependently typed proof system with a runtime featuring algebraic effects and ownership. This article introduces its &lt;strong&gt;macro system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;“The world's most powerful” is a bold claim for a title. The aim is to bring everything I want from macros into a single design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new syntax and DSLs as libraries, complete with registered formatters and syntax highlighting.&lt;/li&gt;
&lt;li&gt;Write macros that transform code based on its types and macros that build proofs, called tactics, using the same mechanism.&lt;/li&gt;
&lt;li&gt;Keep expansion hygienic, so macros do not capture the caller's variables.&lt;/li&gt;
&lt;li&gt;Run untrusted macros without giving them file access, without unbounded execution, and without compromising proof soundness.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/Hihaheho/tauto" rel="noopener noreferrer"&gt;Tauto on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Macros are ordinary functions that return syntax values&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Macro kinds and when to use them&lt;ul&gt;
&lt;li&gt;
Syntax macros: write in your own grammar&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Untyped macros: reinterpret an expression&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Typed macros: inspect types and context&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Tactics: macros that construct proofs&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Attribute macros: generate declarations&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Why list generated declarations?&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Hygiene: macros do not capture the caller's names&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Using effect analysis to contain macro execution&lt;ul&gt;&lt;li&gt;

What about infinite loops?&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

A powerful syntax-macro system&lt;ul&gt;

&lt;li&gt;

Write a grammar, get a typed AST and parser&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Left recursion: LL(k) and LALR(1)&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Syntax errors report locations and expectations&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Registering formatters and syntax highlighting&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Embedding Tauto expressions in a grammar&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Build and prove a language implementation&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

More useful properties&lt;ul&gt;

&lt;li&gt;

Every expansion can be traced&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Typed macros do not change the declaration environment&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Write typing judgments in a DSL&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Macro execution is ordered by file&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Deliberate restrictions&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Design priorities&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

What is not guaranteed&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Summary&lt;ul&gt;&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Macros are ordinary functions that return syntax values
&lt;/h2&gt;

&lt;p&gt;Tauto macros are &lt;strong&gt;ordinary functions&lt;/strong&gt; , rather than programs in a separate macro or template language. They take and return syntax values, represented by AST data types such as &lt;code&gt;SynExpr&lt;/code&gt; and &lt;code&gt;SynStmt&lt;/code&gt;, assembled with &lt;code&gt;quote { … }&lt;/code&gt; and &lt;code&gt;$x&lt;/code&gt;. Calls are always explicit: &lt;code&gt;NAME!(…)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Whatever a macro produces, the expanded program goes through the same path as a handwritten program: the kernel and a second, independently implemented kernel. You do not need to trust the macro's generation logic to preserve type or proof soundness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Macro kinds and when to use them
&lt;/h2&gt;

&lt;p&gt;There are four kinds of macros. &lt;strong&gt;The function's input type alone determines the kind.&lt;/strong&gt; There is no keyword such as &lt;code&gt;typed macro&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Syntax macro:&lt;/strong&gt; takes a typed AST generated from a grammar. Call it as &lt;code&gt;name!(&lt;/code&gt;…&lt;code&gt;)&lt;/code&gt; to introduce notation or a DSL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Untyped macro:&lt;/strong&gt; takes &lt;code&gt;SynExpr&lt;/code&gt;. Call it as &lt;code&gt;name!(a + b)&lt;/code&gt; to reinterpret an expression.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typed macro:&lt;/strong&gt; takes &lt;code&gt;Judgement&lt;/code&gt;. Call it as &lt;code&gt;name!(e)&lt;/code&gt; to transform code using its type and context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tactic:&lt;/strong&gt; takes &lt;code&gt;ProofStep&lt;/code&gt;. Call it as &lt;code&gt;by name!(…): G { … }&lt;/code&gt; to automate proofs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Syntax macros: write in your own grammar
&lt;/h3&gt;

&lt;p&gt;A syntax macro parses its input using a grammar declared with &lt;code&gt;syntax!&lt;/code&gt;. As an example, here is &lt;code&gt;swap!&lt;/code&gt;, which swaps two variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;syntax!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;swp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; ```
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;par&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;
&lt;span class="o"&gt;%%&lt;/span&gt;
&lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;\&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;\&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;\&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

```&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;swp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nf"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SynStmt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Syn&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ident&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Syn&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;ident&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.name_2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="n"&gt;stmts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&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 grammar lives in a fenced block tagged &lt;code&gt;par&lt;/code&gt;. It automatically generates a typed AST called &lt;code&gt;swp::Pair&lt;/code&gt;, which becomes the macro function's input.&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;=&amp;gt;&lt;/code&gt;, the source lists the exact kinds and names of the declarations that will be generated. You do not need to write these lists by hand: &lt;code&gt;tauto fmt --fill-generated main.taut&lt;/code&gt; fills in missing lists and corrects mismatched ones in that file and the files it imports, writing the results back to source.&lt;/p&gt;

&lt;p&gt;The list is required for &lt;code&gt;syntax!&lt;/code&gt;, &lt;code&gt;inductive_syntax!&lt;/code&gt;, attribute macros, and other declaration-generating calls. Generating an unlisted declaration is an error, as is listing a declaration that is not generated. “Why list generated declarations?” below explains why the list remains explicit in the source.&lt;/p&gt;

&lt;p&gt;Here is the caller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "swap.taut"
var tmp := 1
var other := 2
swap!(`tmp other`)
perform show("tmp", tmp)
perform show("other", other)


$ tauto macro expand main.taut
var tmp := 1
var other := 2
let tmp#1 := tmp
tmp := other
other := tmp#1
perform show("tmp", tmp)
perform show("other", other)

$ tauto run main.taut
tmp = 2
other = 1

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

&lt;/div&gt;



&lt;p&gt;The macro's temporary variable &lt;code&gt;tmp&lt;/code&gt; becomes &lt;code&gt;tmp#1&lt;/code&gt;, avoiding a collision with the caller's &lt;code&gt;tmp&lt;/code&gt;. The &lt;code&gt;#1&lt;/code&gt; is a display name; when &lt;code&gt;--write&lt;/code&gt; writes the expansion back to source, it becomes an ordinary name that does not collide. This illustrates the hygiene mechanism discussed below. You can inspect expansions at any time with &lt;code&gt;tauto macro expand&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The DSL inside the backtick fences can also have its own formatter and syntax highlighting. Register the functions with &lt;code&gt;with&lt;/code&gt; at the end of &lt;code&gt;syntax!&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;syntax!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;swp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; ```
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;par&lt;/span&gt;
…
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

```&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;swp_fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;swp_tokens&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;fmt&lt;/code&gt; is called when &lt;code&gt;tauto fmt&lt;/code&gt; formats the contents of a syntax literal such as &lt;code&gt;swp&lt;/code&gt;…&lt;code&gt;&lt;/code&gt;. &lt;code&gt;tokens&lt;/code&gt; is called when the language server highlights it. The grammar author defines &lt;code&gt;swp_fmt&lt;/code&gt; and &lt;code&gt;swp_tokens&lt;/code&gt; as ordinary Tauto functions. Without registration, the contents are left unformatted and highlighting is inferred from terminal names. More details appear in “Registering formatters and syntax highlighting” below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Untyped macros: reinterpret an expression
&lt;/h3&gt;

&lt;p&gt;An untyped macro receives anything that parses as a Tauto expression as a syntax value, &lt;strong&gt;without type-checking it first&lt;/strong&gt;. The standard library's &lt;code&gt;nat!&lt;/code&gt; reinterprets &lt;code&gt;==&lt;/code&gt; as propositional equality &lt;code&gt;=&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; as &lt;code&gt;Nat::add&lt;/code&gt;, allowing theorem statements to look like mathematical expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;add_comm_stmt&lt;/span&gt;(&lt;span class="n"&gt;a&lt;/span&gt;: &lt;span class="n"&gt;Nat&lt;/span&gt;, &lt;span class="n"&gt;b&lt;/span&gt;: &lt;span class="n"&gt;Nat&lt;/span&gt;): &lt;span class="n"&gt;nat&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;) &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add_comm&lt;/span&gt;(&lt;span class="n"&gt;a&lt;/span&gt;, &lt;span class="n"&gt;b&lt;/span&gt;) &lt;span class="err"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Because it runs before checking, it cannot inspect types. In return, it can accept expressions that would not otherwise type-check, such as an expression using &lt;code&gt;==&lt;/code&gt; where that operator is not defined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typed macros: inspect types and context
&lt;/h3&gt;

&lt;p&gt;A typed macro receives a checked expression as an opaque &lt;code&gt;Judgement&lt;/code&gt; value containing its context, term, type, effect row, and variable usage. It runs only after the declaration containing the call has been checked once without macro expansion. &lt;strong&gt;User code never runs in the middle of type inference.&lt;/strong&gt; This structurally rules out a cycle in which a macro inspects a type and then changes the type based on what it finds.&lt;/p&gt;

&lt;p&gt;The output is accepted only if its type is &lt;strong&gt;definitionally equal&lt;/strong&gt; to the original expression's type, its effect row is a &lt;strong&gt;subset of the original row&lt;/strong&gt; , and the &lt;strong&gt;entire declaration passes checking again&lt;/strong&gt;. Ownership, borrowing, and linearity are also checked across the whole expanded declaration. Matching types alone is not treated as a sufficient safety check.&lt;/p&gt;

&lt;p&gt;If you also want to preserve meaning, you can choose the &lt;code&gt;Proved&lt;/code&gt; result form, which returns a proof of equality &lt;code&gt;e = e'&lt;/code&gt; alongside the transformation. The kernel checks that proof.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tactics: macros that construct proofs
&lt;/h3&gt;

&lt;p&gt;A macro taking &lt;code&gt;ProofStep&lt;/code&gt; can be used inside a proof. The kernel checks the term it constructs &lt;strong&gt;against the explicitly written goal&lt;/strong&gt;. Even if a tactic produces an incorrect proof, the kernel decides whether to accept it; the tactic itself does not need to be trusted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;) &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;rewrite&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add_comm&lt;/span&gt;(&lt;span class="n"&gt;a&lt;/span&gt;, &lt;span class="n"&gt;k&lt;/span&gt;)): &lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;a&lt;/span&gt;, &lt;span class="n"&gt;k&lt;/span&gt;)) &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;), &lt;span class="n"&gt;a&lt;/span&gt;) &lt;span class="err"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;⊢&lt;/span&gt; &lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;, &lt;span class="n"&gt;a&lt;/span&gt;)) &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;), &lt;span class="n"&gt;a&lt;/span&gt;) &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;rewrite&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add_succ_left&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;, &lt;span class="n"&gt;a&lt;/span&gt;)) &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;⊢&lt;/span&gt; &lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;, &lt;span class="n"&gt;a&lt;/span&gt;)) &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Succ&lt;/span&gt;(&lt;span class="n"&gt;Nat&lt;/span&gt;::&lt;span class="n"&gt;add&lt;/span&gt;(&lt;span class="n"&gt;k&lt;/span&gt;, &lt;span class="n"&gt;a&lt;/span&gt;)) &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Refl&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;rewrite!&lt;/code&gt; is a standard-library tactic. Since the goal is written at every step, readers can follow the proof without knowing how the tactic is implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attribute macros: generate declarations
&lt;/h3&gt;

&lt;p&gt;Writing &lt;code&gt;@name!(…)&lt;/code&gt; before a declaration lets a macro generate declarations. This is a separate axis from the four kinds above: “attribute macro” describes the call's position, rather than a kind determined by its input type. The macro itself is a syntax macro or an untyped macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="n"&gt;lookup&lt;/span&gt;(&lt;span class="n"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;G&lt;/span&gt;, &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;, &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Looked&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="n"&gt;HasFound&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;HasNone&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;) &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;inductive&lt;/span&gt; &lt;span class="n"&gt;Looked&lt;/span&gt;, &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt;
&lt;span class="k"&gt;inductive&lt;/span&gt; &lt;span class="n"&gt;Has&lt;/span&gt;: (&lt;span class="n"&gt;List&lt;/span&gt;(&lt;span class="n"&gt;Ty&lt;/span&gt;)) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="n"&gt;Nat&lt;/span&gt;) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="n"&gt;Ty&lt;/span&gt;) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This uses the standard library's &lt;code&gt;mode!&lt;/code&gt; to turn the inductive relation below it into a decision function with uniquely determined outputs and a result type carrying a proof of correctness. It cannot transform arbitrary relations: the generator imposes conditions on the shapes of rules it accepts. The kernel checks the generated types and terms as usual.&lt;/p&gt;

&lt;p&gt;The list after &lt;code&gt;=&amp;gt;&lt;/code&gt; names the declarations generated &lt;strong&gt;in addition to&lt;/strong&gt; the original declaration, following the same listing rule. By default, the original declaration remains exactly as written. Rewriting it requires an explicit &lt;code&gt;replace&lt;/code&gt;. A handwritten declaration cannot silently turn into something else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why list generated declarations?
&lt;/h3&gt;

&lt;p&gt;A declaration-generating macro must list its generated declarations after &lt;code&gt;=&amp;gt;&lt;/code&gt; at every call. The macro already knows what it generates, so this could seem like something to infer automatically. Requiring it is deliberate: people and AI tools reading the source should be able to trace where a name came from &lt;strong&gt;without expanding the macro&lt;/strong&gt;. Without the list, the origin of &lt;code&gt;Looked&lt;/code&gt; or &lt;code&gt;lookup&lt;/code&gt; would only become apparent after expansion. A mismatch between the list and the actual output is an error, so stale lists cannot remain unnoticed.&lt;/p&gt;

&lt;p&gt;You do not, however, need to write the list by hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;tauto &lt;span class="nb"&gt;fmt&lt;/span&gt; &lt;span class="nt"&gt;--fill-generated&lt;/span&gt; main.taut

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

&lt;/div&gt;



&lt;p&gt;This fills in missing or incorrect lists using the fixes suggested by the diagnostics. The completed list is written into the source, where readers can see it without expanding anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hygiene: macros do not capture the caller's names
&lt;/h2&gt;

&lt;p&gt;Identifiers carry both a name and a set of scopes. Each expansion adds and removes a fresh scope on its output. This gives the following behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identifiers introduced by a macro's &lt;code&gt;quote&lt;/code&gt; do not capture the caller's variables.&lt;/li&gt;
&lt;li&gt;Identifiers that came from the input resolve to the bindings intended by the caller.&lt;/li&gt;
&lt;li&gt;Global names written in the macro refer to declarations in its definition file, even if the caller has declarations with the same names.&lt;/li&gt;
&lt;li&gt;Intentional capture is possible only through an explicit operation, &lt;code&gt;Syn::ident_like&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Captures are marked as such in &lt;code&gt;tauto macro trace&lt;/code&gt; and are prohibited by lint in the standard library. The policy is to make hidden bindings visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using effect analysis to contain macro execution
&lt;/h2&gt;

&lt;p&gt;Macros execute arbitrary code at compile time. Rust procedural macros run with the compiler process's privileges, so they can access files and the network. Tauto restricts this through &lt;strong&gt;effect rows in the type system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A macro function's effect row must be a subset of &lt;code&gt;{macro_error, macro_warn, elab, Div}&lt;/code&gt;. A function with any other effect cannot be registered as a macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;leak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;swp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;SynExpr&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;macro_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc/passwd"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;FAILED&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.taut&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt;&lt;span class="py"&gt;.row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;macro_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;macro_warn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elab&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;leak&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;performs&lt;/span&gt; &lt;span class="n"&gt;fs_read&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Reading a file performs &lt;code&gt;fs_read&lt;/code&gt;, which is not allowed in a macro's row, so the macro is rejected. The same applies to networking, environment variables, the clock, randomness, and standard output.&lt;/p&gt;

&lt;p&gt;Even if a standard effect were about to execute despite this check, the host running the macro would refuse to handle it and report an error. Directly calling built-in functions that access files or the network is rejected too.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about infinite loops?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Div&lt;/code&gt; marks functions that may diverge. It is allowed in macros so they can use recursion and &lt;code&gt;while&lt;/code&gt;, but macro execution is subject to budgets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;loopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;swp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;SynExpr&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;macro_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spin&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="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;FAILED&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main2&lt;/span&gt;&lt;span class="py"&gt;.taut&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt;&lt;span class="py"&gt;.budget_exceeded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;macro&lt;/span&gt; &lt;span class="n"&gt;loopy&lt;/span&gt; &lt;span class="n"&gt;took&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;than&lt;/span&gt; &lt;span class="mi"&gt;10000000&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Budgets cover steps per call (10⁷ by default), the total per file (10⁸), expansion depth (64), output nodes (10⁵), and evaluator memory allocations (10⁷). Exceeding one produces a diagnostic and fails that declaration, while checking continues with the next declaration. Huge outputs and chains in which macros keep calling more macros are stopped in the same way. DSL strings are also limited to 1 MiB, and the parsing stack to a depth of 10⁴.&lt;/p&gt;

&lt;p&gt;Macros also cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Emit &lt;code&gt;axiom&lt;/code&gt;, &lt;code&gt;extern&lt;/code&gt;, or &lt;code&gt;import&lt;/code&gt;, silently extending the set of things that must be trusted.&lt;/li&gt;
&lt;li&gt;Create a hole such as &lt;code&gt;?h&lt;/code&gt;: syntax values have no constructor for holes.&lt;/li&gt;
&lt;li&gt;Put &lt;code&gt;include_text!&lt;/code&gt; into their output to read a file. Includes run before macro expansion, and only for calls explicitly written in the source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even a malicious macro from a dependency can only emit code that could be written by hand, within the allowed effects and execution budgets. Those effects include diagnostics. You can inspect its output with &lt;code&gt;tauto macro expand&lt;/code&gt;, and the kernel ultimately checks it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A powerful syntax-macro system
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Write a grammar, get a typed AST and parser
&lt;/h3&gt;

&lt;p&gt;A grammar passed to &lt;code&gt;syntax!&lt;/code&gt; automatically produces a typed AST using &lt;code&gt;struct&lt;/code&gt; and &lt;code&gt;enum&lt;/code&gt; for its nonterminals, together with a &lt;code&gt;parse&lt;/code&gt; function that is also usable at runtime. It can even be used directly as a syntax literal, without invoking a macro: &lt;code&gt;math&lt;/code&gt;1 + 2 = 3&lt;code&gt;&lt;/code&gt; produces a &lt;code&gt;math::Eqn&lt;/code&gt; value without running a macro.&lt;/p&gt;

&lt;p&gt;The grammar notation is the same parol format used by &lt;code&gt;tauto.par&lt;/code&gt;, which defines Tauto's own syntax. Users can therefore add their own languages using the same notation used for Tauto itself. Parsing is table-driven. The tables generated from a grammar are ordinary files that can be committed under &lt;code&gt;.tauto-syntax/&lt;/code&gt;; the grammar generator does not have to run on every build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Left recursion: LL(k) and LALR(1)
&lt;/h3&gt;

&lt;p&gt;The default grammar class is LL(k), with lookahead k ≤ 3. Since left recursion is not allowed there, operators are expressed using repetition, such as &lt;code&gt;{ Plus Term }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For more natural left recursion or operator precedence, specify &lt;code&gt;%grammar_type 'LALR(1)'&lt;/code&gt; to generate an LALR(1) table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax!(ex, ```

par
%start E
%grammar_type 'LALR(1)'
%%
E: E Plus T | T;
T: Num;
Num: /[0-9]+/;
Plus: '+';


```) =&amp;gt; enum E, struct T

let r := ex`1 + 2 + 3`

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

&lt;/div&gt;



&lt;p&gt;The left-recursive production &lt;code&gt;E: E Plus T&lt;/code&gt; works as written. Removing the &lt;code&gt;%grammar_type&lt;/code&gt; line makes the grammar LL(k); lookahead conflicts then cause &lt;code&gt;tauto syntax gen&lt;/code&gt; to reject it.&lt;/p&gt;

&lt;p&gt;Both kinds of tables are generated by programs written in Tauto itself, in Nib: &lt;code&gt;totes/llkgen&lt;/code&gt; and &lt;code&gt;totes/lalrgen&lt;/code&gt;. The LALR(1) generator is written to construct the same states as lalry, the library used by parol, and tests compare their outputs. This is part of self-hosting Tauto's grammar infrastructure.&lt;/p&gt;

&lt;p&gt;Ambiguous grammars are reported as conflicts. They are not accepted by retaining multiple parse results or hiding the ambiguity behind ordered choice. This keeps the typed AST unambiguous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax errors report locations and expectations
&lt;/h3&gt;

&lt;p&gt;An error inside a DSL points to the actual line and column within the call's string and lists the terminals expected there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 + * 3 =&amp;gt; error: macro.syntax_error: in calc: expected Num or LParen, found Star

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

&lt;/div&gt;



&lt;p&gt;For indented multiline literals, locations are adjusted for the indentation removed during parsing, so they still point to what the user wrote.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registering formatters and syntax highlighting
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;syntax!&lt;/code&gt; accepts &lt;code&gt;with(fmt: …, tokens: …)&lt;/code&gt; to attach functions that handle text in that syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax!(layout, ```

par
%start Doc
%title "layout"
%%
Doc: Item { Comma Item };
Item: Num | Word;
Num: /[0-9]+/;
Word: /[a-z]+/;
Comma: ',';


```, with(fmt: layout_fmt, tokens: layout_tokens)) =&amp;gt; struct Doc, struct Doc_Rep1, enum Item, fn parse

let d := layout`1,2 , foo,3`

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

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;tauto fmt&lt;/code&gt; finds a literal in this syntax, it calls &lt;code&gt;layout_fmt&lt;/code&gt; to format the contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let d := layout`1, 2, foo, 3`

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;layout_fmt&lt;/code&gt; and &lt;code&gt;layout_tokens&lt;/code&gt; are ordinary Tauto functions that take a list of &lt;code&gt;SynTok&lt;/code&gt; values (a token stream including whitespace and comments) or a lossless concrete syntax tree, &lt;code&gt;SynCst&lt;/code&gt;. The ranges returned by &lt;code&gt;tokens&lt;/code&gt; determine the language server's highlighting. Without a registered function, highlighting is inferred from terminal names.&lt;/p&gt;

&lt;p&gt;The only effects these functions may have are &lt;code&gt;Div&lt;/code&gt; and &lt;code&gt;macro_error&lt;/code&gt;. They cannot access files or other external resources.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$name&lt;/code&gt; and &lt;code&gt;${…}&lt;/code&gt; inside a DSL are always highlighted as Tauto, whether or not &lt;code&gt;tokens&lt;/code&gt; is registered. Any ranges returned by &lt;code&gt;tokens&lt;/code&gt; that overlap these interpolations are trimmed. If the token function fails type checking, reports an error, or returns a range outside the text, the literal falls back to highlighting based on terminal names and gets a warning explaining why.&lt;/p&gt;

&lt;p&gt;Formatters are also constrained. Before writing a result back, &lt;code&gt;tauto fmt&lt;/code&gt; checks three things, keeping the original text and issuing a warning if any check fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The result parses as the same syntax.&lt;/li&gt;
&lt;li&gt;The token sequence, excluding whitespace, is unchanged.&lt;/li&gt;
&lt;li&gt;Formatting again leaves the result unchanged: the formatter is idempotent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A formatter bug therefore cannot change tokens or leave the literal unparsable. These checks are not sufficient, however, for syntax where whitespace changes can change meaning, such as an indentation-sensitive grammar. Authors of &lt;code&gt;fmt&lt;/code&gt; functions for such grammars still need to handle that carefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embedding Tauto expressions in a grammar
&lt;/h3&gt;

&lt;p&gt;The reserved terminal &lt;code&gt;TautoExpr&lt;/code&gt; lets you embed a Tauto expression inside a DSL with &lt;code&gt;${ … }&lt;/code&gt;. The standard library's &lt;code&gt;nat!&lt;/code&gt; uses this to embed Tauto expressions in mathematical notation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;mul_comm&lt;/span&gt;(&lt;span class="n"&gt;n&lt;/span&gt;: &lt;span class="n"&gt;Nat&lt;/span&gt;, &lt;span class="n"&gt;m&lt;/span&gt;: &lt;span class="n"&gt;Nat&lt;/span&gt;): &lt;span class="n"&gt;nat&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;) &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$n&lt;/code&gt; refers to the variable &lt;code&gt;n&lt;/code&gt;, while &lt;code&gt;${Succ(k)}&lt;/code&gt; is an expression. Embedded expressions retain their actual source locations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build and prove a language implementation
&lt;/h3&gt;

&lt;p&gt;In addition to the &lt;code&gt;struct&lt;/code&gt;/&lt;code&gt;enum&lt;/code&gt; AST, &lt;code&gt;inductive_syntax!&lt;/code&gt; generates proof-side &lt;code&gt;inductive&lt;/code&gt; types, with an &lt;code&gt;::I&lt;/code&gt; suffix such as &lt;code&gt;Expr::I&lt;/code&gt;, and conversion functions such as &lt;code&gt;Expr::to_i&lt;/code&gt;. You can then state theorems about the AST generated from the grammar.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;examples/calc&lt;/code&gt; is a small language implementation that reads arithmetic expressions with addition and multiplication from text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;inductive_syntax!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arith&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; ```
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;par&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;Expr&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="s"&gt;"calc"&lt;/span&gt;
&lt;span class="o"&gt;%%&lt;/span&gt;
&lt;span class="n"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Prod&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Plus&lt;/span&gt; &lt;span class="n"&gt;Prod&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;Prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Atom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Star&lt;/span&gt; &lt;span class="n"&gt;Atom&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;Atom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Paren&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Paren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;LParen&lt;/span&gt; &lt;span class="n"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;RParen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Num&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="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Plus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;'+'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Star&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;LParen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;'('&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;RParen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

```&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Atom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inductive&lt;/span&gt; &lt;span class="nn"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nn"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;


&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;tauto&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="py"&gt;.taut&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;incomplete&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;skipped&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;124&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;axioms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;none&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Among the properties proved here is &lt;code&gt;calc_run_correct&lt;/code&gt;: for any syntax tree, the compiled code runs without a stack underflow and leaves the value represented by that tree on the stack. The proofs check without additional axioms: &lt;code&gt;axioms: none&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Some parts remain unproved. The text-to-tree parser &lt;code&gt;arith::parse&lt;/code&gt; and the conversion &lt;code&gt;to_i&lt;/code&gt; are outside these proofs. The parser is a driver over the tables produced by the grammar generator, and its correctness has not yet been formally established. There is no formal proof yet that the text has the meaning represented by the tree. What can currently be proved is soundness and completeness &lt;strong&gt;from the tree returned by the parser onward&lt;/strong&gt;. Getting the AST as an &lt;code&gt;inductive&lt;/code&gt; type makes it possible to start writing a proof of the parser itself; that proof is not complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  More useful properties
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Every expansion can be traced
&lt;/h3&gt;

&lt;p&gt;Every node generated by a macro carries provenance: its call site, definition site, whether it was generated, and the chain of nested expansions. Diagnostics follow that chain to show which macro introduced what, for example: “&lt;code&gt;x&lt;/code&gt; (introduced by expansion of &lt;code&gt;math&lt;/code&gt;).”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tauto macro expand [--all | --at LINE:COL | --write | --json] FILE # inspect or write back the expansion
tauto macro trace [--json | --diff] FILE # trace expansion steps
tauto macro inspect FILE --at LINE:COL [--json]
tauto check --json # list expansions

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

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;--write&lt;/code&gt;, you can write an expansion back to source and keep a version that no longer uses the macro. All these commands support &lt;code&gt;--json&lt;/code&gt;, allowing AI agents to inspect macro expansion programmatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typed macros do not change the declaration environment
&lt;/h3&gt;

&lt;p&gt;Only syntax macros and attribute macros can generate declarations. A typed macro changes only the expression at its call site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write typing judgments in a DSL
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;examples/lambda&lt;/code&gt;, theorems about typing and reduction in the simply typed lambda calculus can be written directly in the calculus's notation. A syntax named &lt;code&gt;lc&lt;/code&gt; parses contextual judgments using a grammar containing &lt;code&gt;|-&lt;/code&gt; and &lt;code&gt;~&amp;gt;*&lt;/code&gt;, and is also used inside proofs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;k_star&lt;/span&gt;(): &lt;span class="n"&gt;lc&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;(&lt;span class="o"&gt;`&lt;/span&gt;(&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;: &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;: &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;) &lt;span class="n"&gt;star&lt;/span&gt; &lt;span class="o"&gt;~&amp;gt;*&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;: &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;star&lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;) &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Macro execution is ordered by file
&lt;/h3&gt;

&lt;p&gt;You can only use macros defined in an earlier file or in a dependency tote (a package). Defining and using a macro in the same file is an error. This makes the timing of macro execution visible at a unit a reader can understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deliberate restrictions
&lt;/h2&gt;

&lt;p&gt;Here are the restrictions discussed above. These are freedoms found in some other macro systems that Tauto deliberately does not provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access files, the network, environment variables, time, randomness, or standard output from a macro.&lt;/strong&gt; Instead, &lt;code&gt;include_text!&lt;/code&gt; reads a file only at an explicitly written call site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate declarations or change the environment from a typed macro.&lt;/strong&gt; Instead, syntax and attribute macros generate declarations, with the generated names listed in advance after &lt;code&gt;=&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a macro in the middle of type inference.&lt;/strong&gt; Instead, a typed macro receives a checked expression as a &lt;code&gt;Judgement&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Put &lt;code&gt;axiom&lt;/code&gt;, &lt;code&gt;extern&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt;, or a hole such as &lt;code&gt;?h&lt;/code&gt; in macro output.&lt;/strong&gt; Instead, emit code that can be written by hand, subject to these output restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silently replace a handwritten declaration.&lt;/strong&gt; Instead, explicitly request replacement with &lt;code&gt;replace&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a macro in the same file where it is defined.&lt;/strong&gt; Instead, use a macro from an earlier file or a dependency tote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silently capture a variable.&lt;/strong&gt; Instead, explicitly capture it with &lt;code&gt;Syn::ident_like&lt;/code&gt;, leaving a trace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guarantee the output's type when the macro itself is written.&lt;/strong&gt; Instead, check the expansion with the same checkers used for handwritten code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these freedoms can be useful. Tauto draws these boundaries to keep the trusted implementation small and expansions readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design priorities
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Soundness: do not accept invalid types, proofs, or authority.&lt;/li&gt;
&lt;li&gt;Minimalism: minimize concepts, special rules, and trusted implementation.&lt;/li&gt;
&lt;li&gt;Composability.&lt;/li&gt;
&lt;li&gt;Expressiveness.&lt;/li&gt;
&lt;li&gt;Security.&lt;/li&gt;
&lt;li&gt;Readability for AI: machine-readable ASTs, types, errors, and expansion steps.&lt;/li&gt;
&lt;li&gt;Performance.&lt;/li&gt;
&lt;li&gt;Self-hosting.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is not guaranteed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Proving the runtime evaluator correct is planned at the model level in Lean; correspondence with the Rust evaluator is checked by tests. A flaw in the evaluator could break macro isolation.&lt;/li&gt;
&lt;li&gt;Macros are not prevented from &lt;strong&gt;generating&lt;/strong&gt; code that performs dangerous actions. That code is treated the same way as the equivalent handwritten code, and can be inspected with &lt;code&gt;tauto macro expand&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A macro close to a resource budget may succeed or fail differently after an evaluator version change. Usage above 90% of the limit produces a warning.&lt;/li&gt;
&lt;li&gt;As noted above, the correctness of the grammar-generated parser remains unproved.&lt;/li&gt;
&lt;li&gt;The language is still experimental. Syntax and diagnostic messages shown here may change.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Macros are ordinary functions returning syntax values. Their input types determine their kinds.&lt;/li&gt;
&lt;li&gt;Expansions are checked by the same checkers as handwritten code, keeping macros out of the trusted base.&lt;/li&gt;
&lt;li&gt;Hygiene uses scope sets. Capture requires an explicit operation and leaves a trace.&lt;/li&gt;
&lt;li&gt;Effect rows prevent file and network access. Macros may use &lt;code&gt;Div&lt;/code&gt;, but execution budgets turn nontermination into diagnostics.&lt;/li&gt;
&lt;li&gt;Writing an LL(k) or LALR(1) grammar gives a syntax macro a typed AST, parser, and syntax literals. Formatters and highlighting can also be registered.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inductive_syntax!&lt;/code&gt; brings ASTs into the proof world, making it possible to state theorems about language implementations. The parser itself remains unproved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/Hihaheho/tauto" rel="noopener noreferrer"&gt;Tauto on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tauto</category>
      <category>macros</category>
      <category>dsl</category>
      <category>formalverification</category>
    </item>
    <item>
      <title>Asynchronous Request and Connection Pooling in Elixir with Cizen</title>
      <dc:creator>Ryo Hirayama</dc:creator>
      <pubDate>Sat, 20 Oct 2018 07:06:53 +0000</pubDate>
      <link>https://dev.to/ryo33/asynchronous-request-and-connection-pooling-in-elixir-with-cizen-16p</link>
      <guid>https://dev.to/ryo33/asynchronous-request-and-connection-pooling-in-elixir-with-cizen-16p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Yesterday, I was really excited to write example Elixir codes with Cizen for this post. Cizen is a library to build applications with automata, events, (and fun!). With cizen, it becomes easier to create highly concurrent, monitorable, and extensible applications. I believe that Cizen has the potential to make our software development more fun as like Elixir does. In this post, we will build an API client which implements asynchronous request and connection pooling with Cizen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automata and Events
&lt;/h2&gt;

&lt;p&gt;With using Cizen, we can use automata (plural of automaton) instead of processes. Automata communicate each other by subscribing and dispatching events in contrast with processes use direct messaging with pid.&lt;/p&gt;

&lt;h2&gt;
  
  
  API
&lt;/h2&gt;

&lt;p&gt;In this article, we suppose that we need to get articles for each category from an API. The API works like the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get_category_id with a body &lt;code&gt;"Elixir"&lt;/code&gt; (category name) returns a response with a body &lt;code&gt;"01"&lt;/code&gt; (category ID)&lt;/li&gt;
&lt;li&gt;get_articles with a body &lt;code&gt;"01"&lt;/code&gt; (category ID) returns a response with a body &lt;code&gt;["Let's Try Elixir", "Implement an API with Elixir"]&lt;/code&gt; (list of articles)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's Get Ready
&lt;/h2&gt;

&lt;p&gt;To get ready, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mix new client
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;articles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add Cizen to dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# in mix.exs&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;deps&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:cizen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.12.1"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, you need to prepare a simple mock of the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# in a new file request.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;API&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@categories&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="s2"&gt;"Elixir"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"Nature"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"02"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"Cizen"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"03"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nv"&gt;@articles&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="s2"&gt;"01"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Let's Try Elixir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Implement an API with Elixir"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"02"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Beautiful Nature"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"03"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Getting Started with Cizen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Asynchronous Request with Cizen"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;get_category_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;:timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Delay for an API call&lt;/span&gt;
    &lt;span class="nv"&gt;@categories&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;get_articles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;:timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniform&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Delay for an API call&lt;/span&gt;
    &lt;span class="nv"&gt;@articles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Single Connection
&lt;/h2&gt;

&lt;p&gt;Let's create &lt;code&gt;Connection&lt;/code&gt; automaton. &lt;code&gt;Connection&lt;/code&gt; automaton repeatedly receives &lt;code&gt;Connection.Request&lt;/code&gt; event and dispatches &lt;code&gt;Connection.Request.Reponse&lt;/code&gt; event for each request.&lt;/p&gt;

&lt;p&gt;First, create &lt;code&gt;Connection&lt;/code&gt; module and define those events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following to request.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Connection&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Request&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;
    &lt;span class="n"&gt;defresponse&lt;/span&gt; &lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:request_id&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:request_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;use Cizen.Request&lt;/code&gt; makes &lt;code&gt;Connection.Request&lt;/code&gt; requestive, and &lt;code&gt;defresponse&lt;/code&gt; defines its response event.&lt;/p&gt;

&lt;p&gt;Next, add the implementation of &lt;code&gt;Connection&lt;/code&gt; automaton.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following into Connection module&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Automaton&lt;/span&gt;

&lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# Subscribe Connection.Request events for this connection.&lt;/span&gt;
  &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="ss"&gt;:loop&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;request_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

  &lt;span class="c1"&gt;# Calls the API&lt;/span&gt;
  &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;request_id:&lt;/span&gt; &lt;span class="n"&gt;request_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="ss"&gt;:loop&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;spawn/2&lt;/code&gt; is called when the automaton is created, and &lt;code&gt;yield/2&lt;/code&gt; is called repeatedly until the automaton finishes. In &lt;code&gt;yield/2&lt;/code&gt;, &lt;code&gt;Connection&lt;/code&gt; handles &lt;code&gt;Connection.Request&lt;/code&gt; and dispatches &lt;code&gt;Connection.Request.Response&lt;/code&gt; one by one.&lt;/p&gt;

&lt;p&gt;Now, we can use &lt;code&gt;Connection&lt;/code&gt; to request to the API. Add the following code to run requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following to request.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effectful&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Elixir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Nature"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Cizen"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;# Request to get a category ID&lt;/span&gt;
          &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:get_category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;
          &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

          &lt;span class="c1"&gt;# Request to get articles&lt;/span&gt;
          &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:get_articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;
          &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

          &lt;span class="c1"&gt;# Returns the articles&lt;/span&gt;
          &lt;span class="n"&gt;articles&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:infinity&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Run&lt;/span&gt;
&lt;span class="no"&gt;Main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Main.main/0&lt;/code&gt; tries to get articles for three categories "Elixir", "Nature", and "Cizen", and the three processes are asynchronously run with using &lt;code&gt;Task.async&lt;/code&gt; and &lt;code&gt;Task.await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, we can run &lt;code&gt;request.exs&lt;/code&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mix run request.exs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;["Let's Try Elixir", "Implement an API with Elixir"]
["Beautiful Nature"]
["Getting Started with Cizen", "Asynchronous Request with Cizen"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Request Logger
&lt;/h2&gt;

&lt;p&gt;Before we use the connection pool, we should create a request logger to monitor the complex asynchronous requests.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;RequestLogger&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following above Main module in request.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;RequestLogger&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Automaton&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;All&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;StartSaga&lt;/span&gt;

  &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;All&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;effects:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;StartSaga&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;{}}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="ss"&gt;connections:&lt;/span&gt; &lt;span class="p"&gt;%{},&lt;/span&gt; &lt;span class="c1"&gt;# connection ID =&amp;gt; connection number&lt;/span&gt;
      &lt;span class="ss"&gt;requests:&lt;/span&gt; &lt;span class="p"&gt;%{}&lt;/span&gt; &lt;span class="c1"&gt;# request ID =&amp;gt; connection number&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cycle&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;StartSaga&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;put_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;connection_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sd"&gt;"""
        #{tabs(connection_number)}request
        #{tabs(connection_number)}#{request.type}
        #{tabs(connection_number)}body: #{request.body}
        """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;request_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
        &lt;span class="n"&gt;put_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;connection_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;request_id:&lt;/span&gt; &lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;connection_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pop_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sd"&gt;"""
        #{tabs(connection_number)}response
        #{tabs(connection_number)}#{inspect response.body}
        """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks a little bit difficult, but it simply logs &lt;code&gt;Connection.Request&lt;/code&gt; event and &lt;code&gt;Connection.Request.Response&lt;/code&gt; event to stdout. Also, it uses the horizontal axis for showing which connection is used and the vertical axis for the time sequence.&lt;/p&gt;

&lt;p&gt;To use the logger, update &lt;code&gt;Main.main/0&lt;/code&gt;;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;perform id, %Start{saga: %RequestLogger{}}&lt;/code&gt; above the line starting the connection:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;    &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;RequestLogger&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="c1"&gt;# here&lt;/span&gt;
      &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And, remove &lt;code&gt;|&amp;gt; Enum.map(&amp;amp;IO.inspect(&amp;amp;1))&lt;/code&gt; in order to avoid confusing with logging outputs:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:infinity&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# |&amp;gt; Enum.map(&amp;amp;IO.inspect(&amp;amp;1)) removed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;$ mix run request.exs&lt;/code&gt; outputs something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request
get_category_id
body: Nature

request
get_category_id
body: Cizen

request
get_category_id
body: Elixir

response
"02"

request
get_articles
body: 02

response
"03"

request
get_articles
body: 03

response
"01"

request
get_articles
body: 01

response
["Beautiful Nature"]

response
["Getting Started with Cizen", "Asynchronous Request with Cizen"]

response
["Let's Try Elixir", "Implement an API with Elixir"]

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

&lt;/div&gt;



&lt;p&gt;It shows that &lt;code&gt;Connection.Request&lt;/code&gt; events are asynchronously dispatched, and the connection handles them in order. In the next section, we use multiple connections with connection pooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Pooling
&lt;/h2&gt;

&lt;p&gt;Now, let's create &lt;code&gt;ConnectionPool&lt;/code&gt; automaton. It queues pushed connections and lends them with borrow event.&lt;/p&gt;

&lt;p&gt;First, define &lt;code&gt;Connection&lt;/code&gt; module and define related events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following above Main module in request.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;ConnectionPool&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;BorrowConnection&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;
    &lt;span class="n"&gt;defresponse&lt;/span&gt; &lt;span class="no"&gt;Lend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:borrow_id&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:borrow_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:connection_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:connection_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ConnectionPool.BorrowConnection&lt;/code&gt; is a requestive event and &lt;code&gt;ConnectionPool.BorrowConnection.Lend&lt;/code&gt; is its response event.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ConnectionPool.PushConnection&lt;/code&gt; is an event for registering a new connection or returning a borrowed connection.&lt;/p&gt;

&lt;p&gt;Next, add implementation of &lt;code&gt;ConnectionPool&lt;/code&gt; automaton.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# append the following into the ConnectionPool module&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Automaton&lt;/span&gt;
&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;All&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;All&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;effects:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="no"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="ss"&gt;:loop&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;borrow_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;push_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Receive&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;event_filter:&lt;/span&gt; &lt;span class="no"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&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="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;push_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

  &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Lend&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;borrow_id:&lt;/span&gt; &lt;span class="n"&gt;borrow_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="ss"&gt;:loop&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, update &lt;code&gt;Main.main/0&lt;/code&gt; to use multiple connections with &lt;code&gt;ConnectionPool&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# replace Main.main/0 with the following&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;RequestLogger&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="c1"&gt;# Starts 3 connections&lt;/span&gt;
    &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
      &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Elixir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Nature"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Cizen"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;# Borrow a connection&lt;/span&gt;
        &lt;span class="n"&gt;lend_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
        &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;
        &lt;span class="c1"&gt;# Request&lt;/span&gt;
        &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:get_category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
        &lt;span class="c1"&gt;# Return the connection&lt;/span&gt;
        &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;# Borrow a connection&lt;/span&gt;
        &lt;span class="n"&gt;lend_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
        &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;
        &lt;span class="c1"&gt;# Request&lt;/span&gt;
        &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="ss"&gt;:get_articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
        &lt;span class="c1"&gt;# Return the connection&lt;/span&gt;
        &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;articles&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;$ mix run request.exs&lt;/code&gt; outputs something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request
get_category_id
body: Cizen

                    request
                    get_category_id
                    body: Elixir

                                        request
                                        get_category_id
                                        body: Nature

response
"03"

request
get_articles
body: 03

                    response
                    "01"

                    request
                    get_articles
                    body: 01

                                        response
                                        "02"

                                        request
                                        get_articles
                                        body: 02

                                        response
                                        ["Beautiful Nature"]

                    response
                    ["Let's Try Elixir", "Implement an API with Elixir"]

response
["Getting Started with Cizen", "Asynchronous Request with Cizen"]

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

&lt;/div&gt;



&lt;p&gt;We made it! The requests are concurrently handled by the 3 connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Readability
&lt;/h2&gt;

&lt;p&gt;I assume that you noticed that the above code of &lt;code&gt;Main.main/0&lt;/code&gt; is too complex, and it may be because we have two steps of &lt;code&gt;perform/2&lt;/code&gt; for starting a connection, and three steps for requesting. In such a situation &lt;code&gt;Chain&lt;/code&gt; effect and &lt;code&gt;Map&lt;/code&gt; effect will help us to make our code clear to understand.&lt;/p&gt;

&lt;p&gt;First, add &lt;code&gt;Main.start_connection/0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# add the following into the Main module&lt;/span&gt;

&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;start_connection&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Chain&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;effects:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;{}},&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It joins the two effects, one for starting a connection and the other for dispatching &lt;code&gt;ConnectionPool.PushConnection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, add &lt;code&gt;Main.request/2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# add the following into the Main module&lt;/span&gt;

&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;effect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Chain&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;effects:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;BorrowConnection&lt;/span&gt;&lt;span class="p"&gt;{}},&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;type:&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;connection_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lend_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection_id&lt;/span&gt;
      &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushConnection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;connection_id:&lt;/span&gt; &lt;span class="n"&gt;connection_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;effect:&lt;/span&gt; &lt;span class="n"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;transform:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It joins the three effects, one for borrowing a connection, another for requesting, and the other for returning the connection. After that, it also transforms the result so that &lt;code&gt;perform id, request(type, body)&lt;/code&gt; will return the response for the request.&lt;/p&gt;

&lt;p&gt;Finally, update &lt;code&gt;Main.main/0&lt;/code&gt; to use them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# replace Main.main/0 with the following&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Cizen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Effects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;

  &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;RequestLogger&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;saga:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;ConnectionPool&lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;
    &lt;span class="c1"&gt;# Starts 3 connections&lt;/span&gt;
    &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Elixir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Nature"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Cizen"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get_category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

        &lt;span class="n"&gt;response_event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get_articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;

        &lt;span class="n"&gt;articles&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:infinity&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, our code is more readable than the old one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/ryo33/cizen-request-example" rel="noopener noreferrer"&gt;The full code for this post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/cizen/cizen" rel="noopener noreferrer"&gt;Cizen on GitLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hex.pm/packages/cizen" rel="noopener noreferrer"&gt;Cizen on Hex.pm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hexdocs.pm/cizen" rel="noopener noreferrer"&gt;Online documentation of Cizen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>cizen</category>
    </item>
  </channel>
</rss>
