<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Andrey Listopadov</title>
    <link>https://andreyor.st/tags/lisp/</link>
    <image>
      <title>Andrey Listopadov</title>
      <link>https://andreyor.st/tags/lisp/</link>
      <url>https://andreyor.st/tags/lisp/favicon-64.png</url>
    </image>
    <description>Posts tagged 'lisp' by Andrey Listopadov</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>Andrey Listopadov 2020-2026 - This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</copyright>
    <lastBuildDate>Sat, 17 Sep 2022 22:39:00 +0300</lastBuildDate>
    <atom:link href="https://andreyor.st/tags/lisp/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Function that can be called a limited amount of times</title>
      <link>https://andreyor.st/posts/2022-09-17-function-that-can-be-called-a-limited-amount-of-times/</link>
      <guid>https://andreyor.st/posts/2022-09-17-function-that-can-be-called-a-limited-amount-of-times/</guid>
      <description>&lt;p&gt;Recently I&amp;rsquo;ve stumped upon a &lt;a href=&#34;https://www.reddit.com/r/rust/comments/xelzrv/function_that_can_only_be_called_a_set_number_of/&#34; target=&#34;_blank&#34;&gt;Reddit thread&lt;/a&gt; about defining a function that you can call a limited amount of times in Rust, with compile-time check, and I wondered if I can make the same thing in Clojure.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defmacro &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;def-n-times-fn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;&amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fnspec&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;atom&lt;/span&gt; ~&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)            &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; A compile-time counter.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;~&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;~@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fnspec&lt;/span&gt;)] &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; The function object, that will be called at runtime.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defmacro &lt;/span&gt;~&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;[&amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;args#&lt;/span&gt;]   &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; Generation of a new macro with the name of the function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; that will manage the counter.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;pos? &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;deref &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x#&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; And if the counter isn&amp;#39;t greater than zero&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt;                    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; an exception is thrown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; ~(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;can&amp;#39;t use `%s` more than %s times!&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;name&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;) {})))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dec&lt;/span&gt;)      &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; otherwise, we decrement the counter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;list* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;args#&lt;/span&gt;)))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; and generate a call&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, this is a macro-generating macro!
I&amp;rsquo;ll go into details in a bit, but let&amp;rsquo;s just appreciate the power of macros here.
Not only we can run all kinds of code at compile time, but we can also use all features that we often rely on at runtime, like lexical scope and closures!
And even though I wouldn&amp;rsquo;t really use a such macro in real code, I find the ability to do such things fascinating.&lt;/p&gt;
&lt;p&gt;We can use the macro like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;def-n-times-fn&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It acts similarly to &lt;code&gt;defn&lt;/code&gt; macro in Clojure, except instead of a function it generates a macro, named &lt;code&gt;vaiv&lt;/code&gt; in this case, that will be later expanded to an actual function call.
For example, we can wrap calls to it in a function, ensuring that the actual calls are delayed, and only compilation of these calls occurs.
I&amp;rsquo;ve put all of this into a file &lt;code&gt;foo.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---8&amp;lt;---snip---8&amp;lt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; (defmacro defn-n-times-fn ...)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; (def-n-times-fn 4 ...)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---8&amp;lt;---snap---8&amp;lt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 5))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now if we try to compile it, we&amp;rsquo;ll get an error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ clojure -M -e &amp;#34;(compile &amp;#39;foo)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Syntax error macroexpanding vaiv at (foo.clj:25:3).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;can&amp;#39;t use `vaiv` more than 4 times!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nice!
And if we comment out one of the calls to &lt;code&gt;vaiv&lt;/code&gt; the compilation is successful:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ clojure -M -e &amp;#34;(compile &amp;#39;foo)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;foo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So what exactly happens here?
If we &lt;code&gt;macroexpand&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; the call to &lt;code&gt;defn-n-times-fn&lt;/code&gt; we&amp;rsquo;ll see that it just generates a new &lt;code&gt;vaiv&lt;/code&gt; macro and a function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;let*&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x__5686__auto__&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;atom&lt;/span&gt; 4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f__5687__auto__&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defmacro &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; [&amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;args__5688__auto__&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;pos? &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x__5686__auto__&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;can&amp;#39;t use `vaiv` more than 4 times!&amp;#34;&lt;/span&gt; {})))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x__5686__auto__&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;list* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f__5687__auto__&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;args__5688__auto__&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So far nothing related to compile time usage checking happened just yet.
This changes whenever later uses of &lt;code&gt;vaiv&lt;/code&gt; itself expand to calls:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;macroexpand &lt;/span&gt;&amp;#39;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; 42))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;function&lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo/eval5694/vaiv--5695&lt;/span&gt;] 42)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s no check in the generated code either, because the check happened during the expansion of the macro, and is invisible to the user.
Every expansion of the &lt;code&gt;vaiv&lt;/code&gt; macro decrements the counter, and once we&amp;rsquo;ve expanded the code enough times it will fire an error.&lt;/p&gt;
&lt;p&gt;Pretty simple!
(If you can look past the meta-meta-programming, that is.)&lt;/p&gt;
&lt;p&gt;Though, this comes with limitations, such that this function can&amp;rsquo;t be passed into other functions, like &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;filter&lt;/code&gt;.
Both because this is not actually a function, but a macro that expands to function call, and because it&amp;rsquo;s impossible to know at compile time how many times &lt;code&gt;map&lt;/code&gt; will invoke this function.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a way to outsmart the check by using any kind of loop:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dotimes &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 5]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works, because from the macro-expansion standpoint there&amp;rsquo;s only one invocation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.walk/macroexpand-all&lt;/span&gt; &amp;#39;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dotimes &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 5] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vaiv&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;let*&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n__6088__auto__&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;long &lt;/span&gt;5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;loop*&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n__6088__auto__&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;function&lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo/eval13775/vaiv--13776&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; (vaiv i)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unchecked-inc&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nevertheless, this was an interesting exercise in writing macros.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I&amp;rsquo;ve slightly edited the output of &lt;code&gt;macroexpand&lt;/code&gt;, mainly removing a lot of &lt;code&gt;clojure.core/&lt;/code&gt; prefixes for a more concise code.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Function that can be called a limited amount of times&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 17 Sep 2022 22:39:00 +0300</pubDate>
    </item><item>
      <title>Wave Function Collapse Algorithm in ClojureScript</title>
      <link>https://andreyor.st/posts/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/</link>
      <guid>https://andreyor.st/posts/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/</guid>
      <description>&lt;p&gt;The last time I touched ClojureScript was &lt;a href=&#34;https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/&#34;&gt;almost two years ago&lt;/a&gt;.
It was a really fun experience, and actually, it was a bit special to me personally.
Prior to that post, I only learned lisp&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; via books and mostly used it only for configuring Emacs, and while I&amp;rsquo;ve liked the idea of code as data and other lisp aspects, I never did anything more with the language.
So this was the first thing that I&amp;rsquo;ve done in lisp from start to finish, the first thing done in Clojure, the first interactive thing with some sort of visualizations.
And this is pretty much the reason I fell in love with Clojure and not with another dialect - I&amp;rsquo;ve used it for something &lt;em&gt;real&lt;/em&gt;, not just an exercise for the book, and I liked the syntax, the data structures, immutability, laziness, and other features.
Since that post I&amp;rsquo;ve got a job in Clojure, so now it&amp;rsquo;s my primary programming language and I love it still.
However, I have a lot less experience with ClojureScript, mainly because I mostly do backend development, and we have a separate team working on the frontend part.&lt;/p&gt;
&lt;p&gt;I like games, but I&amp;rsquo;ve never actually done anything more than simple demos of various game algorithms and techniques&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.
And I mostly did it in Fennel, because it&amp;rsquo;s also a very nice lisp-like language with a very similar syntax to Clojure.
I wanted to do more, but I wanted these experiments to be a bit more reachable, and possibly viewed directly in my blog, as it was with the raycasting example.
So I knew that I wanted to do something with ClojureScript instead of Fennel, which became my main language for this type of thing.
Another reason is that I&amp;rsquo;m thinking about doing some frontend programming in ClojureScript in the upcoming years.&lt;/p&gt;
&lt;p&gt;Luckily for me, not so long ago I found a really neat algorithm for generating worlds.
The algorithm is called Wave Function Collapse, and it actually has nothing to do with quantum physics.
In this post, I&amp;rsquo;ll try to walk you thru the algorithm, and explain how I&amp;rsquo;ve approached this problem.&lt;/p&gt;
&lt;h2 id=&#34;the-algorithm&#34;&gt;The algorithm&lt;/h2&gt;
&lt;p&gt;What makes this algorithm different from most procedural generation algorithms I&amp;rsquo;ve read about is that it is &lt;em&gt;extremely simple&lt;/em&gt;.
It can generate images based on a small sample of data, as shown below:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/coast.png&#34;
         alt=&#34;Figure 1: Example Input&#34;/&gt;&lt;figcaption&gt;
            &lt;p&gt;&lt;span class=&#34;figure-number&#34;&gt;Figure 1: &lt;/span&gt;Example Input&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/result.png&#34;
         alt=&#34;Figure 2: Generation result&#34;/&gt;&lt;figcaption&gt;
            &lt;p&gt;&lt;span class=&#34;figure-number&#34;&gt;Figure 2: &lt;/span&gt;Generation result&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;However, just implementing the algorithm from some description isn&amp;rsquo;t fun.
What I like to do, and this is a general approach I use for all my projects, is to get some assumptions about the thing I want to implement, and then do everything based on these assumptions only&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.
So instead of learning how the algorithm is implemented, I&amp;rsquo;ve just observed its behavior with simple input.&lt;/p&gt;
&lt;p&gt;For example, let&amp;rsquo;s look again at the input sample, but let&amp;rsquo;s split it into tiles with a grid:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;figure--example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/example.png&#34;
         alt=&#34;Figure 3: Sample&#34;/&gt;&lt;figcaption&gt;
            &lt;p&gt;&lt;span class=&#34;figure-number&#34;&gt;Figure 3: &lt;/span&gt;Sample&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This sample specifies that for each tile on this image there are only so many possible neighbors.
For example, this tile in the middle can only have one unique neighbor on each of its sides:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/neighbors.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Other tiles may have two or more unique neighbors, and the job of the algorithm is to analyze each tile on the image, and track what neighboring cells it has, storing it into a ruleset.
And an image is then generated based on these adjacency rules only.&lt;/p&gt;
&lt;p&gt;This is basically what I knew about the algorithm when I started implementing it.
Of course, it&amp;rsquo;s not &lt;em&gt;that&lt;/em&gt; simple, but it&amp;rsquo;s still easy to grasp, and some nuances become apparent when you actually start working on it.
I&amp;rsquo;ll give the algorithm a more comprehensive explanation a bit later, as we&amp;rsquo;ll encounter problems.&lt;/p&gt;
&lt;h2 id=&#34;text-version-of-the-algorithm&#34;&gt;Text version of the algorithm&lt;/h2&gt;
&lt;p&gt;For this project, I once again picked shadow-cljs, so the project can be created with &lt;code&gt;npx create-cljs-project wave-function-collapse&lt;/code&gt;.
But before actually working with images we can begin with a bit simpler to debug version of it which deals with an ordinary text.
This can be done in plain Clojure, but since we&amp;rsquo;ll later plug it into our page, let&amp;rsquo;s use &lt;code&gt;.cljs&lt;/code&gt; file.
We start by implementing our algorithm in the file &lt;code&gt;wfc.cljs&lt;/code&gt;, &lt;code&gt;wfc&lt;/code&gt; being short for wave function collapse.&lt;/p&gt;
&lt;p&gt;As I&amp;rsquo;ve explained in the previous section, we start by transforming an input into a set of rules for the algorithm.
Our input will be a two-dimensional matrix, in this case, an array of arrays of strings.
Let&amp;rsquo;s start with a similar sample to that I&amp;rsquo;ve shown in the &lt;a href=&#34;#figure--example&#34;&gt;previous example&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coast&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;]])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s even simpler, as it doesn&amp;rsquo;t have tiles that represent corners.
The first thing we need to do is to define a function, that gets all neighboring cells in all cardinal directions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-neighbors&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:up&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:down&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;inc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:left&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:right&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;inc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;when-some&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;}]))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function gets only those cells inside our matrix and discards those that are outside of its boundaries.
With this function we can write a function that builds a recipe from the input sample:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; add [clojure.set :as set] to :require&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;build-recipe&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;map-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;map-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neigbors&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:keys&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;]}]] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;}]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-neighbors&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neigbors&lt;/span&gt;})) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;flatten&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply merge-with &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;merge-with &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set/union&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%2&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m using &lt;code&gt;map-indexed&lt;/code&gt; because we need to get neighbors for each cell, and this is what our &lt;code&gt;get-neighbors&lt;/code&gt; function accepts.
Calling this function on the &lt;code&gt;coast&lt;/code&gt; recipe yields the following map:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:up&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:down&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:left&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:right&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:up&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:down&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:left&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:right&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟫&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:up&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:down&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:left&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:right&lt;/span&gt; #{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟦&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;🟩&amp;#34;&lt;/span&gt;}}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have a proper illustration of the adjacency rules we&amp;rsquo;ve talked about before.
With that, we can start implementing the algorithm itself.&lt;/p&gt;
&lt;h2 id=&#34;collapsing-cells&#34;&gt;Collapsing cells&lt;/h2&gt;
&lt;p&gt;In order to collapse anything, we need a world in which we&amp;rsquo;ll do our work.
The beauty of this algorithm lies in the fact that it can work with a partially filled world, but generally, the world starts in a so-called superposition.
To get this superposition, we need to analyze the input sample once again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-superposition&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;#{} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;flatten&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This gives us all possible variants for a single cell.
To define a world we can just generate a new &amp;ldquo;empty&amp;rdquo; matrix that we&amp;rsquo;ll later populate with a cell superposition state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gen-world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-y&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;range &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-x&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;range &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-y&lt;/span&gt;)] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;populate-world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;superpos&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-superposition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;nil? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;superpos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As the last preparation step, we need a way of checking if the world is fully built.
This can be done by checking if any of the cells is still a hash-set and not a concrete value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;done?&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;some &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;flatten&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A more optimal way would be to track how many cells were fully collapsed and compare it with the world size to avoid walking the whole world repeatedly on each step, but for now, this will do.
The last preparation step we need to do is to write a function that chooses which cell to collapse next.
The first cell can be selected at random, but the following must be selected more carefully, or we&amp;rsquo;ll corner ourselves pretty quickly.
To do that we need to measure world entropy and select a cell with the lowest one.
Since every cell can only contain a set of unique elements, we can measure the entropy by counting the number of elements in a cell.
Thus, a function that returns the lowest entropy cell can be defined as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lowest-entropy-cell&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enthropies&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;map-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;) [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]])) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;concat&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shuffle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;sort-by &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;first&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;if-some&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enthropies&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;second &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [0 0])))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will produce uniform distribution, so we might want to change it a bit later, but for now, it&amp;rsquo;ll do.&lt;/p&gt;
&lt;p&gt;Now to the meat and bones of the algorithm.
To actually collapse a cell we need a function that can choose a random element of a cell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;val&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coll?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;val&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;val&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assoc-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;val&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assoc-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;val&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After the cell is collapsed, we need to constrain its neighbors, so their superposition only contained possible elements that can be connected to this cell.
This is a bit harder part of the algorithm, as it involves waling a grid of cells recursively and constraining every cell that is a set and skipping others that are not.
If a cell itself is a set, its content should be treated as a series of cells that also affect how the surrounding cells should be constrained:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse-neighbors&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neighbors&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-neighbors&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neighboring-cells&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shuffle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;vals &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neighbors&lt;/span&gt;))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; ❶&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;&amp;#39; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reduce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; {[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt;}]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; ❷&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set/intersection&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coll?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) #{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set/union&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt;]) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt;])))] &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; ❸&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;seq &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; ❹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neighbors&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse-neighbors&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;neighboring-cells&lt;/span&gt;)))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; ❺&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function is the heart of the algorithm, as it does all of the heavy liftings on constraining cells, so let&amp;rsquo;s break it down.
First, we get all neighbors and extract a sequence of cells that we&amp;rsquo;re going to constrain (❶).
We then iterate over these neighbors inside &lt;code&gt;reduce&lt;/code&gt;, getting the current world state for this cell (❷).
For this cell, we need to compute all remaining variants.
This is done by intersecting this cell&amp;rsquo;s state with variants from a neighbor in a given direction.
And if the cell itself is a set, this is done for each element in a set (❸).
Finally, a cell is collapsed (❹), except when it was a set and the variant list wasn&amp;rsquo;t empty.&lt;/p&gt;
&lt;p&gt;After that process is done for all four neighbors, we need to repeat it for each of the neighbors&amp;rsquo; neighbors.
So we check if our last run actually produced any change in the world, and if it is, we recursively walk through these neighbors (❺), otherwise, we return current world state.
This may actually cause a stack overflow error if there are too many neighbors to collapse, which depends both on the world size and how general the recipe is.
To avoid that, this function can be turned into iterative, but it still will maintain the stack of neighbors to collapse, which will grow in memory, instead of on a stack.
I&amp;rsquo;ve decided to go with recursion, as it&amp;rsquo;s a bit easier to understand in the context of the post.&lt;/p&gt;
&lt;p&gt;The last bit needed is a loop that will repeat this process until the whole world is collapsed.
The process is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pick a cell with the lowest entropy, first one is random&lt;/li&gt;
&lt;li&gt;collapse it&lt;/li&gt;
&lt;li&gt;constrain neighbors&lt;/li&gt;
&lt;li&gt;check if not done
&lt;ul&gt;
&lt;li&gt;repeat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;build-recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;populate-world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rand-int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rand-int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rand-nth&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse-neighbors&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lowest-entropy-cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we can actually try it!
Let&amp;rsquo;s create some helpers, that will print the resulting world, and the input recipe:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; add [clojure.string :as str] to :require&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-sample&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str/join&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str/join&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;println&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sep&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;?&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str/join&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sep&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str/join&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;println&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-result&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample:&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;gen:&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print-world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, if we use our &lt;code&gt;coast&lt;/code&gt; recipe, we should see this in our REPL:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wfc.wfc&amp;gt; (print-result coast (wfc (gen-world 16 16) coast))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sample:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟩🟩🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟩🟦🟦🟩
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gen:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟫🟩🟫🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟫🟩🟦🟩🟫🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟫🟩🟦🟦🟦🟩🟫🟫🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟫🟩🟦🟦🟦🟦🟦🟩🟩🟫🟫🟫🟫
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟫🟩🟦🟦🟦🟦🟦🟦🟦🟦🟩🟫🟩🟩
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟫🟫🟩🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟩🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟩🟩🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can try with a bit more interesting examples, like these trees:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;snowy-trees&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╱&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╲&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╱&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╲&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╱&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;v&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;╲&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;]])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wfc.wfc&amp;gt; (print-result snowy-trees (wfc (gen-world 16 60) snowy-trees))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sample:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*    *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *╱╲ *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* ╱vv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ╱vvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gen:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *  *  *   *   *      *   *     *    *   *  * *    * *  *  *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   *  *  *    * * * *   *  * *    *    *     *  * * *  *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *      *      *              *  *       * *   *   *  * * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  * * *   *   * * *  * *  *     *    * *  *   * *      * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *   *   *   * *   *  *  *  * *  *  *   *  * * * *        *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   *    *  *      *       *  *  *  *  *  *    * * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *        * * *  *  *  * *     *  * *     * *      * * * * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *  *  *    *  * *  *     *  *  * *  *  * *    *   *   * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         * *   * * *      *    *  *     * *  * *  ╱╲  *  *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   *  * * *   *       *  *    *      *        * *╱vv╲  *   *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*   *  *   * *     * * *   *     *  *  * *  *  *╱vvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *   *   * *   * *     *   *   *  *    * *  * ╱vvvvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *  *   *     *   ╱╲ *    *   *   *  ╱╲  *  * ╱vvvvvvvv╲ *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         *     * ╱vv╲ *  *  ╱╲ * * *╱vv╲   * ╱vvvvvvvvvv╲ *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; *   *     *    ╱vvvv╲  * *╱vv╲ * *╱vvvv╲ * ╱vvvvvvvvvvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  ╱╲ *  ╱╲  * ╱vvvvvv╲   ╱vvvv╲ *╱vvvvvv╲ ╱vvvvvvvvvvvvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Noticeable, the spread is too uniform.
This is because we pick a random choice, and the choices have equal distribution.
Instead, it&amp;rsquo;d be nicer if we had a bit more control over what elements are more present and what is less present.&lt;/p&gt;
&lt;p&gt;To do that, we need to replace our random choice picking with weighted random.
First, we need to calculate the weights:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-weights&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;frequencies&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply concat &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will do - the more times a certain tile appears in a recipe, the higher its weight is.
Now we need a weighted random:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weighted-random&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;k&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;k&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;k&lt;/span&gt;))) {} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reductions&lt;/span&gt; #(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;vals &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rnd&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rand-int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;last &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;nth &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;keys &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;variants&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;take-while &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rnd&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And now, that we have weights, we can upgrade our &lt;code&gt;lowest-entropy-cell&lt;/code&gt; function to take weights into account when calculating the entropy.
We also use a better entropy calculation algorithm, based on &lt;a href=&#34;https://en.wikipedia.org/wiki/Entropy_%28information_theory%29&#34; target=&#34;_blank&#34;&gt;Shannon entropy:&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell-enthropy&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight-sum&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce + &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;get &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;log-weight-sum&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce + &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;get &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/log&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;double &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight&lt;/span&gt;)))) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/log&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight-sum&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;log-weight-sum&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weight-sum&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lowest-entropy-cell&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enthropies&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;map-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep-indexed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell-enthropy&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;) [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]])) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce into &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sorted-map&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;if-some&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enthropies&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [0 0])))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The last change needed is in the &lt;code&gt;wfc&lt;/code&gt; function - we need to use &lt;code&gt;weighted-random&lt;/code&gt; when we &lt;code&gt;collapse&lt;/code&gt; a cell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;build-recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-weights&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;populate-world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rand-int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rand-int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-in&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weighted-random&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;collapse-neighbors&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recipe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lowest-entropy-cell&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;weights&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now the algorithm is done, and we can see that the &lt;code&gt;snowy-trees&lt;/code&gt; example has a bit less snow now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wfc.wfc&amp;gt; (print-result snowy-trees (wfc (gen-world 16 60) snowy-trees))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sample:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*    *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *╱╲ *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* ╱vv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ╱vvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gen:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   *    *    *   *  *       *      *           * *         *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *        *    *         *     *       *       * *   * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       *      *        *   *         *    *   *    *   *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   *                *        *     *  *    *     *   *   *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*             *  * *      *          *       *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           *           *   *    *       * *             *  *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              *  *    *            *   *      *      *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    *     *  *     * *     *    *    *     *           * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   * *     *          * *   *  *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          *    *       *  *       *   * *   *     *  * *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  * *       * *    * *   *     *   * * *            *   *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       *   *    *                 *      *        ╱╲ *     *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      *      *        * *            *      *  * ╱vv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     * ╱╲            *    * *          *  *     ╱vvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ╱vv╲   ╱╲  *       *      *        *  *  ╱vvvvvv╲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  *  ╱vvvv╲ ╱vv╲   ╱╲  *  * *           * *  *╱vvvvvvvv╲  *╱
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;working-with-images&#34;&gt;Working with images&lt;/h2&gt;
&lt;p&gt;At the beginning of this article, I&amp;rsquo;ve shown you an image of a coast.
This image is generated by the code above, but right now it can&amp;rsquo;t handle images, only text.
This isn&amp;rsquo;t a problem, really, because the text is just used in place of unique identifiers, so we can plug in anything, and then use the resulting world as a recipe to paint it on a canvas.
Let&amp;rsquo;s do exactly that, but before we can do it, we need to be able to upload an image and splice it into tiles.&lt;/p&gt;
&lt;p&gt;To do that, we&amp;rsquo;ll need an &lt;code&gt;index.html&lt;/code&gt; file in our &lt;code&gt;public/&lt;/code&gt; directory, and a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; tag in it with an appropriate &lt;code&gt;id&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;canvas id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_view&amp;#34;&lt;/span&gt; width=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;512&amp;#34;&lt;/span&gt; height=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;512&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/canvas&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;input type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_input&amp;#34;&lt;/span&gt; accept=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;image/*&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/input&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;script type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;text/javascript&amp;#34;&lt;/span&gt; src=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/js/main.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;window&lt;/span&gt;.onload = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    wfc.core.init();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m also adding an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag, to open an image.
Additionally to that, there should be the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag that loads our &lt;code&gt;core&lt;/code&gt; module and runs the &lt;code&gt;init&lt;/code&gt; function.
With this in place, we can add an event listener to the button, and load the image to canvas.
In &lt;code&gt;core.cljs&lt;/code&gt; add:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_input&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/upload&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in &lt;code&gt;sample.cljs&lt;/code&gt; create the &lt;code&gt;upload&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:width&lt;/span&gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:height&lt;/span&gt; 0})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_view&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/Image.&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getContext&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.clearRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; 0 0 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;viewer&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.drawImage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt; 0 0)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;load&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-src&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-result&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;upload&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;files&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-files&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reader&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/FileReader.&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reader&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;load&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.readAsDataURL&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reader&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;aget &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;files&lt;/span&gt; 0)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should allow us to upload an image.
Now we need to split it into tiles.
To do that, let&amp;rsquo;s add another button to our &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;button type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;split_to_tiles&amp;#34;&lt;/span&gt;&amp;gt;Split to tiles&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In &lt;code&gt;core.cljs&lt;/code&gt; we add another event listener:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_input&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/upload&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tile-size&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;split_to_tiles&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tile-size&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/split-to-tiles&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render-button&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;render&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render-button&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render/render&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And define the function that does the work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*sample*&lt;/span&gt; [])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*tiles*&lt;/span&gt; {})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;split-to-tiles&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.createElement&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;canvas&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getContext&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.drawImage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;) 0 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hashes-imgs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;range &lt;/span&gt;0 (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;) 32)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;range &lt;/span&gt;0 (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*image*&lt;/span&gt;) 32)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;img&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getImageData&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 32 32)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hash&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;img.data&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;img&lt;/span&gt;])))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*sample*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hashes-imgs&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*tiles*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{} (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply concat &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hashes-imgs&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/alert&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Please upload an image first&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We do basic error checking, that an image was uploaded by checking &lt;code&gt;*image*&lt;/code&gt; to have anything under the &lt;code&gt;:image&lt;/code&gt; key.
If there&amp;rsquo;s an image, we create a canvas, that we draw this image on, and then iterate thru it row by row, tile by tile, with a fixed tile size of &lt;code&gt;32&lt;/code&gt;.
In this loop, we get an array of pixels, representing the given tile, and we calculate its hash, which we will use in our wave function collapse algorithm.&lt;/p&gt;
&lt;p&gt;Now we can upload an image, and split it into tiles, the only thing left is to actually draw the result!&lt;/p&gt;
&lt;h2 id=&#34;drawing-the-result&#34;&gt;Drawing the result&lt;/h2&gt;
&lt;p&gt;We need yet another canvas for that.
Actually, we need only one canvas for all of this, as we have the input button that takes care of image loading, and another button for splitting.
But I still like to see what sample is loaded, as it gives a better understanding of what the resulting image was constructed from.
So let&amp;rsquo;s add another canvas and a button:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;canvas id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;render_view&amp;#34;&lt;/span&gt; width=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;512&amp;#34;&lt;/span&gt; height=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;512&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/canvas&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;button type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;render&amp;#34;&lt;/span&gt;&amp;gt;Generate&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once again, let&amp;rsquo;s add a handler to this button in &lt;code&gt;core.cljs&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.render&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;sample_input&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample-input&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/upload&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tile-size&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;split_to_tiles&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tile-size&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/split-to-tiles&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render-button&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;render&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render-button&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render/render&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in &lt;code&gt;render.cljs&lt;/code&gt; we need to define the &lt;code&gt;render&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.render&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.sample&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc.wfc&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/*image*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;renderer&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;render_view&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getContext&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;renderer&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;renderer&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;renderer&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.clearRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; 0 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;solve&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/alert&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Please upload an image&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nothing too complicated, just a handler that clears the canvas and calls &lt;code&gt;solve&lt;/code&gt;.
Now, &lt;code&gt;solve&lt;/code&gt; is where the work is done:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;solve&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;seq &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/*sample*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tiles&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/*tiles*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt; 32]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc/wfc&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wfc/gen-world&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sample/*sample*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;row&lt;/span&gt; &amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rows&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;world&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;row&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;row&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt; &amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cells&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;row&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;get &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tiles&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cell&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cells&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rows&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/alert&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Please split image to tiles&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, we compute the result with &lt;code&gt;wfc&lt;/code&gt; call, and then we iterate over it calling &lt;code&gt;draw&lt;/code&gt; for each cell.
The tile is retrieved from the &lt;code&gt;*tiles*&lt;/code&gt; variable, we&amp;rsquo;ve set in &lt;code&gt;sample.cljs&lt;/code&gt; when we split the image.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;draw&lt;/code&gt; function is simple - it accepts an image, coordinates where we need to draw it, the size, and the canvas&amp;rsquo; context.
Then it just draws the image:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;arr&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/Uint8ClampedArray.&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;image.data&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;place&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getImageData&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;size&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.set&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;place&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;arr&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.putImageData&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;place&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The result will probably look a bit different, but the general idea is the same:&lt;/p&gt;
&lt;p&gt;&lt;canvas id=&#34;sample_view&#34; width=&#34;192&#34; height=&#34;160&#34; style=&#34;background-color: #888&#34;&gt;&lt;/canvas&gt;
&lt;br&gt;
&lt;input type=&#34;file&#34; id=&#34;sample_input&#34; accept=&#34;image/*&#34;&gt;&lt;/input&gt;
&lt;br&gt;
&lt;button type=&#34;button&#34; id=&#34;split_to_tiles&#34;&gt;Split to tiles&lt;/button&gt;
&lt;br&gt;
&lt;br&gt;
&lt;canvas id=&#34;render_view&#34; width=&#34;256&#34; height=&#34;256&#34; style=&#34;background-color: #888&#34;&gt;&lt;/canvas&gt;
&lt;br&gt;
&lt;br&gt;
&lt;button type=&#34;button&#34; id=&#34;render&#34;&gt;Generate&lt;/button&gt;&lt;/p&gt;
&lt;script type=&#34;text/javascript&#34; src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/js/main.js&#34;&gt;&lt;/script&gt;
&lt;script&gt;
  window.onload = function() {
    wfc.core.init();
  }
&lt;/script&gt;
&lt;p&gt;You can use this image to try the whole process:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2022-05-10-wave-function-collapse-algorithm-in-clojurescript/coast.png&#34;
         alt=&#34;Figure 4: coast&#34;/&gt;&lt;figcaption&gt;
            &lt;p&gt;&lt;span class=&#34;figure-number&#34;&gt;Figure 4: &lt;/span&gt;coast&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Alternatively, you can try other samples, just beware that the tile size is fixed to 32x32 pixels.&lt;/p&gt;
&lt;h2 id=&#34;a-proper-demo&#34;&gt;A proper demo&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve actually omitted some more things on the JS side, as the post already got a bit to long even after we&amp;rsquo;ve finished the algorithm.
Things like configurable tile size, and custom world sizes, better error handling can be added, it&amp;rsquo;s just mostly the same stuff we already did for other buttons, and thus can get repetitive pretty quickly.
So instead I&amp;rsquo;ve set up a separate page with a better visuals, tile picker, editor, some additional examples to try, and more robust error handling.
You can try it &lt;a href=&#34;https://andreyor.st/wave-function-collapse/&#34;&gt;here&lt;/a&gt;.
And a bit more polished code can be found in the &lt;a href=&#34;https://gitlab.com/andreyorst/wave-function-collapse&#34; target=&#34;_blank&#34;&gt;repo&lt;/a&gt; for that demo page.&lt;/p&gt;
&lt;p&gt;I know that this isn&amp;rsquo;t how ClojureScript is used in production, but it&amp;rsquo;s still nice that you can build such pages pretty quickly, using your favorite language.
In the future I&amp;rsquo;ll probably learn some proper frontend related stuff, like Lumen or re-frame, but this is a thing for another time.
Hope this was an interesting read!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I&amp;rsquo;m saying lisp as in the language not as in concrete implementation.
To be clear, I&amp;rsquo;ve worked my way thru SICP, and mostly used Racked or GNU Guile, not Common Lisp, so I&amp;rsquo;m not biased on what is lisp, and I accept Clojure as a valid dialect, even if some may disagree.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;This includes &lt;a href=&#34;https://gitlab.com/andreyorst/love-fabrik&#34; target=&#34;_blank&#34;&gt;LÖVE Fabrik&lt;/a&gt;, &lt;a href=&#34;https://andreyor.st/posts/2020-10-15-raymarching-with-fennel-and-love/&#34;&gt;raymarching&lt;/a&gt;, &lt;a href=&#34;https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/&#34;&gt;raycasting&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;This is the approach I&amp;rsquo;ve taken when I&amp;rsquo;ve implemented my first Scheme-like language, condition-system, a library for asynchronous programming, raymarching algorithm, and many other projects.
I think I find this approach fascinating because when the thing finally works, and I go and look how it should be done, and see that I&amp;rsquo;ve got some things right, it gives me a lot of joy.
This also trains to think outside of the box, and solve problems that you don&amp;rsquo;t exactly know how to solve.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Wave Function Collapse Algorithm in ClojureScript&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 10 May 2022 08:20:00 +0300</pubDate>
    </item><item>
      <title>Lazy sequences and iterators</title>
      <link>https://andreyor.st/posts/2021-10-09-lazy-sequences-and-iterators/</link>
      <guid>https://andreyor.st/posts/2021-10-09-lazy-sequences-and-iterators/</guid>
      <description>&lt;p&gt;Today’s topic will be about lazy sequences and how these are different from iterators.
I’ve wanted to make an article on this topic for some time, but unfortunately, there was no good way to show the differences using a single language (that I know), because usually, languages stick to one of those things.
But since I’ve been into library writing lately, I wrote a lazy sequence library for the Fennel language, and because Fennel compiles to Lua, it makes Lua a great candidate for this article.&lt;/p&gt;
&lt;p&gt;Lua has first-class support for iterators, as it is kind of a central paradigm very closely related to tables.
And because iterators are so common in Lua, &lt;a href=&#34;https://lunarmodules.github.io/Penlight/libraries/pl.seq.html&#34; target=&#34;_blank&#34;&gt;some libraries&lt;/a&gt; even treat them as sequences.
However, iterators are not sequences, even though they can be used similarly.
And proper sequences also can be created from tables much like iterators and would have similar use cases, without some problems that iterators have.
So today we’ll look into Lua iterators, and lazy sequences, and will try to understand their differences.&lt;/p&gt;
&lt;h2 id=&#34;iterators-in-lua&#34;&gt;Iterators in Lua&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s begin by understanding what iterators are, and what key features they provide.&lt;/p&gt;
&lt;p&gt;In Lua, iterators are usually higher-order functions, produced by another function, based on its input.
A standard way to get an iterator over a table is to call &lt;code&gt;pairs&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next, t, k = pairs({a = 1, b = 2, c = 3})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lua supports multiple return values, so calling pairs returns us the iterator function as the first value, a table (our original table in this case), that we&amp;rsquo;re going to iterate as the second value, and the starting key, which in our case is &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Calling this &lt;code&gt;get_next&lt;/code&gt; function, and passing it our table &lt;code&gt;t&lt;/code&gt;, and the key &lt;code&gt;k&lt;/code&gt;, we get back a pair of values, representing the key and a value associated with that key:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next(t, k) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- b	2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We then can use the returned key as an input to the next call to &lt;code&gt;get_next&lt;/code&gt; and get the next key-value pair, repeating the process until &lt;code&gt;get_next&lt;/code&gt; returns &lt;code&gt;nil&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next(t, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;b&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- c	3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next(t, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;c&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- a	1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next(t, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;nil&lt;/code&gt; means our table is exhausted, and no more keys are present in it.
The order may be different for you, as it depends on hashing.&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;get_next&lt;/code&gt; is a &lt;em&gt;stateless iterator&lt;/em&gt; - it doesn&amp;rsquo;t have any hidden state inside it, which means, that it can be reused.
For example, we can pass a different table to the &lt;code&gt;get_next&lt;/code&gt; function, and it will work on it without any problem:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next({f = 42, g = 27}, &lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- g	27&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This pattern is quite common, so Lua has such a function in its standard library, it is called &lt;code&gt;next&lt;/code&gt; and is a basis for all table iterators created with &lt;code&gt;pairs&lt;/code&gt;.
In addition to &lt;code&gt;pairs&lt;/code&gt;, Lua provides another iterator constructor called &lt;code&gt;ipairs&lt;/code&gt;, which is used to iterate over sequential tables, and it works similarly to &lt;code&gt;pairs&lt;/code&gt; except uses integers as input keys.&lt;/p&gt;
&lt;p&gt;While stateless iterators are good, it&amp;rsquo;s not always efficient, and sometimes not even possible to create a stateless iterator.
For example, opening a file in Lua and calling &lt;code&gt;lines&lt;/code&gt; method on it creates an iterator over this file, which is a stateful iterator that can be exhausted, i.e. you can call it only so many times as there are lines in the file.
Let&amp;rsquo;s create a file &lt;code&gt;example.txt&lt;/code&gt; with the following contents, and create an iterator over it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;line 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;line 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;line 3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;file = io.open(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;example.txt&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;r&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next_line = file:lines()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next_line() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- line 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next_line() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- line 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next_line() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- line 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_next_line() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that even though we&amp;rsquo;re calling the &lt;code&gt;get_next_line&lt;/code&gt; function without any arguments, like the file, or the line number, it always returns the next line of the file.
This is an example of a stateful iterator, which we can only use once - even if we call the &lt;code&gt;lines&lt;/code&gt; method on the file object again, the returned iterator will be exhausted:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_get_next_line = file:lines()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_get_next_line() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This happens because the state is held in the file handle itself, so we need to reopen the file to get a new iterator.
Because of this you usually want to open the file, walk it, use or cache needed lines, and close the resource, ideally doing all of this in a protected call.&lt;/p&gt;
&lt;p&gt;And lastly, let&amp;rsquo;s create our own stateful iterator, that keeps its state in the closure.
For the purposes of this example, let&amp;rsquo;s create a &lt;code&gt;range&lt;/code&gt; iterator, that can create various ranges based on initial input:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--range-iterator&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;range&lt;/span&gt;(lower, upper, step)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; lower, upper, step = lower &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; 0, upper &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; math.huge, step &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; tmp = lower
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lower = lower + step
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; tmp &amp;lt; upper &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To keep it simple I&amp;rsquo;ve left some corner cases out, but this is basically the idea for a range iterator.
When we call &lt;code&gt;range&lt;/code&gt;, local variables &lt;code&gt;lower&lt;/code&gt;, &lt;code&gt;upper&lt;/code&gt;, and &lt;code&gt;step&lt;/code&gt; are created based on given arguments or their default values.
Then an anonymous function is returned, which refers to these local variables as closures, and sets the &lt;code&gt;lower&lt;/code&gt; variable to a new value each time it is called:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r = range(1, 4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r() &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see, when we exhaust our iterator it returns &lt;code&gt;nil&lt;/code&gt;, similarly to iterators created with &lt;code&gt;pairs&lt;/code&gt; or file iterators.
Thanks to this, we can use it in Lua&amp;rsquo;s &lt;code&gt;for&lt;/code&gt; statement:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; range(1, 10, 3) &lt;span style=&#34;font-weight:bold&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  print(x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So now, when we more or less know what iterators are, and how they&amp;rsquo;re defined, let&amp;rsquo;s discuss their key properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Iterators are lazy,&lt;/li&gt;
&lt;li&gt;Stateless iterators accept some kind of state (usually an object and a key) as arguments to produce the next key-value pair, and hence can be reused,&lt;/li&gt;
&lt;li&gt;Stateful iterators are like cursors, and can&amp;rsquo;t be reused unless created anew.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Laziness is a very good property of iterators - it allows us to create actual infinite streams of data, computed on demand.
For example, we can open really huge, or even infinite files, and read those line by line without consuming more memory than is actually needed to hold a single line.
Alternatively, as was shown with the &lt;code&gt;range&lt;/code&gt; iterator above, we can create an infinite range, by not supplying an upper border for it, and it will use the &lt;code&gt;math.huge&lt;/code&gt; value, which is &lt;code&gt;inf&lt;/code&gt; in Lua.
So if Lua had arbitrary precision math, the range would grow to infinity, but in the case of this function, it will just overflow again and again.&lt;/p&gt;
&lt;p&gt;However, while laziness is an extremely handy and important part of iterators, their benefits pretty much end on it.
Iterator is basically a one-shot thing - you create it, use it until it is exhausted, or you&amp;rsquo;ve accomplished what you wanted to do with them, and then you never use the same iterator again.
This is due to the fact, that iterators were not meant to be shared - you can&amp;rsquo;t tell if an iterator is stateless or stateful, and if it is a stateful iterator, there&amp;rsquo;s no safe way to share it.
Someone can exhaust it, and later users will not get any values.
Stateless iterators are less dangerous to share, but the usefulness of this is also significantly lower, as you need to pass the context along with an iterator.&lt;/p&gt;
&lt;p&gt;All of this can be summarized to one point - iterators are not a data structure.
And while this is not a bad thing, the usefulness of the iterator is limited because of this.
So what if we wanted to share an iterator, and also make sure, that it doesn&amp;rsquo;t have problems with stateful iterators, and can be used as a data structure?
That&amp;rsquo;s where lazy sequences come in handy!&lt;/p&gt;
&lt;h2 id=&#34;lazy-sequences&#34;&gt;Lazy Sequences&lt;/h2&gt;
&lt;p&gt;What are sequences?
Think of a lazy sequence as a &lt;a href=&#34;https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list&#34; target=&#34;_blank&#34;&gt;singly-linked list&lt;/a&gt;, with the difference that the tail may not be an actual cell, but a special kind of lazily evaluated cell.
In order to create a sequence, we need to implement a so-called &lt;code&gt;cons&lt;/code&gt; cell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cons&lt;/span&gt; (head, tail)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; (ht)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; ht &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; tail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Conses are an old term that comes from the LISP language and basically represents a pair.
It&amp;rsquo;s a data structure that holds two elements - a value and a pointer to the next value or a cons cell.
This is usually illustrated with these boxes:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2021-10-09-lazy-sequences-and-iterators/cons-list.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;These stacked boxes represent a single cons cell - a pair of boxes, each referring to a value.
The first box refers to &lt;code&gt;1&lt;/code&gt;, and the second box refers to another cons cell, which in turn refers to &lt;code&gt;2&lt;/code&gt;, and finally to nothing, indicating the end of the list.
This data structure suits our task quite well, but you may notice that our implementation isn&amp;rsquo;t exactly a data structure, but a function.
So how do we work with it then?&lt;/p&gt;
&lt;p&gt;We need two primitive operations.
In LISP these are historically called &lt;code&gt;car&lt;/code&gt; and &lt;code&gt;cdr&lt;/code&gt;, but it&amp;rsquo;s not meaningful to use these names in the context of Lua, so let&amp;rsquo;s call them &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;first&lt;/span&gt; (cell)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; cell(&lt;span style=&#34;font-weight:bold&#34;&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rest&lt;/span&gt; (cell)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; cell(&lt;span style=&#34;font-weight:bold&#34;&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since our cons cell is a function of one argument with &lt;code&gt;if&lt;/code&gt; statement in it, &lt;code&gt;first&lt;/code&gt; will pass &lt;code&gt;true&lt;/code&gt; to it, to get the first element, and &lt;code&gt;rest&lt;/code&gt; will pass &lt;code&gt;false&lt;/code&gt; to get the other element of a cons cell.
Here&amp;rsquo;s a quick demonstration:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--non-lazy-list&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;list = cons(1, cons(2, cons(3, &lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1 -&amp;gt; 2 -&amp;gt; 3 -&amp;gt; nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(list) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(list))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve created a &lt;code&gt;list&lt;/code&gt; variable, that holds a single-linked list with values &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;.
And the final value is &lt;code&gt;nil&lt;/code&gt;, which is needed to indicate the end of the list since the last cons cell must refer to nothing.
However, this list is not lazy just yet.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s recap how iterators achieve laziness.
Iterators produce the next value only when you call them, which makes them very similar to generators by nature.
However, the key difference from lazy sequences is that all previous results are thrown away and not kept with the iterator.&lt;/p&gt;
&lt;p&gt;So how we can achieve laziness in our sequences?
We can try a naive approach of wrapping arguments into functions, and realizing them when a value is requested:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lazy_cons&lt;/span&gt; (headf, tailf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; (ht)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; ht &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; headf()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; tailf()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, when constructing a list, instead of passing the elements directly, we need to pass some functions that will return the list&amp;rsquo;s elements:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy_list = lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;realize head&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 1 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;realize tail&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 2 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Because the interface is the same, we can use &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt; to get values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rest(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize tail&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can see, that when we&amp;rsquo;re calling &lt;code&gt;first&lt;/code&gt; on our &lt;code&gt;lazy_list&lt;/code&gt; it realizes the value, and then returns it.
This is very close to our goal, but we&amp;rsquo;re not there yet.
The problem is, that if we call &lt;code&gt;first&lt;/code&gt; on &lt;code&gt;lazy_list&lt;/code&gt; again, it will call the realization function again and again without caching the result, which is not right:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To solve this issue, we&amp;rsquo;ll need to rewrite &lt;code&gt;lazy_cons&lt;/code&gt; in a such way, that it will realize our cell only once, and cache the result somehow.
This can be done by creating mutable closures, but I think there&amp;rsquo;s a better way, that will also allow us to do more interesting stuff later.
And it is also kinda hard to differentiate if the closure is uninitialized or the realization set it to &lt;code&gt;nil&lt;/code&gt;.
So instead we can use a clever metatable trick to realize cons cell contents upon access:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lazy_cons&lt;/span&gt; (headf, tailf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; cell = {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;realize&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; head, tail = headf(), tailf()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;realized&lt;/span&gt; (_, ht)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; ht &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; tail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; setmetatable(cell, {__call = realized})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; setmetatable(cell, {__call = &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; (_, ht) &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; realize()(ht) &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Basically, we create a table &lt;code&gt;cell&lt;/code&gt;, to which we set a metamethod &lt;code&gt;__call&lt;/code&gt; that works similarly to the function that is returned by &lt;code&gt;cons&lt;/code&gt;, except not quite.
Note the &lt;code&gt;realize()(ht)&lt;/code&gt; call in this metamethod - it calls the &lt;code&gt;realize&lt;/code&gt; function first, then invokes the resulting function.
The &lt;code&gt;realize&lt;/code&gt; function is defined above, and this function resets the &lt;code&gt;__call&lt;/code&gt; metamethod to another function, that uses cached values.
Now using &lt;code&gt;first&lt;/code&gt; on a such cell will work as expected:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy_list = lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;realize head&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 1 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;realize tail&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 2 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- realize tail&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rest(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It realizes the cell and then caches the results in a closure, so when we call &lt;code&gt;first&lt;/code&gt; on this cell later, we get the same values every time.
Now we can create and manipulate lazy sequences with only these three basic functions!
Here&amp;rsquo;s our &lt;code&gt;list&lt;/code&gt; &lt;a href=&#34;#code-snippet--non-lazy-list&#34;&gt;example from above&lt;/a&gt;, but now lazy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy_list = lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;first&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 1 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;second&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 2 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; lazy_cons (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;third&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 3 &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And we can inspect it with the same &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt; functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- first&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(lazy_list)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- third&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(lazy_list)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s pretty much it!
We have a way of constructing lazy sequences via a very primitive &lt;code&gt;lazy_cons&lt;/code&gt; function, and anonymous functions as arguments.
The usefulness of this may not be obvious, so let&amp;rsquo;s see some more examples of how this can be utilized before we move on.&lt;/p&gt;
&lt;h3 id=&#34;more-examples&#34;&gt;More examples&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s create a lazy sequence that works similarly to the &lt;code&gt;range&lt;/code&gt; &lt;a href=&#34;#code-snippet--range-iterator&#34;&gt;iterator we did earlier&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;range_seq&lt;/span&gt;(lower, upper, step)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; lower, upper, step = lower &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; 0, upper &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; math.huge, step &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; lower &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; tmp = lower + step
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; tmp &amp;lt; upper &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; range_seq(tmp, upper, step)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; cons(&lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;, &lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A bit more verbose, but notice that this is no longer a stateful thing!
Instead, it is a recursive function, which returns a self-referencing cons cell, which calls itself with changed arguments.&lt;/p&gt;
&lt;p&gt;A recursion?
How&amp;rsquo;s it lazy then?&lt;/p&gt;
&lt;p&gt;The thing is, that it&amp;rsquo;s not even a recursion!
The next recursion step will only happen when a cell is realized, and it will simply produce another lazy cell, which will not go to the next recursion step immediately.
And even if Lua had no tail call optimization it would still work just fine, as it acts more like a trampoline, and the call stack never actually grows.
Here&amp;rsquo;s how we can see that our &lt;code&gt;range_seq&lt;/code&gt; is working:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r = range_seq(1, 4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(r)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(rest(r))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And for infinite ranges we can drop as many values before working with the range:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r = range_seq()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;for&lt;/span&gt; i=1,1000000 &lt;span style=&#34;font-weight:bold&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- let&amp;#39;s drop some elements&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  r = rest(r)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(r) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1000000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(r)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 1000001&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a quite common pattern when working with infinite sequences to drop some values before working with them.
So if we want to create an infinite range, that starts from a given value,  we can write a &lt;code&gt;drop&lt;/code&gt; function, which will produce a new lazy sequence without first &lt;code&gt;n&lt;/code&gt; elements in it.&lt;/p&gt;
&lt;p&gt;Another thing to note is that it is a bit tedious to write nested &lt;code&gt;rest&lt;/code&gt; calls every time, so let&amp;rsquo;s iterate over this range instead, with the power of recursion:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;loop&lt;/span&gt; (seq, f)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; head, tail = first(seq), rest(seq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  f(head)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; tail &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    loop(tail, f)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;loop(range_seq(0, 10, 2), print)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This &lt;code&gt;loop&lt;/code&gt; function accepts a sequence and calls a supplied &lt;code&gt;f&lt;/code&gt; function on each element for side effects.
A very similar concept exists in most functional languages, and it is called mapping, so let&amp;rsquo;s create a lazy map function:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--lazy-map&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;map&lt;/span&gt; (seq, f)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; first(seq) &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; lazy_cons(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; f(first(seq)) &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; map(rest(seq), f) &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; cons(&lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;, &lt;span style=&#34;font-weight:bold&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now with this &lt;code&gt;map&lt;/code&gt; function, we can not only apply a function to every element of the sequence, but we can also collect the results into another sequence.
Let&amp;rsquo;s write a function that prints every element of the given sequence, and pass the result of the &lt;code&gt;map&lt;/code&gt; call to it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print_seq&lt;/span&gt; (seq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  io.stdout:write(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;[&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;print_seq&lt;/span&gt; (seq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; first(seq) &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      io.stdout:write(first(seq), &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      print_seq(rest(seq))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  print_seq(seq)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  io.stdout:write(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\b\b&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;square&lt;/span&gt; (x) &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; x * x &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print_seq(map(range_seq(0, 10), square))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, to demonstrate that this is really a lazy &lt;code&gt;map&lt;/code&gt;, let&amp;rsquo;s add a &lt;code&gt;print&lt;/code&gt; call to &lt;code&gt;square&lt;/code&gt;, and store the resulting sequence to a variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;square&lt;/span&gt; (x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  print(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;square of &amp;#34;&lt;/span&gt;..x..&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; is &amp;#34;&lt;/span&gt;..x * x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; x * x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;squares = map(range_seq(0, 10), square)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nothing is printed until we realize some elements of our sequence:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(squares)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- prints: square of 0 is 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(squares)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- prints: square of 2 is 4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(rest(rest(squares)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- prints nothing, as the result was already realized&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that while this is still just a (kinda special) function, it behaves just like a real linked list, and thus represents a proper data structure.
Although it&amp;rsquo;s &lt;em&gt;a bit&lt;/em&gt; clumsy to use directly, as shown with the &lt;code&gt;map&lt;/code&gt; example, we can build a library around this concept, that will abstract the construction of a lazy sequence away from the user.
And that&amp;rsquo;s exactly what I did.&lt;/p&gt;
&lt;h2 id=&#34;lazy-seq-library&#34;&gt;Lazy-seq library&lt;/h2&gt;
&lt;p&gt;It should be pointed out that the code above is a very rough example of a lazy sequence implementation.
I think it&amp;rsquo;s fine for explaining the idea, but there are some edge cases that are not handled properly.
For example, the &lt;a href=&#34;#code-snippet--lazy-map&#34;&gt;&lt;code&gt;map&lt;/code&gt; function we&amp;rsquo;ve written is not fully lazy&lt;/a&gt;, as it actually realizes its first element, and the &lt;code&gt;range_seq&lt;/code&gt; will not properly work for negative ranges.
And the &lt;code&gt;lazy_cons&lt;/code&gt; is not really the most useful abstraction - instead of using it directly, a much more handy &lt;code&gt;lazy_seq&lt;/code&gt; function should be created, that would accept another function, which in turn would return any kind of sequence.
To address these shortcomings I&amp;rsquo;ve created a &lt;a href=&#34;https://gitlab.com/andreyorst/lazy-seq&#34; target=&#34;_blank&#34;&gt;lazy-seq&lt;/a&gt; library, which has a lot of functions to create and manipulate lazy sequences.&lt;/p&gt;
&lt;p&gt;Now, it&amp;rsquo;s a &lt;a href=&#34;https://fennel-lang.org/&#34; target=&#34;_blank&#34;&gt;Fennel&lt;/a&gt; library, written in Fennel, and aimed toward it first.
That is, mainly due to the fact that this library mimics Clojure&amp;rsquo;s vision of lazy sequences and ports a lot of functions from its core namespace.
But the core principles are exactly the same as described above, and you still can use the library from Lua, just like we did earlier!&lt;/p&gt;
&lt;p&gt;Except the semantics are expanded a bit - there are handy constructors for creating lazy sequences from tables or strings, supporting both sequential and associative tables.
And, as you may remember from the previous section since our cons cells are secretly tables underneath, sequences defined by this library also implement various metamethods, like &lt;code&gt;__len&lt;/code&gt;, &lt;code&gt;__index&lt;/code&gt;, and so on, for more convenient usage.&lt;/p&gt;
&lt;p&gt;Proper versions of &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;range&lt;/code&gt; already exist in this library, along with other functions, which can be used as building blocks for creating all kinds of sequences.
For example, here&amp;rsquo;s how one would create an infinite Fibonacci sequence using the lazy variant of the &lt;code&gt;map&lt;/code&gt; function in Lua:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy = require &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first, rest, map = lazy.first, lazy.rest, lazy.map
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;concat, drop, lazy_seq = lazy.concat, lazy.drop, lazy[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bc = require &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;bc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;add&lt;/span&gt; (a, b) &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; a + b &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fib = concat(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {bc.new(0), bc.new(1)},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  lazy_seq(&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; map(add, rest(fib), fib) &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;first(drop(400, fib))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- 176023680645013966468226945392411250770384383304492191886725992896575345044216019675&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the example above I&amp;rsquo;m also using the &lt;a href=&#34;https://web.tecgraf.puc-rio.br/~lhf/ftp/lua/#lbc&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;lbc&lt;/code&gt; library&lt;/a&gt; which provides arbitrary precision math for Lua to illustrate that you can compute as many Fibonacci numbers as you want (try dropping the first 100000 elements for example)
That&amp;rsquo;s a bit verbose still, but not as verbose as the manually created lazy linked list from previous sections.
And note that the &lt;code&gt;concat&lt;/code&gt; function, which is used to concatenate sequences, also works with tables, as shown in the example above.
All sequence manipulating functions in the &lt;code&gt;lazy-seq&lt;/code&gt; library work with tables, as tables are implicitly converted to sequences.&lt;/p&gt;
&lt;p&gt;In Fennel, the same code is even more compact because we can use the &lt;code&gt;lazy-cat&lt;/code&gt; macro instead of using &lt;code&gt;concat&lt;/code&gt; and &lt;code&gt;lazy-seq&lt;/code&gt;, and thanks to anonymous function shorthand:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;drop&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;import-macros&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lazy-cat&lt;/span&gt;} &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bc&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;bc&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;global&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fib&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;lazy-cat &lt;/span&gt;[(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bc.new&lt;/span&gt; 0) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bc.new&lt;/span&gt; 1)] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fib&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fib&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;drop &lt;/span&gt;400 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fib&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; 176023680645013966468226945392411250770384383304492191886725992896575345044216019675&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note however that macros are a Fennel-only feature, not available in Lua, so where in Fennel you would write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;import-macros&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;lazy-cat &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lazy-seq&lt;/span&gt;} &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;lazy-cat &lt;/span&gt;[1 2 3] [4 5 6])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lazy-seq&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;I&amp;#39;m lazy&amp;#34;&lt;/span&gt;) [1 2 3]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Lua it would be:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy = require &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;concat, lazy_seq = lazy.concat, lazy[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;concat(lazy_seq(&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; {1, 2, 3} &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;), lazy_seq(&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; {4, 5, 6} &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy_seq(&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; () print &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;I&amp;#39;m lazy&amp;#34;&lt;/span&gt; {1, 2, 3} &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code is fully equivalent to fennel code, except that macros write all these anonymous functions for you.&lt;/p&gt;
&lt;p&gt;But macros are not the only unique feature in Fennel, the other one is destructuring.
I&amp;rsquo;ll not go into details here, but destructuring is kinda similar to pattern matching, and it allows specifying data structure shape and binding values of the data structure to variables defined by that shape.
So similarly to how you would destructure a table, thanks to &lt;code&gt;__len&lt;/code&gt; and &lt;code&gt;__index&lt;/code&gt; metamethods, destructuring works on lazy sequences:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;range&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; &amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rest&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;range &lt;/span&gt;10)] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rest&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; 0 1 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; [3 4 5 6 7 8 9]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just make sure you don&amp;rsquo;t use &lt;code&gt;&amp;amp;&lt;/code&gt; destructuring with infinite sequences&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.
And more than that, sequences define the &lt;code&gt;__pairs&lt;/code&gt; metamethod, and thus support creating stateless iterators created with &lt;code&gt;pairs&lt;/code&gt;!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fennel = require &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fennel&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- for pretty printer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lazy = require &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;squares = lazy.map(&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; (x) &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; x * x &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;, {1, 2, 3, 4, 5})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;for&lt;/span&gt; k,v &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; pairs(squares) &lt;span style=&#34;font-weight:bold&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  print(fennel.view(k), v)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- @seq(4 9 16 25) 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- @seq(9 16 25)   4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- @seq(16 25)     9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- @seq(25)        16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- @seq()          25&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve come a full circle.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve required the &lt;code&gt;fennel&lt;/code&gt; library, to provide the pretty-printed representation of a sequence for a better illustration.
You can see that on each step of iteration we see the shorter and shorter sequence.
Sequence automatically pretty-printed in the REPL like this, but that&amp;rsquo;s one of Fennel&amp;rsquo;s features, that I&amp;rsquo;ve &lt;a href=&#34;https://andreyor.st/posts/2021-01-09-pretty-printing-for-fennel-language/&#34;&gt;previously written about&lt;/a&gt;, and implemented a very similar linked list there, so if you&amp;rsquo;re interested in that, you can find some more info there.
And viewing such a sequence in this way really shows us that it is nothing else but a data structure!&lt;/p&gt;
&lt;p&gt;Unlike tables, a stateless iterator over a sequence uses the tail of the sequence as the key to getting the next element, because the iterator is simply built on top of &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt;.
It ends when it reaches the empty cons cell, which is at the end of each sequence.
The only exceptions are infinite sequences, which don&amp;rsquo;t have empty cons at the end as, well, they&amp;rsquo;re infinite.
So calling &lt;code&gt;pairs&lt;/code&gt; and iterating over infinite sequences should have another guard for terminating iteration.
Or, you can limit the size of the sequence with &lt;code&gt;take&lt;/code&gt;, &lt;code&gt;take-while&lt;/code&gt;, and other filtering functions.&lt;/p&gt;
&lt;p&gt;There are also various functions like &lt;code&gt;line-seq&lt;/code&gt; which accepts a file handle, so here&amp;rsquo;s what happens when we call it on a file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;line-seq &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;doall&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;with-open &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.open&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;example.txt&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:r&lt;/span&gt;)] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doall &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;line-seq &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; @seq(&amp;#34;line 1&amp;#34; &amp;#34;line 2&amp;#34; &amp;#34;line 3&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We have to realize the whole sequence before &lt;code&gt;with-open&lt;/code&gt; automatically closes the file handle, but you can lazily work with this sequence while you&amp;rsquo;re inside of the &lt;code&gt;with-open&lt;/code&gt; block without any issues.
In contrary to the iterator, we can re-use this sequence of lines, as no results have been thrown away.&lt;/p&gt;
&lt;p&gt;Finally, as I&amp;rsquo;ve mentioned, lazy sequences can be generated from tables with the &lt;code&gt;seq&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;seq&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;seq &lt;/span&gt;[1 2 3])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; @seq(1 2 3)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;seq &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; @seq(&amp;#34;a&amp;#34; &amp;#34;b&amp;#34; &amp;#34;c&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we pass in an associative table we get a bit different representation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;seq &lt;/span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 3})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; @seq([&amp;#34;a&amp;#34; 1] [&amp;#34;c&amp;#34; 3] [&amp;#34;b&amp;#34; 2])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These sequences are all lazy because &lt;code&gt;seq&lt;/code&gt; creates a wrapper around an iterator over the table.
This means, that if you change the table before the sequence is fully realized, your resulting sequence will have updated elements much like an iterator would produce them.
This is not recommended, and instead &lt;a href=&#34;https://gitlab.com/andreyorst/itable&#34; target=&#34;_blank&#34;&gt;immutable tables&lt;/a&gt; a better be used to produce sequences, and in general.
And since sequences themselves are immutable and persistent this is a win-win.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;lazy-seq&lt;/code&gt; library also provides a lot of other functions, like filtering, restructuring, modifying, and combining infinite sequences.
It&amp;rsquo;ll take a lot of time to list all of them here, so I&amp;rsquo;d recommend you to read the documentation if you&amp;rsquo;re interested.
But as an example of what you can do, here we create an infinite sequence of random numbers, filter out only those which are perfect squares, and group those by 2:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;take &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;filter &lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;repeatedly&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;partition&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lazy-seq&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rands&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;repeatedly&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.random&lt;/span&gt; 0 64))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;perfect-squares&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;filter &lt;/span&gt;#(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;0 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.sqrt&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$&lt;/span&gt;) 2)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rands&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rand-square-pairs&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;partition&lt;/span&gt; 2 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;perfect-squares&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;take &lt;/span&gt;10 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rand-square-pairs&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; @seq(@seq(64 16)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(4 0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(64 4)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(4 0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(0 4)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(4 64)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(16 0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(0 64)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(16 4)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;      @seq(16 36))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that we did all operations on an infinite sequence, and then only used &lt;code&gt;take&lt;/code&gt; to get the first 10 elements of it.
This is a common pattern when working with infinite sequences - create something infinite, filter or modify it, and take the needed amount of elements.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s all I wanted to say about lazy sequences and their relationship with iterators.
But of course, there&amp;rsquo;s much more to it, as there are a lot more functions for sequence manipulation I&amp;rsquo;ve left uncovered because it would simply be too long for an article.
The main point I&amp;rsquo;ve wanted to share is that sequences are similar to iterators, but don&amp;rsquo;t have some downsides that iterators have.
Someone can argue that these downsides are features, but I think sequences still have their uses.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s recap what we have learned about sequences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequences are a data structure, with very important properties of persistence and immutability.&lt;/li&gt;
&lt;li&gt;Sequences are lazy, much like iterators, but they cache their values for later re-use.&lt;/li&gt;
&lt;li&gt;Things that required stateful iterators, can be done with stateless sequences by using laziness and recursion.&lt;/li&gt;
&lt;li&gt;Sequences, implemented by &lt;code&gt;lazy-seq&lt;/code&gt; library, support common table operations, making it easy to integrate lazy computation into existing Lua code.&lt;/li&gt;
&lt;li&gt;Operations on infinite sequences can be easily composed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope you got a good understanding of lazy sequences, and I got you interested in at least trying them out!
Despite being a Fennel library, &lt;a href=&#34;https://gitlab.com/andreyorst/lazy-seq&#34; target=&#34;_blank&#34;&gt;lazy-seq&lt;/a&gt; can be used from Lua just fine, you only need to compile it to Lua first, which is not hard to do, given that Fennel itself is also just a library.
But I suggest using this library with Fennel, as it adds a bit more facilities, like pretty-printing of your data structures, and provides macros for a more concise code.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;: As of &lt;a href=&#34;https://git.sr.ht/~technomancy/fennel/tree/HEAD/changelog.md#100--2021-11-14&#34; target=&#34;_blank&#34;&gt;Fennel v1.0.0&lt;/a&gt; the &lt;code&gt;__fennelrest&lt;/code&gt; metamethod was added, and &lt;code&gt;&amp;amp;&lt;/code&gt; destructuring works on infinite sequences.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Lazy sequences and iterators&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 09 Oct 2021 21:34:00 +0300</pubDate>
    </item><item>
      <title>Condition system for Fennel language and Lua runtime</title>
      <link>https://andreyor.st/posts/2021-08-08-condition-system-for-fennel-language-and-lua-runtime/</link>
      <guid>https://andreyor.st/posts/2021-08-08-condition-system-for-fennel-language-and-lua-runtime/</guid>
      <description>&lt;p&gt;Not long ago I posted a small article on a &lt;a href=&#34;https://andreyor.st/posts/2021-04-17-condition-system-in-clojure/&#34;&gt;Condition System in Clojure language&lt;/a&gt;.
In that article, I was mostly trying to understand what a condition system is, and how it can enhance error handling in the code I write.
Since that time, I’ve understood this system a lot better, by actually trying it in the Common Lisp language, the place where it came from, as far as I know.
And you know what it means (because you’ve read the title) - it’s time to implement such a system for Fennel!&lt;/p&gt;
&lt;p&gt;I like Fennel a lot, it’s a really cool language to tinker with - it’s small, slick, Lua runtime is actually really versatile, and can be bent to your needs without a lot of extra work.
But the reason I’ve decided to implement this library for Fennel, and not for Lua itself, is because of a feature that is not available in Lua but is available in Fennel - lisp macros.
The library is already available for everyone to use: &lt;a href=&#34;https://gitlab.com/andreyorst/fennel-conditions&#34; target=&#34;_blank&#34;&gt;fennel-conditions&lt;/a&gt;, and in this article, I’ll do a deep dive into the details behind the implementation.&lt;/p&gt;
&lt;h2 id=&#34;condition-system&#34;&gt;Condition system?&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s actually explain what the condition system is.&lt;/p&gt;
&lt;p&gt;Condition system is a feature of the Common Lisp language, that can be very roughly described as resumable exceptions.
Though, while this isn&amp;rsquo;t the only way you can use the condition system, it is the main reason I&amp;rsquo;ve decided to port this system into Fennel, as Lua error handling is not the best, and we can do better.
You still can use a condition system for basic control flow to some extent, though not as versatile as in Common Lisp, I don&amp;rsquo;t think that Fennel really needs these features.&lt;/p&gt;
&lt;p&gt;In Common Lisp, a condition is an object, which represents a &lt;em&gt;certain event&lt;/em&gt;.
You can bind handlers for particular events, and trigger these handlers by &lt;em&gt;raising&lt;/em&gt; a condition.
This may sound similar to the classic exception model found in languages like Java, but it has one major difference.
Exceptions are a two-part system, while the condition system is three-part.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s really hard to come up with a small example to show what condition the system has to offer that exceptions don&amp;rsquo;t, and I don&amp;rsquo;t really know Common Lisp well enough to write it.
So I encourage you to read &lt;a href=&#34;https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html&#34; target=&#34;_blank&#34;&gt;Chapter 19 from the Practical Common Lisp book&lt;/a&gt; which covers this topic in detail before continuing reading.
There&amp;rsquo;s also a good article on the &lt;a href=&#34;http://wiki.c2.com/?CommonLispConditionSystem&#34; target=&#34;_blank&#34;&gt;wiki.c2.com&lt;/a&gt;.
If you&amp;rsquo;ve read that before or just now, and didn&amp;rsquo;t understand what the condition system is, hopefully, you&amp;rsquo;ll get the idea in this post, but I can&amp;rsquo;t guarantee that.&lt;/p&gt;
&lt;p&gt;If I were to describe the main difference between this system from classic exceptions, I would say that when you write a code that throws an exception, you have to deal with this exception &lt;em&gt;somewhere else&lt;/em&gt;.
And the place where you handle that exception is the place where the program would continue running after the handling is done.&lt;/p&gt;
&lt;p&gt;In the condition system, the place where you&amp;rsquo;ve thrown such an exception can be the place where the program continues running if you use some special constructs, that allow you to return to that place.&lt;/p&gt;
&lt;h3 id=&#34;an-example&#34;&gt;An example&lt;/h3&gt;
&lt;p&gt;In the spirit of the Practical Common Lisp book example mentioned above, here&amp;rsquo;s a rather naive Clojure code that parses a log file, and uses exceptions to indicate that parsing failed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;log-parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.java.io&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:import&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.lang&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ExceptionInfo&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Checks if the line contains basic date-time, a service name, and a message
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;separated by colons.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt; #&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([12]\d\d\d-[01]\d-[0-3]\d)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time-re&lt;/span&gt; #&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([01]\d:[0-5]\d:[0-5]\d\.\d+)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service-re&lt;/span&gt; #&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([^:]+)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message-re&lt;/span&gt; #&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;(.*)&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-matches &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-pattern &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;T&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message-re&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Extract `date`, `time`, `service` name, and a `message` from a `line`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:time&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Return a vector of parsed lines, each element being a map with the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  following keys: `:date`, `:time`, `:service`, `:message`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ExceptionInfo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*out*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*err*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;prn &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%s:%s&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;))))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-log&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;file&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;with-open &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io/reader&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;file&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;parse &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;line-seq &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Yes, there are more idiomatic ways of doing this task in Clojure, but for the purposes of demonstrating the difference between exceptions and conditions this will do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So this code checks if the line has a valid format, and if not it will throw an exception.
And here&amp;rsquo;s a problem - if a single line is invalid, we will get no results at all.
We can avoid that by moving &lt;code&gt;try&lt;/code&gt; into our iteration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Return a vector of parsed lines, each element being a map with the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  following keys: `:date`, `:time`, `:service`, `:message`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mapv&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ExceptionInfo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*out*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*err*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;prn &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%s: %s&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will correctly parse our log, but we will have &lt;code&gt;nil&lt;/code&gt; in place of each malformed line.
This can once again be fixed by using &lt;code&gt;keep&lt;/code&gt; instead of &lt;code&gt;mapv&lt;/code&gt;, but what if we can&amp;rsquo;t afford to lose any lines?
Maybe we can fix the line and parse it one more time?
This again can be done by modifying our anonymous function, so it would catch the exception, try to fix the line, and then call &lt;code&gt;parse-line&lt;/code&gt; again.
And if we can&amp;rsquo;t fix the line, we will log it as before, and don&amp;rsquo;t add it to the resulting vector:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;We don&amp;#39;t care when this happened, just want to know what happened.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-matches &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;.*:([^:]+):([^:]+)$&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1970-01-01T00:00:00.000:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Return a vector of parsed lines, each element being a map with the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  following keys: `:date`, `:time`, `:service`, `:message`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;[]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ExceptionInfo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*out*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*err*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;prn &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;%s: %s&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But then again, when we will use &lt;code&gt;parse-line&lt;/code&gt; in some other part of the program we will need to do all this stuff over and over.
The main problem here is that we&amp;rsquo;re building concrete ways to recover from error as a part of the calling function that is meaningful only in the context of the &lt;code&gt;parse-line&lt;/code&gt; and the responsibility for recovering should really be on it.
Condition system can help us write more generic code, that knows how it can recover from the error, but let the recovery happen on the calling side.
Consider the following Fennel code that uses &lt;a href=&#34;https://gitlab.com/andreyorst/fennel-conditions&#34; target=&#34;_blank&#34;&gt;fennel-conditions&lt;/a&gt; library:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--fennel-example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;make-condition&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:fennel-conditions&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;import-macros&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;define-condition&lt;/span&gt;} &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:fennel-conditions&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;define-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Checks if the line starts with basic date-time followed by a colon and a word.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([12]%d%d%d%-[01]%d%-[0-3]%d)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([01]%d:[0-5]%d:[0-5]%d%.%d%d%d)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;([^:]+)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;(.*)&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;string.match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;T&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service-pat&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message-pat&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Extract `date`, `time`, `service` name, and a `message` from a `line`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;) {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:time&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;make-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ignore-val&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ignore-val&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;We don&amp;#39;t care when this happens, just want to know what happened.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;string.match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:([^:]+):([^:]+)$&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1970-01-01T00:00:00.000:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;parse &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Return a vector of parsed lines, each element being a map with the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;following keys: `:date`, `:time`, `:service`, `:message`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;icollect&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ipairs&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-log&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;file&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;with-open &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.open&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;file&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:r&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;parse &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;icollect&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:lines&lt;/span&gt;)] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For those unfamiliar with condition system special forms or Fennel itself, &lt;code&gt;handler-bind&lt;/code&gt; is something similar to &lt;code&gt;try&lt;/code&gt; with the difference that the only way to recover from the error is by calling &lt;code&gt;invoke-restart&lt;/code&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.
&lt;code&gt;with-open&lt;/code&gt; is the same thing as in Clojure or Common Lisp, and &lt;code&gt;icollect&lt;/code&gt; is something similar to &lt;code&gt;mapv&lt;/code&gt; in Clojure, but it&amp;rsquo;s a macro, that accepts body form instead of function.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s different about this code from the code in Clojure&amp;rsquo;s example?
Let&amp;rsquo;s look at &lt;code&gt;parse-line&lt;/code&gt; functions in Clojure and in Fennel:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Clojure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Extract `date`, `time`, `service` name, and a `message` from a `line`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:time&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Fennel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Extract `date`, `time`, `service` name, and a `message` from a `line`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;well-formed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;) {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:time&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:service&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;message&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;make-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;})))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ignore-val&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ignore-val&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apart from some syntactic differences, you can see that both functions are throwing an error - by using &lt;code&gt;throw&lt;/code&gt; in Clojure, and &lt;code&gt;error&lt;/code&gt; in Fennel.
However, while the Clojure version only throws the error, the Fennel version does some additional things.
What we&amp;rsquo;re interested in here is the &lt;code&gt;restart-case&lt;/code&gt; macro, which is a special macro from the condition system, that allows us to return to its location when we want to handle the error.&lt;/p&gt;
&lt;p&gt;So when &lt;code&gt;parse-line&lt;/code&gt; throws an error in Clojure, JWM unwinds the stack, and we basically leave this function completely.
We then catch the exception in the &lt;code&gt;parse-log&lt;/code&gt; function, which can&amp;rsquo;t do anything about it but handle it right there or let it fall through.&lt;/p&gt;
&lt;p&gt;However, when &lt;code&gt;parse-line&lt;/code&gt; throws an error in Fennel, we don&amp;rsquo;t actually unwind the stack at all.
Instead, we travel up the dynamic scope, in search of a handler bound to this error by the &lt;code&gt;handler-bind&lt;/code&gt; macro in the &lt;code&gt;parse&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This handler tries to fix the line, and calls &lt;code&gt;(invoke-restart :reparse-line fixed-line)&lt;/code&gt;.
&lt;code&gt;invoke-restart&lt;/code&gt; is another special function in condition system - it once again travels through the second dynamic scope, and finds that there&amp;rsquo;s a restart named &lt;code&gt;:reparse-line&lt;/code&gt; bound by &lt;code&gt;restart-case&lt;/code&gt; in the &lt;code&gt;parse-line&lt;/code&gt; function.
This restart is executed right there, despite the fact that we&amp;rsquo;ve &amp;ldquo;left&amp;rdquo; the lexical scope of that function to find a handler, and its value is used in the original &lt;code&gt;parse-line&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;So the order in which all functions are called looks something like that:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2021-08-08-condition-system-for-fennel-language-and-lua-runtime/calls.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;In other words, when we wrote &lt;code&gt;parse-line&lt;/code&gt; in Clojure, we only defined how to detect malformed lines and how to signal an error.
When we wrote &lt;code&gt;parse-line&lt;/code&gt; in Fennel, we not only specified what to do if the line is malformed but also provided concrete ways to recover, that are meaningful in the context of this function.&lt;/p&gt;
&lt;p&gt;When we caught the exception in Clojure, we had no choice but to handle it right there.
In Fennel, when we caught the exception we could decide whether we can handle the error, and how we can handle it without &lt;em&gt;leaving&lt;/em&gt; the original call.&lt;/p&gt;
&lt;p&gt;I hope this illustration is clear enough to demonstrate the main difference between exception and condition.
Again, yes, there are better ways of dealing with this particular error in Clojure, but what I wanted to illustrate is that there&amp;rsquo;s no way of achieving the same flexibility of the condition system with just exceptions.
I&amp;rsquo;ve covered possible ways of implementing a rather basic condition system in pure Clojure in my previous post &lt;a href=&#34;https://andreyor.st/posts/2021-04-17-condition-system-in-clojure/&#34;&gt;Condition System in Clojure language&lt;/a&gt;, so it&amp;rsquo;s not entirely impossible, but has its own shortcomings.
With that in mind let&amp;rsquo;s talk about the implementation of this system.&lt;/p&gt;
&lt;h2 id=&#34;the-implementation&#34;&gt;The implementation&lt;/h2&gt;
&lt;p&gt;As I&amp;rsquo;ve mentioned previously, the dynamic scope is what allows us to travel through our code without transferring the control.
However, Lua doesn&amp;rsquo;t have a dynamic scope builtin into the language.
So how is this possible?&lt;/p&gt;
&lt;p&gt;Well, as you might know, Lua has tables, and these tables are dynamic and mutable.
So theoretically, we could create a table, that is available globally, properly encapsulate it, and use it as our dynamic scope.
And that&amp;rsquo;s exactly what the fennel-conditions library does.&lt;/p&gt;
&lt;p&gt;However, implementing dynamic scope via tables is not enough.
First of all, we need to manage the dynamic scope in a sensible way.
Second, we need some way of actually traveling through the lexical scope to the point where the dynamic scope was created, once we know where we need to move after all handling has been done.
And finally, the scope should be thread-local, and even though Lua doesn&amp;rsquo;t have threads, it has coroutines, which can act as threads, so we should maintain dynamic scope with respect to this aspect of the language.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s begin by listing things that will be implemented in the condition system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;condition objects - conditions are objects, that can have inheritance, and can embed additional information inside to convey more info about a conditional situation when needed.
Condition objects are defined with &lt;code&gt;define-condition&lt;/code&gt; macro, and a particular instance is created from a base condition object with &lt;code&gt;make-condition&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handler-case&lt;/code&gt;, &lt;code&gt;handler-bind&lt;/code&gt;, &lt;code&gt;restart-case&lt;/code&gt; - macros for creating new frame of the dynamic scope, in which the handlers, and restarts are bound to condition objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As well as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cerror&lt;/code&gt; - a macro for raising a condition that can be ignored by invoking special &lt;code&gt;continue&lt;/code&gt; restart.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ignore-errors&lt;/code&gt; - a macro for suppressing all errors, similarly to &lt;code&gt;try&lt;/code&gt; with a catchall clause that does nothing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unwind-protect&lt;/code&gt; - a macro for catching all errors, similar to &lt;code&gt;try&lt;/code&gt; with just a &lt;code&gt;finally&lt;/code&gt; clause.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these macros share the very common part about setting up and cleaning the dynamic scope, as well as some &lt;code&gt;pcall&lt;/code&gt; trickery to make it all work, which makes it a good entry point to understand what&amp;rsquo;s happening under the hood.&lt;/p&gt;
&lt;h3 id=&#34;the-dynamic-scope&#34;&gt;The dynamic scope&lt;/h3&gt;
&lt;p&gt;Beware, this is going to get really messy.
Dynamic scoping is a foreign concept for Lua, so we have to deal with it ourselves, and ensure that it is correct.
But before we begin, I should illustrate the structure of the library:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fennel-conditions/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├─ impl/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├─ condition-system.fnl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  ├─ debugger.fnl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│  └─ utils.fnl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├─ init.fnl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└─ init-macros.fnl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;init.fnl&lt;/code&gt;, and &lt;code&gt;init-macros.fnl&lt;/code&gt; at the top level are the main entry points for runtime functions, and macros.
These modules depend on the &lt;code&gt;impl/condition-system.fnl&lt;/code&gt; module - the library&amp;rsquo;s private API.
Which in turn uses &lt;code&gt;impl/debugger.fnl&lt;/code&gt; that holds implementation of the interactive debugger, and &lt;code&gt;impl/utils.fnl&lt;/code&gt; which stores common functions, used by condition system and debugger.
The main things we&amp;rsquo;re interested in are &lt;code&gt;init.fnl&lt;/code&gt;, &lt;code&gt;init-macros.fnl&lt;/code&gt;, and &lt;code&gt;impl/condition-system.fnl&lt;/code&gt; - the meat and bones of the library.&lt;/p&gt;
&lt;p&gt;The dynamic scope is stored in the &lt;code&gt;impl.condition-system&lt;/code&gt; module and this module is required every time we need to access the dynamic scope.
Lua has a system for caching required modules, so this is a rather cheap operation and this way we don&amp;rsquo;t need to expose dynamic scope in the global scope.&lt;/p&gt;
&lt;p&gt;This is how the dynamic scope table is defined in &lt;code&gt;impl.utils&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;metadata&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:fennel&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dynamic-scope&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:set&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:fnl/docstring&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Dynamic scope for the condition system.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;Dynamic scope is a maintained table where handlers and restarts are
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;stored thread-locally.  Thread name is obtained with
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`coroutine.running` call and each thread holds a table with the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;following keys `:handlers`, `:restarts`, and `:current-context`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;Handlers and restarts itselves are tables.&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s nothing special really, just an ordinary table, but the documentation string mentions several interesting points.
First, that this is a maintained table, meaning that it should not be modified manually.
Second, that it stores scopes in thread-local contexts, meaning that each thread will have its own dynamic scope table.
Each such table in turn has a table for handlers, a separate table for restarts, and some &lt;code&gt;current-context&lt;/code&gt; field, which we will cover a bit later.&lt;/p&gt;
&lt;p&gt;So, to illustrate how the dynamic scope may look at some point of the program running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;thread: 0x564cab9a12a8&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba2c6e0&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabb01500&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba2c6e0&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba5ccf0&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restarts&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                               &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ignore-val&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ignore&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabb01580&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                               &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fixed-line&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;reparse-line&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabaa7a10&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;use-value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba5cd30&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the state of the dynamic scope when we enter the &lt;code&gt;restart-case&lt;/code&gt; macro and do all setups, in the &lt;a href=&#34;#code-snippet--fennel-example&#34;&gt;fennel&lt;/a&gt; code from the example section.
There&amp;rsquo;s quite a lot happening here - lots of nested tables with similar internal structures, and even some empty tables.&lt;/p&gt;
&lt;p&gt;First thing you can spot is that the outermost table has a key &lt;code&gt;&amp;quot;thread: 0x564cab9a12a8&amp;quot;&lt;/code&gt; which holds the table with &lt;code&gt;handlers&lt;/code&gt; and &lt;code&gt;restarts&lt;/code&gt;.
This is the thread-local dynamic scope, representing the main thread.
Inside of it in the table under the &lt;code&gt;handlers&lt;/code&gt; key, we see a table with a &lt;code&gt;handler&lt;/code&gt; key holding a table with a condition, (which is actually just another table&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;), and a function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba2c6e0&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabb01500&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba2c6e0&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba5ccf0&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This table corresponds to all dynamic scopes set up with &lt;code&gt;handler-bind&lt;/code&gt; macros.
But as you can see here, it has a &lt;code&gt;parent&lt;/code&gt; key, that holds another very similar table, but as you might remember, there was only one &lt;code&gt;handler-bind&lt;/code&gt; instance in the &lt;a href=&#34;#code-snippet--fennel-example&#34;&gt;example code&lt;/a&gt; - why there are two tables?
Here&amp;rsquo;s a quick refresher of how &lt;code&gt;handler-bind&lt;/code&gt; was used:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that there are two separate entries for &lt;code&gt;MalformedLogEntry&lt;/code&gt; condition.
Each such entry creates a separate frame in the dynamic scope, which results in two nested tables as shown above.
This is done this way because the handlers are bound sequentially, and their order in the handler bind determines the order of how they will be called.
We directly use this property, by writing the first handler in such a way, that if the line can&amp;rsquo;t be fixed with &lt;code&gt;fix-line&lt;/code&gt; function, we are not calling &lt;code&gt;invoke-restart&lt;/code&gt; and the condition falls through to the next handler.
This handler in turn calls &lt;code&gt;:ignore&lt;/code&gt; restart, and successfully recovers from the error.
Now let&amp;rsquo;s look at the dynamic scope stored under &lt;code&gt;:restarts&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ignore-val&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ignore&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabb01580&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fixed-line&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;reparse-line&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabaa7a10&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;use-value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba5cd30&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very similarly, each level stores a &lt;code&gt;:restart&lt;/code&gt; table, with an argument list, name, and the function itself.
Under the &lt;code&gt;:parent&lt;/code&gt; key, the very similar table is stored, holding the next restart.
Since our code defined three restarts, we get a table of the depth of three.
One might wonder, why this is necessary, restarts are selected and not tried in order.
While this is true, nothing prevents you from creating two restarts with the same name:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will create the following table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;use-value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabb01380&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:args&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;use-value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restart&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564cabaa5b40&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You then will be able to choose which restart to call via the interactive debugger interface.
But more about that later.&lt;/p&gt;
&lt;p&gt;Now that we have a rough understanding of how dynamic scopes are composed inside, let&amp;rsquo;s look at how those are really constructed.&lt;/p&gt;
&lt;h3 id=&#34;constructing-dynamic-scope-for-handlers&#34;&gt;Constructing dynamic scope for handlers&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s look at the &lt;code&gt;handler-bind&lt;/code&gt; macro invocation once again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Much like &lt;code&gt;let&lt;/code&gt;, it accepts a vector of bindings - a condition object, and a function that will be called.
Similarly to &lt;code&gt;let&lt;/code&gt; it binds sequentially, but doesn&amp;rsquo;t override bindings, but creates a set of nested scope frames to store each binding.
Then it executes the body in the context of this dynamic scope.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at the actual implementation and break it down:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;gensym &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;gensym &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:scope&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt; &amp;#39;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;do&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assert-compile&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; 2) 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;expected even number of signal/handler bindings&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; 1 -2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assert-compile&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sym?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;function-form?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler must be a function&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt; `(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assert &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;condition object must not be nil&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         `(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-bind&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;}}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pack&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack#&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;utils&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pcall-handler-bind&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind#&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-system&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; ,(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;current-scope&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;)) ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers#&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the entirety of &lt;code&gt;handler-bind&lt;/code&gt; macro, minus the docstring and some comments, and while the actual body that gets spliced into the program&amp;rsquo;s source code is not very big, the setup looks somewhat complicated.
So let&amp;rsquo;s break it down.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;gensym &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;gensym &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:scope&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt; &amp;#39;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;do&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assert-compile&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; 2) 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;expected even number of signal/handler bindings&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, we create some unique names that we will use both at compile-time, and then at runtime.
You might remember the &lt;code&gt;:target&lt;/code&gt; key in tables, that represented the dynamic scope.
This key is holding this &lt;code&gt;target&lt;/code&gt; symbol, which we define at run time, but we need a way of putting it into the dynamic scope at compile-time, that&amp;rsquo;s why it&amp;rsquo;s defined here.
I&amp;rsquo;ll explain why it&amp;rsquo;s an important key soon.&lt;/p&gt;
&lt;p&gt;Next up is the &lt;code&gt;scope&lt;/code&gt;, this is an instance of dynamic scope we&amp;rsquo;re going to construct at compile time.
&lt;code&gt;binding-len&lt;/code&gt; is just to avoid small pieces of code duplication, and the last one - &lt;code&gt;setup&lt;/code&gt; is the code that will fill the missing bits of our dynamic scope at runtime.&lt;/p&gt;
&lt;p&gt;After &lt;code&gt;let&lt;/code&gt;, we&amp;rsquo;re doing a check, that the &lt;code&gt;binding-vec&lt;/code&gt;, a vector that holds condition objects and their handlers, has an even amount of values.
We can&amp;rsquo;t properly construct the dynamic scope if a handler is missing, so it&amp;rsquo;s a compile-time error.&lt;/p&gt;
&lt;p&gt;Now for the main part - the &lt;code&gt;for&lt;/code&gt; loop, which creates a set of instructions that will construct the dynamic scope:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-len&lt;/span&gt; 1 -2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binding-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;assert-compile&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sym?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;function-form?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler must be a function&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt; `(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assert &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;condition object must not be nil&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     `(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-bind&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                        ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt;}}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It does several things - first, it checks that the handler is either a symbol or a function form, i.e. a list that will evaluate a function definition.
Next it inserts the runtime assertion, that verifies that the &lt;code&gt;condition-object&lt;/code&gt; is not &lt;code&gt;nil&lt;/code&gt;.
And finally, the &lt;code&gt;tset&lt;/code&gt; call is inserted, that will populate current &lt;code&gt;scope&lt;/code&gt;&amp;rsquo;s &lt;code&gt;:handlers&lt;/code&gt; table with a new table, that refers to the original table via the &lt;code&gt;:parent&lt;/code&gt; key.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve might notice that the loop actually goes backward.
This is done to preserve the correct order when constructing nested tables.
As the dynamic scope is constructed as a set of nested tables, the order of construction has to be reversed, so the travel order gets preserved.
But this code doesn&amp;rsquo;t actually construct the scope, it just describes how to construct it.
The last portion of the macro is what gets spliced into the user&amp;rsquo;s code, so let&amp;rsquo;s look at it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; ---- 8&amp;lt; ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;`(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pack&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack#&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;utils&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pcall-handler-bind&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind#&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-system&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; ,(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;current-scope&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;)) ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers#&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;re finally setting some of those symbols, we&amp;rsquo;ve defined before!
The &lt;code&gt;,target {}&lt;/code&gt; thing, is a way to make sure we get a unique object address that we can later compare, to determine if we&amp;rsquo;ve reached the correct destination when &amp;ldquo;unwinding&amp;rdquo;.
Next, we import some helper functions, like &lt;code&gt;pack#&lt;/code&gt; and &lt;code&gt;pcall-handler-bind#&lt;/code&gt; - the first one is a portable &lt;code&gt;table.pack&lt;/code&gt; implementation, and the last one is a runtime part of &lt;code&gt;handler-bind&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After that, we&amp;rsquo;re calling something like &lt;code&gt;current-scope&lt;/code&gt;.
It is a commonly used part of all macros, so I&amp;rsquo;ve put it into another macro.
In short, it just returns the current thread&amp;rsquo;s dynamic scope or creates it if it doesn&amp;rsquo;t exist yet.
And right after that, you can see that we&amp;rsquo;re caching original handlers right before &lt;code&gt;,setup&lt;/code&gt;.
This &lt;code&gt;,setup&lt;/code&gt; will splice in all that setup we&amp;rsquo;ve been constructing at compile, that will populate the current scope with new tables.
And then we&amp;rsquo;re calling &lt;code&gt;pcall-handler-bind#&lt;/code&gt; function with all necessary info.&lt;/p&gt;
&lt;p&gt;So this code from &lt;a href=&#34;#code-snippet--fennel-example&#34;&gt;the example&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:reparse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:ignore&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;icollect&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:lines&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;uses &lt;code&gt;handler-bind&lt;/code&gt; macro we&amp;rsquo;ve just examined.
Let&amp;rsquo;s look at what this code expands to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target_1_&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pack&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack_10_auto&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fennel-conditions.impl.utils&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pcall-handler-bind&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind_11_auto&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fennel-conditions.impl.condition-system&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cs_3_auto&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fennel-conditions.impl.condition-system&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread_4_auto&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coroutine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coroutine.running&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tostring&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;coroutine.running&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cs_3_auto&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;dynamic-scope&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread_4_auto&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_5_auto&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_5_auto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_5_auto&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; {} &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restarts&lt;/span&gt; {}}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cs_3_auto&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;dynamic-scope&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread_4_auto&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_5_auto&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_5_auto&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers_12_auto&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handlers&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assert &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;condition object must not be nil&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handlers&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;malformed log entry: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ignore&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handlers&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target_1_&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assert &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;condition object must not be nil&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handlers&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fix-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;reparse-line&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fixed-line&lt;/span&gt;)))}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handler-bind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;handlers&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target_1_&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind_11_auto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;hashfn&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pack_10_auto&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;icollect&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:lines&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                               (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope_2_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target_1_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers_12_auto&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quite a lot of code, and there are even more things going on when we&amp;rsquo;re calling the &lt;code&gt;pcall-handler-bind&lt;/code&gt; function!
But you can see that it does exactly what I&amp;rsquo;ve described above - requires some API functions, creates a thread-local scope, sets it up, and wraps our code with the &lt;code&gt;pack&lt;/code&gt; function, for later execution.
Let&amp;rsquo;s now look at what &lt;code&gt;pcall-handler-bind&lt;/code&gt; does.&lt;/p&gt;
&lt;h3 id=&#34;implementing-control-transfer-via-protected-calls&#34;&gt;Implementing control transfer via protected calls&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;pcall-handler-bind&lt;/code&gt; function is defined in the library&amp;rsquo;s private API:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall-handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Call `f` in given `scope` and pass result up to `target`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;Restore dynamic scope handlers to `orig-handlers`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pcall&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:current-context&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orig-handlers&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ok&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unpack&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handled&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res.type&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res.condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.handlers.parent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.restarts.parent&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Looks pretty simple, but this is because we delegate most of the work to other functions.&lt;/p&gt;
&lt;p&gt;It starts with calling &lt;code&gt;f&lt;/code&gt; in a protected call and immediately removes &lt;code&gt;current-context&lt;/code&gt; from the scope, and sets &lt;code&gt;handlers&lt;/code&gt; to the original handlers, which we&amp;rsquo;ve stored back at the macro side.
Then, if the function exited successfully, we just return the results by unpacking those (for keeping &lt;code&gt;nils&lt;/code&gt; in multiple value returns).
But when the function didn&amp;rsquo;t succeed, we expect a set of certain things as a return.&lt;/p&gt;
&lt;p&gt;For those unfamiliar with &lt;code&gt;match&lt;/code&gt; - it&amp;rsquo;s a pattern-matching macro from Fennel standard library.
It accepts an expression, and a pair of patterns and their respective bodies to run, if the result of an expression matches this pattern.
The first pattern here is &lt;code&gt;{:state :handled :target target}&lt;/code&gt;, meaning that the function &lt;code&gt;f&lt;/code&gt; returned a table with a key &lt;code&gt;:state&lt;/code&gt; holding a &lt;code&gt;:handled&lt;/code&gt; value, and a non-nil &lt;code&gt;:target&lt;/code&gt; key that is equal to the value of &lt;code&gt;target&lt;/code&gt;, passed as function argument.
The table returned in this case usually looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handled&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition-object&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MalformedLogEntry&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x564caba2c6e0&amp;gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this case, we &lt;code&gt;raise&lt;/code&gt; the condition object stored in the result from calling &lt;code&gt;f&lt;/code&gt;, with a correct type, meaning that the type is &lt;code&gt;:error&lt;/code&gt;, we raise it as an error, or if it&amp;rsquo;s a &lt;code&gt;:warning&lt;/code&gt;, as a warning and so on.
We&amp;rsquo;ll look at &lt;code&gt;raise&lt;/code&gt; in a moment, but for now, all you need to know is that it will throw the condition object further up.&lt;/p&gt;
&lt;p&gt;If the pattern contained &lt;code&gt;:state&lt;/code&gt; &lt;code&gt;:error&lt;/code&gt; we check if we have more handlers up the dynamic scope, and if we do, we throw the result as is, so it could be handled.
If not, that means that we&amp;rsquo;re already at a top level, so we convert this to Lua error with a message.&lt;/p&gt;
&lt;p&gt;In all other cases this is an error that we want to throw up, as we can&amp;rsquo;t do anything about it because it is either not a conditional situation or &lt;code&gt;target&lt;/code&gt; doesn&amp;rsquo;t match the expected one.&lt;/p&gt;
&lt;p&gt;So the basic idea here is that we&amp;rsquo;re ensuring that the function will either succeed or fail as we expect, and if it fails in an unexpected way, we just rethrow the error.
Lua doesn&amp;rsquo;t have a way to rethrow the stack traces, but it&amp;rsquo;s a small price to pay here.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at &lt;code&gt;raise&lt;/code&gt; now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Raises `condition-object&amp;#39; as a condition of `condition-type&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`condition-object&amp;#39; must not be `nil&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assert &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;condition must not be nil&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;current-thread&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dynamic-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dynamic-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; {} &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restarts&lt;/span&gt; {}}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dynamic-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope.handlers.handler-type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-bind&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope.current-context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.target&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.parent&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.target&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.parent&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handlers&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:warning&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-warning&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function does something interesting with &lt;code&gt;current-context&lt;/code&gt;.
As you saw in &lt;code&gt;pcall-handler-bind&lt;/code&gt;, we&amp;rsquo;ve set the &lt;code&gt;current-context&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;, but &lt;code&gt;raise&lt;/code&gt; actually check it.
Why?&lt;/p&gt;
&lt;p&gt;This is because the condition can be raided inside the handler.
In such a case, we need to unwind the stack to the point where we were in the handler.
So each invocation of the &lt;code&gt;handle&lt;/code&gt; function sets the &lt;code&gt;current-context&lt;/code&gt; field, and this field is cleared when we exit the handler.
This stack unwinding needs to be done in order to avoid infinite recursion, which will result in a stack overflow error.&lt;/p&gt;
&lt;p&gt;After that is done, we branch on the condition type and raise the condition accordingly.
For the purposes of this article let&amp;rsquo;s look at conditions of error type only, by looking at the &lt;code&gt;raise-error&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-error&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_G.condition-system-use-debugger?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-debugger&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;compose-error-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;) 2))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In case the condition is not handled it&amp;rsquo;s raised as a Lua error unless the debugger feature was enabled.
The condition itself is raised with the &lt;code&gt;raise-condition&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-condition&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;where&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handled&lt;/span&gt; &amp;amp;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:restarted&lt;/span&gt; &amp;amp;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res&lt;/span&gt; 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s the &lt;code&gt;handle&lt;/code&gt; innovation, mentioned above.
The result can be either a table with &lt;code&gt;:handled&lt;/code&gt; or &lt;code&gt;:restarted&lt;/code&gt; states, each of which tells the condition system what to do next.
Even though the condition is handled this result gets thrown up as an error because we actually need to tell the condition system that the condition was handled, and differentiate it from a successful return from the function.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s look at how conditions are handled.&lt;/p&gt;
&lt;h3 id=&#34;handling-conditions&#34;&gt;Handling conditions&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;handle&lt;/code&gt; function looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;?scope&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Handle the `condition-object&amp;#39; of `type*&amp;#39; and optional `?scope`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;Finds the `condition-object&amp;#39; handler in the dynamic scope.  If found,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;calls the handler, and returns a table with `:state` set to
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;`:handled`, and `:handler` bound to an anonymous function that calls
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;the restart.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;current-thread&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dynamic-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-handler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;?scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope.handlers&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;thread-scope&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:current-context&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.handler-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-case&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handled&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unpack&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition-object&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:type&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:handler-bind&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;unpack&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scope.parent&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;wrong handler-type: &amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:state&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:message&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;no handler bound for condition: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-name&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;condition-object&lt;/span&gt;})))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s dive into it.&lt;/p&gt;
&lt;p&gt;After getting the current thread and the scope, we call &lt;code&gt;find-handler&lt;/code&gt;.
For now, it&amp;rsquo;s enough to know, that it takes a condition object, and walks the dynamic scope comparing this object to handlers.
Next up, if the handler were found, we set the &lt;code&gt;current-context&lt;/code&gt; to the handler&amp;rsquo;s scope.
This will ensure that we know where we last were before actually executing a handler, so we could unwind the stack to this point in case an error happens inside the handler.
This was a very painful thing to figure out when I worked on the implementation.&lt;/p&gt;
&lt;p&gt;After that, we branch on the handler type.
The &lt;code&gt;handler-case&lt;/code&gt; macro allows handling without calling &lt;code&gt;invoke-restart&lt;/code&gt;, so we just return a table with &lt;code&gt;:state&lt;/code&gt; set to &lt;code&gt;:handled&lt;/code&gt;, and a handler that actually does the handling.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;handler-bind&lt;/code&gt; is different - it requires handling with &lt;code&gt;invoke-restart&lt;/code&gt;, which, as you might remember throws an error to transfer control flow.
So if the &lt;code&gt;handler&lt;/code&gt; function exited normally, we go to the next &lt;code&gt;handle&lt;/code&gt; invocation, which will propagate the condition object to another handler up the stack.
This ensures that we can decline to handle a condition.&lt;/p&gt;
&lt;p&gt;If no handler is found the error is returned.&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2021-08-08-condition-system-for-fennel-language-and-lua-runtime/handling.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;A similar pattern occurs for other condition types, with the difference being that some may not return an actual error when unhandled.&lt;/p&gt;
&lt;p&gt;So how handlers are found?
The &lt;code&gt;find-handler&lt;/code&gt; function, which accepts a condition object and a handler type, will walk the scope comparing the given condition object to bound handlers.
However, condition objects actually support inheritance, so this gets a bit more complicated.
We need to look for a handler in the current scope, and if no handler is found, we need to get the parent from the condition object and search its handler in the same scope.
If no handler and no parent handler are to be found, we go to the next scope frame.&lt;/p&gt;
&lt;p&gt;Additionally, conditions may not be of the condition-object type, but be an arbitrary Lua value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-case&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;signal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.random&lt;/span&gt; 5))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (0 [] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:zero&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (1 [] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:one&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (2 [] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:two&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Condition&lt;/span&gt; [] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:else&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; an unnecessarily complicated equivalent of&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.random&lt;/span&gt; 5)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:zero&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:two&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:else&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice, that while I&amp;rsquo;m handling conditions as numbers, the catch-all condition object is specified as &lt;code&gt;Condition&lt;/code&gt;.
Let&amp;rsquo;s talk more about condition inheritance.&lt;/p&gt;
&lt;h3 id=&#34;condition-inheritance&#34;&gt;Condition inheritance&lt;/h3&gt;
&lt;p&gt;As was already mentioned, condition objects can have parent condition objects.
A parent can be explicitly set by using the &lt;code&gt;:parent&lt;/code&gt; key when defining a condition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;define-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MathError&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;define-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DivideByZero&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MathError&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;define-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;NegSquareRoot&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:parent&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MathError&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;make-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;NegSquareRoot&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.sqrt&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;div&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;make-condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DivideByZero&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;main&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-case&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; -1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MathError&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Can&amp;#39;t take square root of &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-case&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;div&lt;/span&gt; 2 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MathError&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;io.stderr&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:write&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Can&amp;#39;t divide by zero\n&amp;#34;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s an example of handling different errors through their common parent.
You can create hierarchical errors, which then can be handled with more granularity, or as a whole class of errors.&lt;/p&gt;
&lt;p&gt;But there are a bit more rules regarding inheritance.
All conditions raised with &lt;code&gt;error&lt;/code&gt; function will by default inherit from the &lt;code&gt;Error&lt;/code&gt; condition.
All conditions raised with &lt;code&gt;warn&lt;/code&gt; will inherit from a &lt;code&gt;Warning&lt;/code&gt; condition.
Both &lt;code&gt;Warning&lt;/code&gt; and &lt;code&gt;Error&lt;/code&gt; are inherited from the &lt;code&gt;Condition&lt;/code&gt; condition.&lt;/p&gt;
&lt;p&gt;This also applies to any arbitrary data you can throw with &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, or &lt;code&gt;signal&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-random-condition&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.random&lt;/span&gt; 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    0 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;an error&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    1 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;signal&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a signal&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    2 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;warn&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a warning&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raise-random-condition&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Error&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;caught an error&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Warning&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;caught a warning&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Condition&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;caught a condition&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;msg&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here all conditions are just Lua strings, but we still have some hierarchy.
Note that the order of handlers here is very important - placing the &lt;code&gt;(Condition [msg] (print &amp;quot;caught a condition&amp;quot; msg))&lt;/code&gt; as the first handler will prevent &lt;code&gt;Error&lt;/code&gt; and &lt;code&gt;Warning&lt;/code&gt; handlers from ever running.
It is very similar to &lt;code&gt;match&lt;/code&gt; in that regard - placing &lt;code&gt;_&lt;/code&gt; as the first pattern will make all other patterns unreachable.&lt;/p&gt;
&lt;p&gt;Another thing to point out is that Lua errors also inherit from &lt;code&gt;Error&lt;/code&gt; condition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-case&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Error&lt;/span&gt; [] 0))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is done for seamless integration with libraries that don&amp;rsquo;t use the condition system, or if your code did something wrong by mistake.&lt;/p&gt;
&lt;p&gt;However, the integration is not as seamless as it could be.
The point where it get&amp;rsquo;s not as good as it could be is when interfacing with the interactive debugger, provided by the library.&lt;/p&gt;
&lt;h3 id=&#34;the-debugger&#34;&gt;The debugger&lt;/h3&gt;
&lt;p&gt;Speaking of which, the debugger is not as featureful as in Common Lisp, but still provides a way to recover from an error, when the current scope allows for it.
Consider this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fennel&#34; data-lang=&#34;fennel&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cs.error&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Executing this code will raise a condition, which is not handled, so it gets propagated to a Lua error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runtime error: condition 10 was raised
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, if we set &lt;code&gt;_G.condition-system-use-debugger?&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, we&amp;rsquo;ll get this instead:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Debugger was invoked on unhandled condition: 10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;restarts (invokable by number or by name):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  1: [use-value] use-value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2: [throw    ] Throw condition as a Lua error
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debugger&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now every unhandled condition will invoke the debugger, which will provide you with available recovery options.
In the case of this example, there are two restarts bound - &lt;code&gt;use-value&lt;/code&gt;, bound by the &lt;code&gt;restart-case&lt;/code&gt; macro, and the other one is an automatically bound &lt;code&gt;throw&lt;/code&gt; restart, that will exit the debugger.&lt;/p&gt;
&lt;p&gt;By typing &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;use-value&lt;/code&gt; in the prompt, we&amp;rsquo;ll enter the next prompt, that asks for a value to use for a selected restart:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debugger&amp;gt;&amp;gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Provide inputs for use-value (args: [x]) (^D to cancel)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debugger:use-value&amp;gt;&amp;gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thus making the result of the expression to be &lt;code&gt;5&lt;/code&gt;, accordingly to the restart&amp;rsquo;s body.&lt;/p&gt;
&lt;p&gt;This debugger has no runtime penalty unless the condition was not handled.
So only When an unhandled condition pops to the top of the dynamic scope stack, the debugger begins its work.&lt;/p&gt;
&lt;p&gt;Debugger again traverses the scope, gathering all available restarts, and forms this interactive prompt, with each restart in order of their definition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;use-value (impostor)&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:do-something&lt;/span&gt; [] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2 3)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:do-something-else&lt;/span&gt; [] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;3 2 1)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that the &lt;code&gt;use-value&lt;/code&gt; restart was specified twice.
I&amp;rsquo;ve mentioned that this is possible, but it is meaningless unless we use a debugger.
Here&amp;rsquo;s what will be prompted to the user, if this code is executed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Debugger was invoked on unhandled condition: attempt to perform arithmetic on a nil value&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;restarts (invokable by number or by name):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  1: [use-value        ] use-value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2:                     use-value (impostor)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  3: [do-something     ] do-something
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  4: [do-something-else] do-something-else
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  5: [throw            ] Throw condition as a Lua error
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debugger&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that the first restart is indeed named &lt;code&gt;use-value&lt;/code&gt;, but the second one has no name, only its docstring is displayed.
This restart can be manually called by typing &lt;code&gt;2&lt;/code&gt; in the prompt - it will ask for the argument similarly to &lt;code&gt;use-value&lt;/code&gt; restart, but will negate it.
Other restarts are self-explanatory.&lt;/p&gt;
&lt;h2 id=&#34;ending-thoughts&#34;&gt;Ending thoughts&lt;/h2&gt;
&lt;p&gt;This should provide some information about this library&amp;rsquo;s internals.&lt;/p&gt;
&lt;p&gt;Seeing how many &lt;code&gt;pcall&lt;/code&gt; calls it does to transfer control flow around, and how it manages the dynamic stack, can make you think that it has not a very good performance.
And in fact, I would agree, the performance could be better.
But it&amp;rsquo;s not that bad.
For example, here&amp;rsquo;s a 10000000 invocations of Lua&amp;rsquo;s &lt;code&gt;error&lt;/code&gt; function inside a &lt;code&gt;pcall&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fennel&#34; data-lang=&#34;fennel&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;macro &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;times&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;os.clock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;s#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c#&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r#&lt;/span&gt; &lt;span style=&#34;&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;expr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c#&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Average time elapsed &amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;* &lt;/span&gt;1000 (&lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;s#&lt;/span&gt;)) &lt;span style=&#34;&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;times&lt;/span&gt; 1)) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; ms&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r#&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1 10000000]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;pcall error &lt;/span&gt;10))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      10000000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Average time elapsed 0.0002025262 ms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here&amp;rsquo;s an equivalent using condition system&amp;rsquo;s &lt;code&gt;error&lt;/code&gt; and &lt;code&gt;ignore-errors&lt;/code&gt; macro:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fennel&#34; data-lang=&#34;fennel&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local &lt;/span&gt;{&lt;span style=&#34;font-weight:bold&#34;&gt;: &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt;} (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;require &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:condition-system&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;time&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1 10000000]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ignore-errors&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;error &lt;/span&gt;10)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      10000000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Average time elapsed 0.0051841138 ms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s one order of magnitude difference in performance here, meaning that &lt;code&gt;ignore-errors&lt;/code&gt; is ~10 times slower than pure &lt;code&gt;pcall&lt;/code&gt;.
But the benefits, that the condition system provides, out-weight this cost, in my opinion.&lt;/p&gt;
&lt;p&gt;Also, a note on why I didn&amp;rsquo;t port the rest of Common Lisp&amp;rsquo;s condition system.
While this library is not a full port, I think it has all the necessary parts in the context of the Fennel language.
What I mean by that is, that since Fennel, for example, deliberately chose to avoid Lua&amp;rsquo;s &lt;code&gt;return&lt;/code&gt; special, I don&amp;rsquo;t think a condition system should provide &lt;code&gt;block&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt;, or &lt;code&gt;go&lt;/code&gt; specials.
I don&amp;rsquo;t have strong reasoning behind it, but I feel that the error handling part in Lua is what&amp;rsquo;s needed to be improved, thus this library is only aimed at fixing this part of the runtime.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;In Common Lisp there are more ways to recover from an error from the handler bound with &lt;code&gt;handler-bind&lt;/code&gt;, but &lt;code&gt;fennel-conditions&lt;/code&gt; library doesn&amp;rsquo;t implement all those ways.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Tables, tables, tables, tables, tables&amp;hellip; tables, and tables - that&amp;rsquo;s Lua at its best.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Condition system for Fennel language and Lua runtime&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sun, 08 Aug 2021 18:47:00 +0300</pubDate>
    </item><item>
      <title>Condition system in Clojure</title>
      <link>https://andreyor.st/posts/2021-04-17-condition-system-in-clojure/</link>
      <guid>https://andreyor.st/posts/2021-04-17-condition-system-in-clojure/</guid>
      <description>&lt;p&gt;A while ago I&amp;rsquo;ve watched this amazing talk: &lt;a href=&#34;https://www.youtube.com/watch?v=zp0OEDcAro0&#34; target=&#34;_blank&#34;&gt;Condition Systems in an Exceptional Language&lt;/a&gt; by Chris Houser.
And more recently I&amp;rsquo;ve found one interesting library called &lt;a href=&#34;https://github.com/IGJoshua/farolero&#34; target=&#34;_blank&#34;&gt;farolero&lt;/a&gt;, which provides a set of functions and macros that mimic Common Lisp&amp;rsquo;s condition system.
So I was generally interested in the topic and decided to give it a shot and try both approaches.
But before we can appreciate the condition system and its error handling capabilities, we need to look at how errors are generally handled in Clojure.
So let&amp;rsquo;s start with the classic Clojure/Java approach of throwing and catching exceptions.&lt;/p&gt;
&lt;h2 id=&#34;exception-based-error-handling&#34;&gt;Exception-based error handling&lt;/h2&gt;
&lt;p&gt;The examples in the talk are based on the examples from the book called &amp;ldquo;Practical Common Lisp&amp;rdquo;, and while these are great examples, I still find it a bit overburdened with details.
I think the main reason for this is that we have four functions to think about, each of which tries to take its part, and demonstrate how we could design such error handling in our application.
Sure this can provide a great way to show how we can handle errors on different levels, but it can also confuse a lot of people who don&amp;rsquo;t know about the condition system.
It was definitively confusing for me at first read at the very least, so let&amp;rsquo;s use a more simple example with one or two functions instead.
We can always add more complexity later if we want to expand.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say we want to parse a date string, and we want to check if the date is a correct leap date as well.
We can do this with this regular expression:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:const&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-pattern &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;(?:(?:(?:0[1-9]|1[0-9]|2[0-8])-(?:0[1-9]|1[012]))|(?:29|30|31)-(?:0[13578]|1[02])|(?:29|30)-(?:0[4,6,9]|11))-(?:19|[2-9][0-9])\d\d&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   #&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;|(?:29-02-(?:19|[2-9][0-9])(?:00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You don&amp;rsquo;t really need to dig into this regexp, all you need to know is that it handles dates formatted as &lt;code&gt;dd-MM-yyyy&lt;/code&gt;, and correctly detects leap dates.
Now we can write a function that parses the date string:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;import &lt;/span&gt;&amp;#39;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;java.time&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;LocalDate&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;import &lt;/span&gt;&amp;#39;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;java.time.format&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DateTimeFormatter&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Parse `date` string into Java `LocalDate`&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;LocalDate/parse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DateTimeFormatter/ofPattern&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;dd-MM-yyyy&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;invalid date&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, if our &lt;code&gt;date&lt;/code&gt; is a valid one, we &lt;code&gt;parse&lt;/code&gt; it to &lt;code&gt;LocalDate&lt;/code&gt;.
If &lt;code&gt;date&lt;/code&gt; is not valid, we throw an exception, because we don&amp;rsquo;t know how to deal with invalid dates at this level, so hopefully, the higher scope will &lt;code&gt;catch&lt;/code&gt; the exception and deal with it.&lt;/p&gt;
&lt;p&gt;Now, we can use this function to convert all valid dates and filter out invalid ones like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Exception&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; simple error logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; invalid date 29-02-2021&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; invalid date 12-34-5678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; =&amp;gt; (#object[java.time.LocalDate 0x194a4280 &amp;#34;2020-02-29&amp;#34;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we call this &lt;code&gt;keep&lt;/code&gt; we successfully parse the first date, but fail to parse other ones, because there&amp;rsquo;s no February 29th in 2021, and the last one is plain wrong, so we log it with &lt;code&gt;println&lt;/code&gt; and move on.
But let&amp;rsquo;s assume that we&amp;rsquo;re OK with this wrong leap date, we just want to transform it into March 1st of 2021.
Let&amp;rsquo;s write a function that checks if the given date is indeed February 29th, and transforms it.
If the date is not a leap one, we again throw an exception:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-((?::19|[2-9][0-9])\d\d)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;01-03-&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Wrong leap date: %s, using %s instead&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Not a leap date&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can try to re-parse the date of the initial parse has failed, but we also now have another exception to deal with, so we wrap everything in another &lt;code&gt;try&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; #(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Exception&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;try&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;catch&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Exception&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-message&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e&lt;/span&gt;)))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Wrong leap date: 29-02-2021, using 01-03-2021 instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Not a leap date 12-34-5678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; =&amp;gt; (#object[java.time.LocalDate 0x102d92c4 &amp;#34;2020-02-29&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;     #object[java.time.LocalDate 0x2b97cc1f &amp;#34;2021-03-01&amp;#34;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now one can say, that we&amp;rsquo;ve written the code, that successfully recovers from errors while parsing dates.
However, the problem here, is that we had to incorporate our error handling into the function we&amp;rsquo;re passing to &lt;code&gt;keep&lt;/code&gt; (in our case an anonymous function).
We may want to promote this to a named function and share it with some other places in our program, but such places may not be OK with converting wrong leap dates.
Or, the caller of this promoted function will not be OK with it returning &lt;code&gt;nil&lt;/code&gt;, when the date is invalid, and instead will have to do extra work around the function checking its return value.&lt;/p&gt;
&lt;p&gt;So we may find ourselves with functions like &lt;code&gt;parse-date-or-convert-leap&lt;/code&gt;, &lt;code&gt;parse-date-or-log-invalid&lt;/code&gt;, e.t.c., or with a lot of anonymous functions, all of which will share the &lt;code&gt;parse-date&lt;/code&gt; at it&amp;rsquo;s core.
And throwing exceptions may be a bit costly, as exceptions are expensive, so this may not be the optimal strategy in the first place.
So right now our options are either to write a lot of &lt;code&gt;try catch&lt;/code&gt; mess, duplicate code, or handle errors somehow differently.&lt;/p&gt;
&lt;p&gt;And actually, let&amp;rsquo;s think a bit more about this example.
We&amp;rsquo;re detecting and signaling the error inside the &lt;code&gt;parse-date&lt;/code&gt; function, but handling the actual error outside of this function.
This means that we&amp;rsquo;re not really recovering from the error in the function which signaled it, but rather in the caller scope of that function.
So outer function must know how to deal with the error in the inner function, and perhaps have some code that does what was supposedly needed from the function which threw an error.&lt;/p&gt;
&lt;p&gt;Ideally, we would want to return to the exact place in the function where the error happened and do something about it instead.
And this is what the condition system in Common Lisp allows us to do.&lt;/p&gt;
&lt;h2 id=&#34;conditions-in-pure-clojure&#34;&gt;Conditions in pure Clojure&lt;/h2&gt;
&lt;p&gt;We can implement the condition system in Clojure using only inbuilt features of the language - mainly the dynamic scope.
But first, let&amp;rsquo;s understand what the condition system actually is.&lt;/p&gt;
&lt;p&gt;Common Lisp condition system is a very useful feature of the language, often used for error handling, and to do other interesting stuff as well.
The main difference between conditions and exceptions is that exceptions are a two-part system, where one side signals the error, and another side decides how to handle it and actually handles it.
In Common Lisp, conditions are a three-part system, with an additional thing, called restarts.
This can be seen as that our &lt;code&gt;catch&lt;/code&gt; block is separated into two parts - one will only decide how to recover from the error, and another will actually do the recovery part.
In conventional exception systems, by the time you get an exception, you should already decide how to handle it.
Furthermore, you have to deal with the exception outside of the place where it has actually happened, while in the condition system you can &lt;em&gt;return&lt;/em&gt; to that place and &lt;em&gt;restart&lt;/em&gt; the process.&lt;/p&gt;
&lt;p&gt;So, the condition system consists of three main parts: signals, handlers, and restarts.
We can think of signals as exceptions in Clojure, but a bit more general.
Which means that we already have signals, however, we actually can&amp;rsquo;t use Java&amp;rsquo;s exceptions in the condition system to signal errors.
An exception will still be used for stack unwinding, and the topmost error handling, where an unhandled signal will pop up as an exception, but ideally this will not happen.
And handlers and restarts don&amp;rsquo;t really exist yet so we&amp;rsquo;ll have to define those manually.&lt;/p&gt;
&lt;p&gt;So how we can do this in Clojure?
First, we need to create the signal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;throw&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ex-info&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;invalid date&amp;#34;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:data&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;})))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s it.
We&amp;rsquo;ve just moved the &lt;code&gt;throw&lt;/code&gt; call into a separate dynamic function, which gave us the facility to replace this function&amp;rsquo;s behavior later with a custom handler.
Now we can introduce some restarts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dynamic&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This may not make much sense right now, as we&amp;rsquo;ve just created two more dynamic vars without any behavior, but we will assign some behavior in the function where we would use these restarts.
Which we will do in the &lt;code&gt;parse-date&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;identity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;unable to parse&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;LocalDate/parse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DateTimeFormatter/ofPattern&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;dd-MM-yyyy&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this &lt;code&gt;binding&lt;/code&gt; form we&amp;rsquo;re assigning default behaviors to our restarts - you can think of it as &lt;code&gt;restart-case&lt;/code&gt; in Common Lisp.
The &lt;code&gt;*use-value*&lt;/code&gt; restart is a pretty common restart, which means we will do the error recovery outside of the function, and pass the correct value for this function to use.
The &lt;code&gt;*log-invalid-date*&lt;/code&gt; restart is a simple logger that can be also used instead.
We could add more restarts here if there were more ways to recover from the error, but let&amp;rsquo;s just stay with these two for now.&lt;/p&gt;
&lt;p&gt;And in the &lt;code&gt;if-let&lt;/code&gt; we&amp;rsquo;re checking if the &lt;code&gt;date&lt;/code&gt; is a string and matches our regexp, and if not we&amp;rsquo;re using our &lt;code&gt;*invalid-date*&lt;/code&gt; signal.
Right now this signal will throw an exception, so if we will use this function in our &lt;code&gt;keep&lt;/code&gt;, we&amp;rsquo;ll get an unhandled exception:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But now, we can register a handler to our signal, that will log our errors.
We do this by using another &lt;code&gt;binding&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; unable to parse 29-02-2021&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; unable to parse 12-34-5678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; =&amp;gt; (#object[java.time.LocalDate 0x102d92c4 &amp;#34;2020-02-29&amp;#34;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: we have to use either &lt;code&gt;doall&lt;/code&gt; or &lt;code&gt;bound-fn&lt;/code&gt; in our &lt;code&gt;keep&lt;/code&gt; call, as we&amp;rsquo;re in dynamic scope, and &lt;code&gt;keep&lt;/code&gt; is lazy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;So, here we&amp;rsquo;re binding our &lt;code&gt;*invalid-date*&lt;/code&gt; signal to use a &lt;code&gt;*log-invalid-date*&lt;/code&gt; restart and continue.
If we run this code, we&amp;rsquo;ll see two dates being logged and only one date lands on the resulting list of parsed dates.
Now, let&amp;rsquo;s add a recovery, that will try to re-parse our date, and recover from the error.&lt;/p&gt;
&lt;p&gt;To do so, we need to change our &lt;code&gt;reparse-leap-date&lt;/code&gt; function like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;identity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; #(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;unable to parse as leap date&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-((?::19|[2-9][0-9])\d\d)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;01-03-&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Wrong leap date: %s, using %s instead&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, we&amp;rsquo;re imitating the &lt;code&gt;restart-case&lt;/code&gt; from Common Lisp with &lt;code&gt;binding&lt;/code&gt;, in which we provide two restarts.
And as in the previous version, if the date is not February 29th, we signal the error with &lt;code&gt;*invalid-date*&lt;/code&gt; signal.
So how we would use this function to recover?&lt;/p&gt;
&lt;p&gt;One may think that we will just need to rebind &lt;code&gt;*invalid-date*&lt;/code&gt; to a function that calls &lt;code&gt;*use-value*&lt;/code&gt; restart, and provide the result of &lt;code&gt;reparse-leap-date&lt;/code&gt; to this restart as an input.
This is mostly true, but actually, there&amp;rsquo;s a bit of a problem.
We need to remember that if our function can&amp;rsquo;t parse a date as a leap date, we&amp;rsquo;re signaling the error using the &lt;strong&gt;same signal&lt;/strong&gt; we&amp;rsquo;ve just rebound.
This is a recipe for stack overflow exception because we will call &lt;code&gt;reparse-leap-date&lt;/code&gt; over and over again from &lt;code&gt;*invalid-date*&lt;/code&gt; signal handler.
So, generally speaking, once we&amp;rsquo;ve entered the handler, we need to bind the original signal&amp;rsquo;s value back, because we can&amp;rsquo;t be sure that by handling this signal, we will not receive it again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                               (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;])))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is how we invoke our &lt;code&gt;*use-value*&lt;/code&gt; restart.
It may seem a bit tricky at first glance, and we&amp;rsquo;re rebinding things in dynamic scope in a kinda special way, so let me explain what happens here.&lt;/p&gt;
&lt;p&gt;The first thing we do is store our original signal value in the &lt;code&gt;let&lt;/code&gt; binding as &lt;code&gt;decline-invalid-date&lt;/code&gt;.
We then bind our &lt;code&gt;*invalid-date*&lt;/code&gt; signal to an anonymous function that, when called, binds &lt;code&gt;*invalid-date*&lt;/code&gt; back to its original value stored in the closure, and executes the &lt;code&gt;*use-value*&lt;/code&gt; restart.
This restart receives the value from the &lt;code&gt;reparse-leap-date&lt;/code&gt; function, which may use &lt;code&gt;*invalid-date*&lt;/code&gt; signal, but it won&amp;rsquo;t be handled with this particular handler anymore, as we&amp;rsquo;ve just unbound it.
This means, that if an error happens in &lt;code&gt;reparse-leap-date&lt;/code&gt;, an exception will be thrown, as our &lt;code&gt;*invalid-date*&lt;/code&gt; signal is bound to its original function which throws an exception.
So to handle the error from the &lt;code&gt;reparse-leap-date&lt;/code&gt; function we need another handler around the &lt;code&gt;let&lt;/code&gt; block, which will use the logging restart for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Wrong leap date: 29-02-2021, using 01-03-2021 instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; unable to parse as leap date 12-34-5678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; =&amp;gt; (#object[java.time.LocalDate 0x551de37d &amp;#34;2020-02-29&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;     #object[java.time.LocalDate 0x6ef81f31 &amp;#34;2021-03-01&amp;#34;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we run this code we will get a list of two dates and a message in the log.
The first date will be parsed correctly, the second one will be handled with the inner &lt;code&gt;*invalid-date*&lt;/code&gt; handler, and the third date will be logged with the outer &lt;code&gt;*invalid-date*&lt;/code&gt; handler.
And, as a matter of fact, since the &lt;code&gt;*log-invalid-date*&lt;/code&gt; restart will be called only from the &lt;code&gt;decline-invalid-date&lt;/code&gt; function we just as well could register the handler in the inner &lt;code&gt;binding&lt;/code&gt;, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So this is a flexible system.&lt;/p&gt;
&lt;p&gt;But another great property of storing the original signal&amp;rsquo;s value in the &lt;code&gt;let&lt;/code&gt; is that we can decline to handle the signal completely.
This means, that we can add some logic into our handler, that analyzes its input value, decides whether it can handle or it should decline to handle this, and just propagate the error up the dynamic scope.
This is why I&amp;rsquo;ve called original value &lt;code&gt;decline-invalid-date&lt;/code&gt; because by calling it we will decline to handle the &lt;code&gt;*invalid-date*&lt;/code&gt; error.
And Common Lisp condition system also can do the same thing, except it&amp;rsquo;s a bit easier there.
We do so by not calling the &lt;code&gt;invoke-restart&lt;/code&gt; function in the handler, but since in our system there&amp;rsquo;s no &lt;code&gt;invoke-restart&lt;/code&gt; at all, we have to save the signal value manually.&lt;/p&gt;
&lt;p&gt;However, even though this system is pretty flexible it is also a bit too boilerplate.
We have to do many things, that can be actually wrapped into macros, and the farolero library, I&amp;rsquo;ve mentioned earlier, provides that.
Let&amp;rsquo;s see how our code above can look with more Common Lisp-like macros.&lt;/p&gt;
&lt;h2 id=&#34;farolero-conditions-and-restarts&#34;&gt;Farolero conditions and restarts&lt;/h2&gt;
&lt;p&gt;Farolero is a library, that provides a set of functions and macros that provide a condition system very similar to the one from Common Lisp.
This is a fairly new library, but I&amp;rsquo;ve found it the most interesting one among the others, which provides condition systems for Clojure.
First, let&amp;rsquo;s add it as a dependency.
Create &lt;code&gt;deps.edn&lt;/code&gt; file with the following contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:deps&lt;/span&gt; {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.suskalo/farolero&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:mvn/version&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.0.0-RC2&amp;#34;&lt;/span&gt;}}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alternatively you can use &lt;code&gt;clj -Sdeps &#39;{:deps {org.suskalo/farolero {:mvn/version &amp;quot;1.0.0-RC2&amp;quot;}}}&#39;&lt;/code&gt; to start the REPL with this library available for &lt;code&gt;require&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s &lt;code&gt;require&lt;/code&gt; needed stuff, and rewrite our &lt;code&gt;parse-date&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &amp;#39;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;farolero.core&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:refer&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt;]])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date-re&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;LocalDate/parse&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DateTimeFormatter/ofPattern&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;dd-MM-yyyy&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::log-invalid-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;unable to parse&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we&amp;rsquo;re using proper &lt;code&gt;restart-case&lt;/code&gt; macro, which accepts the expression as the first argument, and restarts we desire to implement for this expression.
In the expression we check &lt;code&gt;date&lt;/code&gt; with our regular expression and if it doesn&amp;rsquo;t match, we&amp;rsquo;re calling &lt;code&gt;error&lt;/code&gt;, which signals the &lt;code&gt;::invalid-date&lt;/code&gt; error with one argument &lt;code&gt;date&lt;/code&gt;.
Similarly to our previous example, we can handle this error by using the &lt;code&gt;::log-invalid-date&lt;/code&gt; restart:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::log-invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)) [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Executing this code we will, as before, receive a list with one parsed date, and two messages in the log.
To actually recover from the first error, we can bind this handler to a &lt;code&gt;::use-value&lt;/code&gt; restart, which we pass the value provided with &lt;code&gt;reparse-leap-date&lt;/code&gt; function, but first we need to update it to use restarts as well:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;restart-case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;if-let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;re-find &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-((?::19|[2-9][0-9])\d\d)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;01-03-&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;year&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Wrong leap date: %s, using %s instead&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;next-day&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::use-value&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::log-invalid-date&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;unable to parse as leap date&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note, that we&amp;rsquo;re signaling the same &lt;code&gt;::invalid-date&lt;/code&gt; with &lt;code&gt;error&lt;/code&gt; function, and we had to deal with this in the dynamic scope solution previously, but this will not be problematic in the case of this library.
We now can use this function to provide a value for the &lt;code&gt;::use-value&lt;/code&gt; restart as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::log-invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::use-value&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;])))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Wrong leap date: 29-02-2021, using 01-03-2021 instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; unable to parse as leap date 12-34-5678&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; =&amp;gt; (#object[java.time.LocalDate 0x13741d5a &amp;#34;2020-02-29&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;;     #object[java.time.LocalDate 0x6b69761b &amp;#34;2021-03-01&amp;#34;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And I&amp;rsquo;ve already included the outer handler, that logs every unhandled date.
This outer handler could have been defined as the inner handler around &lt;code&gt;reparse-leap-date&lt;/code&gt; call, but I&amp;rsquo;ve used it outside just to show that we don&amp;rsquo;t have to deal with signal rebinding.&lt;/p&gt;
&lt;p&gt;Compare this code to our no-libraries-required solution:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*log-invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;binding &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*invalid-date*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;decline-invalid-date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*use-value*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The difference is not that big and the structure is mostly the same.
However, the code which uses farolero library is still much clearer, because there are no &lt;code&gt;let&lt;/code&gt; and nested &lt;code&gt;binding&lt;/code&gt; in handlers, which needed to provide ways to decline error handling and unwind the stack.
And as a matter of fact, if we&amp;rsquo;re exiting the handler normally, e.g. not by using &lt;code&gt;invoke-restart&lt;/code&gt;, we will decline error handling, and our signal will unwind the stack if there&amp;rsquo;s no other handler to catch it.&lt;/p&gt;
&lt;p&gt;An additional feature, provided by the farolero library, is an interactive debugger, which is mostly the same as in Common Lisp (to my knowledge).
This debugger allows us to handle unhandled signals by using provided restarts interactively.
For example, if we remove the outermost &lt;code&gt;handler-bind&lt;/code&gt; and execute the code as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handler-bind&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::invalid-date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_condition&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;invoke-restart&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;::use-value&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reparse-leap-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;keep&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bound-fn&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;parse-date&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;date&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2020&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;29-02-2021&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;12-34-5678&amp;#34;&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We will see an interactive prompt that provides us with some information about the signal, and our restart options:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Debugger level 1 entered on :user/invalid-date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:user/invalid-date was signaled with arguments (&amp;#34;12-34-5678&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0 [:user/use-value] :user/use-value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1 [:user/log-invalid-date] :user/log-invalid-date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 [:user/use-value] :user/use-value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 [:user/log-invalid-date] :user/log-invalid-date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 [:farolero.core/throw] Throw the condition as an exception
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;user&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;why-this-might-not-work-for-you--but-still-is-an-option&#34;&gt;Why this might not work for you (but still is an option)&lt;/h2&gt;
&lt;p&gt;One glaring problem with both of these approaches is that both are &lt;em&gt;somewhat&lt;/em&gt; foreign to the language, even though both use just the features provided by the language.
The advantage of the condition system in Common Lisp is that it is deeply integrated into the language, and conditions, signals, and restarts are widely used across all code, and not just to handle errors.
In Java, and therefore in Clojure exceptions are the primary way of error handling.
And actually, in Clojure we&amp;rsquo;re trying to avoid exceptions as much as possible, mostly using &lt;code&gt;nil&lt;/code&gt; to tell that function has failed and then branching on return values.&lt;/p&gt;
&lt;p&gt;If you think about it, &lt;code&gt;if-some&lt;/code&gt; and &lt;code&gt;try catch&lt;/code&gt; are two of the most common error handling patterns in Clojure - the first one is mainly used in plain Clojure, and the second one is when interacting with Java.
This is a bit of a shame because both can&amp;rsquo;t provide all these features that the condition system has, and we can&amp;rsquo;t really run away from exceptions, given that so many java libraries use them.&lt;/p&gt;
&lt;p&gt;Libraries like farolero, or the dynamic scope approach can close this gap a bit, however, as I&amp;rsquo;ve mentioned, the key advantage of the condition system in Common Lisp is that it is used everywhere.
Whereas conditions in Clojure will only be an additional way of error handling, thus one more thing to think of and remember.
Hence, some parts of the project will use exceptions, because of some libraries that throw them around, some parts will use nil-punning, and some will use conditions, which only may make it harder to maintain the project.
Or you will have to wrap a lot of stuff to use your condition system of choice, which will add a lot of implementation details to the code.&lt;/p&gt;
&lt;p&gt;Another point is that there are several ways of using the condition system in Clojure - either via some library or by using a dynamic scope.
This is not a problem for a project that is more like an application rather than a library, but libraries should not expose their dependencies unless it&amp;rsquo;s absolutely necessary.
Although by using dynamic vars to provide signals and restarts you&amp;rsquo;re not taking away traditional exception handling, you only provide an additional way to recover, and there&amp;rsquo;s no extra dependency at all.&lt;/p&gt;
&lt;p&gt;This may seem that I&amp;rsquo;m mostly against the use of the condition system, but in fact, I think that you should at least try this approach, and understand where it would be the preferred way.
Condition system really can make your application very robust, and provide very versatile ways to recover from errors.
For example, with farolero you can even fix your application at runtime when an unhandled signal pops up by using the interactive debugger it provides.
And since farolero also has some ways of handling exceptions as conditions, this may be a good choice even if you use exceptions in your codebase.
But this needs more experimenting, and I&amp;rsquo;m definitively going to keep an eye on this library, as well as the others.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;You can find more information on the condition system in the &lt;a href=&#34;http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html&#34; target=&#34;_blank&#34;&gt;Chapter 19 of the Practical Common Lisp book&lt;/a&gt;, and here&amp;rsquo;s some more info on the &lt;a href=&#34;https://wiki.c2.com/?CommonLispConditionSystem&#34; target=&#34;_blank&#34;&gt;c2 wiki&lt;/a&gt; page.
These are two more articles on the topic that are very handy: &lt;a href=&#34;http://www.nhplace.com/kent/Papers/Exceptional-Situations-1990.html&#34; target=&#34;_blank&#34;&gt;Exceptional Situations&lt;/a&gt;, &lt;a href=&#34;http://www.nhplace.com/kent/Papers/Condition-Handling-2001.html&#34; target=&#34;_blank&#34;&gt;Condition Handling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And there are also a lot more Clojure libraries that implement condition systems to various degrees:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/IGJoshua/farolero&#34; target=&#34;_blank&#34;&gt;farolero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/clojureman/special&#34; target=&#34;_blank&#34;&gt;Special&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/scgilardi/slingshot&#34; target=&#34;_blank&#34;&gt;Slingshot&lt;/a&gt; with &lt;a href=&#34;https://github.com/hugoduncan/swell&#34; target=&#34;_blank&#34;&gt;Swell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zcaudate/hara&#34; target=&#34;_blank&#34;&gt;Hara&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bwo/conditions&#34; target=&#34;_blank&#34;&gt;Conditions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://clojure.github.io/clojure-contrib/error-kit-api.html&#34; target=&#34;_blank&#34;&gt;error-kit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;ve only tried &lt;code&gt;slingshot&lt;/code&gt;, although without the &lt;code&gt;swell&lt;/code&gt; part, and have yet to see the other ones, so there are always more things to experiment with.
The dynamic scope approach seems like the most fun way of doing it, but it is as well as the most boilerplate one, so may not be suitable in a big application.
It&amp;rsquo;s also worth pointing out that it is not thread-safe or lazy-safe, so it&amp;rsquo;s not the best choice overall, but a great way to understand the condition system.&lt;/p&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Condition system in Clojure&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 17 Apr 2021 20:40:00 +0300</pubDate>
    </item><item>
      <title>PF4J and Clojure</title>
      <link>https://andreyor.st/posts/2021-04-10-pf4j-and-clojure/</link>
      <guid>https://andreyor.st/posts/2021-04-10-pf4j-and-clojure/</guid>
      <description>&lt;p&gt;Today we&amp;rsquo;ll take a look at an interesting Java library, called &lt;a href=&#34;https://pf4j.org/&#34; target=&#34;_blank&#34;&gt;PF4J&lt;/a&gt;, which describes itself as a Plugin Framework for Java.
The main purpose of this library is to provide a way of detecting, initializing, and using plugins to extend your Java application with new features without the need to modify the code.
The official repository has examples of how to use this library with Java, and Kotlin, but there is no Clojure example.&lt;/p&gt;
&lt;p&gt;Recently I had to find a way how to use this library with Clojure, and it has turned a bit hard to achieve, because this library is very &lt;em&gt;Javaish&lt;/em&gt;, if you know what I mean :).
Classes, interfaces, and Java annotations are not the most common thing to see in Clojure, as we usually have no classes, interfaces, or annotations, but functions, data abstractions, and metadata.
I&amp;rsquo;m not very experienced in Java bytecode inspection, and Clojure class generation, and I was unable to find any information on how to integrate PF4J and Clojure, so this post will explain what I&amp;rsquo;ve found so far.
You know, so I would be able to refresh this if I ever again will need to use this library, or will find myself in a similar situation where I need to work with annotations or class generation.
And hopefully, this information will be useful for others as well.&lt;/p&gt;
&lt;p&gt;So here we will write an example plugin, in the same way how Java example plugins are written in the &lt;a href=&#34;https://github.com/pf4j/pf4j/tree/master/demo&#34; target=&#34;_blank&#34;&gt;pf4j demo application&lt;/a&gt;.
But first, let&amp;rsquo;s look at how the Java plugin is structured.&lt;/p&gt;
&lt;h2 id=&#34;anatomy-of-a-plugin&#34;&gt;Anatomy of a plugin&lt;/h2&gt;
&lt;p&gt;The complete plugin consists of two main components - the plugin itself, and the extension point.
We will take the &lt;code&gt;.jar&lt;/code&gt; approach for storing and distributing plugins, as it is the easiest one to reach, and we can directly compare the bytecode of the Java plugin, and Clojure plugin.
So let&amp;rsquo;s first create an extension point in Java.&lt;/p&gt;
&lt;p&gt;Create project &lt;code&gt;Greeting&lt;/code&gt; in your Java IDE of choice.
I&amp;rsquo;m creating a maven project, so the first thing we&amp;rsquo;ll need is to add &lt;code&gt;pf4j&lt;/code&gt; dependency to our &lt;code&gt;pom.xml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snip --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;dependencies&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;groupId&amp;gt;org.pf4j&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;artifactId&amp;gt;pf4j&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;version&amp;gt;3.6.0&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/dependencies&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snap --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can create extension point class &lt;code&gt;org.example.Greeting&lt;/code&gt;, and add this code into it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.ExtensionPoint&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;extends&lt;/span&gt; ExtensionPoint {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    String &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getGreeting&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is all we need for our small extension point, and we can install it in our local repo with &lt;code&gt;mvn install&lt;/code&gt;.
AFAIU, extension point&amp;rsquo;s main purpose is to help PF4J detect &lt;em&gt;particular&lt;/em&gt; plugins, and not &lt;em&gt;all&lt;/em&gt; plugins.&lt;/p&gt;
&lt;p&gt;Now we need the plugin itself.
This plugin depends on both &lt;code&gt;pf4j&lt;/code&gt; and this extension point we&amp;rsquo;ve just created and installed.
Create a new project &lt;code&gt;JavaWelcomePlugin&lt;/code&gt;, and add there &lt;code&gt;pf4j&lt;/code&gt; dependency as explained above, and the &lt;code&gt;org.example.Greeting&lt;/code&gt; dependency:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snip --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;groupId&amp;gt;org.example&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;artifactId&amp;gt;Greeting&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snap --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, create a new class &lt;code&gt;GreetingsPlugin&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Extension&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Plugin&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.PluginWrapper&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.Greeting&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;extends&lt;/span&gt; Plugin {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt;(PluginWrapper wrapper) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;super&lt;/span&gt;(wrapper);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    @Override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;start&lt;/span&gt;() { System.out.println(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Java plugin start&amp;#34;&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    @Override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stop&lt;/span&gt;() { System.out.println(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Java plugin stop&amp;#34;&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    @Extension
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Welcome&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;implements&lt;/span&gt; Greeting {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getGreeting&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hi from Java!&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This plugin has &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; methods that &lt;code&gt;pf4j&lt;/code&gt; will call during initialization, and deinitialization of the plugin, and the main part here is the nested &lt;code&gt;Welcome&lt;/code&gt; class.
This class implements our &lt;code&gt;Greeting&lt;/code&gt; extension point, and is annotated with &lt;code&gt;@Extension&lt;/code&gt;, which helps &lt;code&gt;pf4j&lt;/code&gt; discover this class during the build process.&lt;/p&gt;
&lt;p&gt;One more thing we need to add to our &lt;code&gt;pom.xml&lt;/code&gt; are new manifest entries.
&lt;code&gt;Pf4j&lt;/code&gt; expects each plugin to have at least two entries in &lt;code&gt;MANIFEST.mf&lt;/code&gt; file in the &lt;code&gt;.jar&lt;/code&gt; archive: &lt;code&gt;Plugin-Version&lt;/code&gt;, and &lt;code&gt;Plugin-ID&lt;/code&gt;.
In our case, we will also need to add &lt;code&gt;Plugin-Class&lt;/code&gt; entry, as we&amp;rsquo;ve created a wrapper class &lt;code&gt;GreetingsPlugin&lt;/code&gt;.
Add this to the &lt;code&gt;pom.xml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snip --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;build&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;plugins&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;lt;artifactId&amp;gt;maven-jar-plugin&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;lt;configuration&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;archive&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;lt;manifestEntries&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;Plugin-ID&amp;gt;java-welcome-plugin&amp;lt;/Plugin-ID&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;Plugin-Class&amp;gt;org.example.GreetingsPlugin&amp;lt;/Plugin-Class&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;Plugin-Version&amp;gt;1.0&amp;lt;/Plugin-Version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &amp;lt;/manifestEntries&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;/archive&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &amp;lt;/configuration&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/plugins&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/build&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&amp;lt;!-- snap --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a bit too verbose (well, it is XML after all), but here we&amp;rsquo;re just adding these three entries to our manifest file during the build process.
Now let&amp;rsquo;s package this plugin with the &lt;code&gt;mvn package&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;This makes the complete example plugin in Java - much like the one in the demo application from PF4J examples.
Both the interface and the plugin are written, and we can plug this code into any application, that looks for our &lt;code&gt;Greeting&lt;/code&gt; interface.
Now let&amp;rsquo;s test this plugin in a small Clojure program.&lt;/p&gt;
&lt;h2 id=&#34;writing-clojure-program-that-uses-plugins&#34;&gt;Writing Clojure program that uses plugins&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s create a small project based on the &lt;code&gt;app&lt;/code&gt; template, that uses &lt;code&gt;pf4j&lt;/code&gt; library, and loads this plugin we&amp;rsquo;ve just written in Java.
I&amp;rsquo;m using &lt;a href=&#34;https://leiningen.org/&#34; target=&#34;_blank&#34;&gt;Leiningen&lt;/a&gt; for project automation, but you may use &lt;code&gt;deps&lt;/code&gt; or other tools if you prefer.
But we will later need to edit &lt;code&gt;project.clj&lt;/code&gt; and do some tweaks other than adding dependencies, so if you&amp;rsquo;re using &lt;code&gt;deps&lt;/code&gt; you&amp;rsquo;re on your own here.
For me, the command is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein new app pf4j-clj-app
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A new project is created and we need to add &lt;code&gt;org.pf4j/pf4j&lt;/code&gt; and &lt;code&gt;org.example.Greeting&lt;/code&gt; dependencies to the &lt;code&gt;:dependencies&lt;/code&gt; section in &lt;code&gt;project.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dependencies&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.clojure/clojure&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.10.1&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j/pf4j&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;3.6.0&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example/Greeting&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.0-SNAPSHOT&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rest of the &lt;code&gt;project.clj&lt;/code&gt; can be left as is.
Now, let&amp;rsquo;s write our &lt;code&gt;-main&lt;/code&gt; function in the &lt;code&gt;core.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pf4j-clj-app.core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:import&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;JarPluginManager&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:gen-class&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plugin-manager&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;JarPluginManager.&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plugin-manager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.loadPlugins&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.startPlugins&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;greets&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getExtensions&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plugin-manager&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Found&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;greets&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;extensions for extension point&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getName&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doseq &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;greet&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;greets&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.getGreeting&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;greet&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plugin-manager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.stopPlugins&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.unloadPlugins&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ll keep this brief - we&amp;rsquo;re importing our &lt;code&gt;Greeting&lt;/code&gt; extension point, and the &lt;code&gt;pf4j&lt;/code&gt; library, creating &lt;code&gt;plugin-manager&lt;/code&gt;, loading and starting plugins.
Then we print how many plugins we&amp;rsquo;ve found for the &lt;code&gt;Greeting&lt;/code&gt; extension point, and execute the &lt;code&gt;.getGreeting&lt;/code&gt; method for each plugin.
And after that, we&amp;rsquo;re stopping and unloading plugins to keep things clean.&lt;/p&gt;
&lt;p&gt;By default &lt;code&gt;pf4j&lt;/code&gt; searches for &lt;code&gt;jar&lt;/code&gt; plugins in the &lt;code&gt;plugin&lt;/code&gt; directory at the root of the project.
Let&amp;rsquo;s create this directory, copy our Java plugin there, and start our application with &lt;code&gt;lein run&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir plugins
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cp path/to/JavaWelcomePlugin/target/JavaWelcomePlugin-1.0-SNAPSHOT.jar ./plugins/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Failed to load class &amp;#34;org.slf4j.impl.StaticLoggerBinder&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Defaulting to no-operation (NOP) logger implementation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Found 1 extensions for extension point &amp;#39;org.example.Greeting&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hi from Java!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It works!
We&amp;rsquo;ve seen the message from the &lt;code&gt;start&lt;/code&gt; method, the &lt;code&gt;getGreeting&lt;/code&gt; call result, and then the &lt;code&gt;stop&lt;/code&gt; method message.
Now let&amp;rsquo;s do everything in Clojure!&lt;/p&gt;
&lt;h2 id=&#34;clojure-extensionpoint-implementation&#34;&gt;Clojure &lt;code&gt;ExtensionPoint&lt;/code&gt; implementation&lt;/h2&gt;
&lt;p&gt;To make an extension point in Clojure, let&amp;rsquo;s create a new library project with &lt;code&gt;lein new clj-greeting&lt;/code&gt;, and add needed changes to our &lt;code&gt;project.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defproject &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example/Greeting&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.0-SNAPSHOT&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:description&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;pf4j extension poin example in Clojure&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:license&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:url&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;https://www.eclipse.org/legal/epl-2.0/&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dependencies&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.clojure/clojure&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.10.1&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j/pf4j&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;3.6.0&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:aot&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:all&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve mainly changed the project name from &lt;code&gt;clj-greeting&lt;/code&gt; to &lt;code&gt;org.example/Greeting&lt;/code&gt; so we could hot-swap our Java extension point to the Clojure one with simple &lt;code&gt;lein install&lt;/code&gt;.
Similarly, the version was changed to &lt;code&gt;1.0-SNAPSHOT&lt;/code&gt; to match the version of our Java extension point.
The &lt;code&gt;pf4j&lt;/code&gt; dependency was added to the &lt;code&gt;:dependencies&lt;/code&gt; key.
Lastly, &lt;code&gt;:aot :all&lt;/code&gt; entry was added to make sure we AOT compile every file.&lt;/p&gt;
&lt;p&gt;Now we can create our interface.
To do so, first we need to create needed directories with &lt;code&gt;src/org/example&lt;/code&gt; directories, and move &lt;code&gt;core.clj&lt;/code&gt; to &lt;code&gt;src/org/example/greeting.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir -p src/org/example
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mv src/clj_greeting/core.clj src/org/example/greeting.clj
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ rmdir src/clj_greeting
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, we add this code to &lt;code&gt;greeting.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.greeting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.ExtensionPoint&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gen-interface&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.Greeting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:extends&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.ExtensionPoint&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:methods&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getGreeting&lt;/span&gt; [] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;String&lt;/span&gt;]])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, we&amp;rsquo;re creating an interface with &lt;code&gt;gen-inteface&lt;/code&gt; and naming it to &lt;code&gt;org.example.Greeting&lt;/code&gt;.
This interface extends the &lt;code&gt;org.pf4j.ExtensionPoint&lt;/code&gt; class, and exposes one method &lt;code&gt;getGreeting&lt;/code&gt; which takes zero arguments, and returns a &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s package this as a &lt;code&gt;jar&lt;/code&gt; archive with &lt;code&gt;lein jar&lt;/code&gt; command, and see its contents with &lt;code&gt;zipinfo&lt;/code&gt;.
If you don&amp;rsquo;t have &lt;code&gt;zipinfo&lt;/code&gt; you can use any other way to view archives.
Here are the contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lein jar &amp;amp;&amp;amp; zipinfo -1 target/Greeting-1.0-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Compiling clj-greetings.core
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Created /home/alistopadov/Git/clj-greetings/target/Greeting-1.0-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/MANIFEST.MF
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/org.example/Greeting/pom.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/leiningen/org.example/Greeting/project.clj
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/leiningen/org.example/Greeting/README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/leiningen/org.example/Greeting/LICENSE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/org.example/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/org.example/Greeting/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/org.example/Greeting/pom.properties
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org/example/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org/example/Greeting.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_greetings/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_greetings/core__init.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_greetings/core$loading__6721__auto____171.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_greetings/core$fn__173.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_greetings/core.clj
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;re mainly interested in the &lt;code&gt;org/example/Greeting.class&lt;/code&gt; entry.
Let&amp;rsquo;s decompile it. This can be either done with Intellij Idea or by using &lt;a href=&#34;https://github.com/fesh0r/fernflower&#34; target=&#34;_blank&#34;&gt;fernflower&lt;/a&gt; directly.
The decompiled bytecode looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.ExtensionPoint&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;extends&lt;/span&gt; ExtensionPoint {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   String &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getGreeting&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And this looks exactly like the Java example we&amp;rsquo;ve written before.
Great, let&amp;rsquo;s test it!&lt;/p&gt;
&lt;p&gt;We do this by installing this extension point in place of our Java one, by using the &lt;code&gt;lein install&lt;/code&gt; command (you can remove the old extension from the &lt;code&gt;.m2&lt;/code&gt; directory for extra safety).
Then we need to repackage our Java plugin and copy it again to our Clojure application.
When we run it, we should see the same output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Found 1 extension for extension point org. example.Greeting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hi from Java!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, our extension point is now implemented in Clojure.
Now we can write the plugin itself!&lt;/p&gt;
&lt;h2 id=&#34;pf4j-plugin-in-clojure&#34;&gt;PF4J plugin in Clojure&lt;/h2&gt;
&lt;p&gt;To write a plugin let&amp;rsquo;s create another project with &lt;code&gt;lein new clj-welcome-plugin&lt;/code&gt;.
Again, we need to alter &lt;code&gt;project.clj&lt;/code&gt; a bit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defproject &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj-welcome-plugin&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.1.0-SNAPSHOT&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:description&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;pf4j plugin example in Clojure&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:license&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:url&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;https://www.eclipse.org/legal/epl-2.0/&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dependencies&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.clojure/clojure&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.10.1&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j/pf4j&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;3.6.0&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example/Greeting&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1.0-SNAPSHOT&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:manifest&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Plugin-Id&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;clojure-welcome-plugin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Plugin-Version&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Plugin-Class&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;clj_welcome_plugin.GreetingsPlugin&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:aot&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:all&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, we&amp;rsquo;re adding &lt;code&gt;:aot :all&lt;/code&gt; entry and the &lt;code&gt;:manifest&lt;/code&gt; key with a map of keys and values of manifest entries we need to add.
Thankfully, Leiningen makes it really easy to deal with this, compared to &lt;code&gt;pom.xml&lt;/code&gt; we&amp;rsquo;ve had to modify previously.&lt;/p&gt;
&lt;p&gt;Now, we need to create a wrapper class, and the &lt;code&gt;@Extension&lt;/code&gt; class, and here&amp;rsquo;s a problem.
To my knowledge, there&amp;rsquo;s no way to write nested classes in Clojure.
And annotations are also a bit finicky.
So let&amp;rsquo;s approach this step by step.&lt;/p&gt;
&lt;p&gt;The first thing we&amp;rsquo;ve done in Java code was import all needed libraries, and create a class that extended &lt;code&gt;Plugin&lt;/code&gt; class:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Extension&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Plugin&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.PluginWrapper&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.Greeting&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;extends&lt;/span&gt; Plugin {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt;(PluginWrapper wrapper) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;super&lt;/span&gt;(wrapper);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* ... */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s do the same in Clojure.
We start by renaming the &lt;code&gt;core.clj&lt;/code&gt; to &lt;code&gt;greetings_plugin.clj&lt;/code&gt;, and importing all needed libraries, also saying that our &lt;code&gt;:gen-class&lt;/code&gt; has no &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;:extends org.pf4j.Plugin&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj-welcome-plugin.greetings-plugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:import&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Plugin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;PluginWrapper&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Extension&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Greeting&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:gen-class&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj_welcome_plugin.GreetingsPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:main&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:extends&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Plugin&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So far so good.
Now we need a constructor, but in our case, Clojure has already generated one, which we can see by compiling our code into the &lt;code&gt;jar&lt;/code&gt; file, and looking through the bytecode:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj_welcome_plugin&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* Clojure imports */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Plugin&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.PluginWrapper&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;extends&lt;/span&gt; Plugin {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* some initialization Clojure stuff */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin&lt;/span&gt;(PluginWrapper var1) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;super&lt;/span&gt;(var1);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* rest of the Clojure stuff */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A custom constructor can be provided by using the &lt;code&gt;:init&lt;/code&gt; key in &lt;code&gt;:gen-class&lt;/code&gt;, but I&amp;rsquo;ll leave it out to the reader.&lt;/p&gt;
&lt;p&gt;Now we can add &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; methods:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-start&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Clojure plugin start&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-stop&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Clojure plugin stop&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And this basically completes our wrapper class, so how do we add a nested class?
Well, &lt;em&gt;actually&lt;/em&gt;, from a bytecode standpoint this is not a nested class, and the outer class simply acts as a namespace.
We can actually see that in the contents of the &lt;code&gt;jar&lt;/code&gt; file which contains compiled code of our Java plugin:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org/example/GreetingsPlugin.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org/example/GreetingsPlugin$Welcome.class
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So the inner &lt;code&gt;public static Welcome&lt;/code&gt; class is actually a separate &lt;code&gt;.class&lt;/code&gt; file, and we can replicate this in Clojure pretty easily.
Let&amp;rsquo;s add another call to &lt;code&gt;gen-class&lt;/code&gt; in the same file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gen-class&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; ^{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Extension&lt;/span&gt; {}} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj_welcome_plugin.GreetingsPlugin$Welcome&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:prefix&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;impl-&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:implements&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.Greeting&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;impl-getGreeting&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Hi from Clojure!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or we can create another file, and use &lt;code&gt;:gen-class&lt;/code&gt; there, but to match Java plugin source code layout, I&amp;rsquo;m using the single file.&lt;/p&gt;
&lt;p&gt;The most important thing here is the &lt;code&gt;:name&lt;/code&gt; key.
You can see that we&amp;rsquo;re providing a metadata entry &lt;code&gt;^{org.pf4j.Extension {}}&lt;/code&gt; which is a way to add Java annotation to a class.
And we&amp;rsquo;re naming our class as &lt;code&gt;clj_welcome_plugin.GreetingsPlugin$Welcome&lt;/code&gt;.
Lastly, the &lt;code&gt;:implements&lt;/code&gt; key is used to tell, that our class implements our extension point.
And because we&amp;rsquo;re using the same file, we change &lt;code&gt;:prefix&lt;/code&gt; to &lt;code&gt;&amp;quot;impl-&amp;quot;&lt;/code&gt;, and the &lt;code&gt;getGreeting&lt;/code&gt; method is defined as &lt;code&gt;impl-getGreeting&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s compile our code with &lt;code&gt;lein jar&lt;/code&gt; again, and see if we&amp;rsquo;ve managed to replicate the &lt;code&gt;.class&lt;/code&gt; layout in the &lt;code&gt;jar&lt;/code&gt; archive:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein jar &amp;amp;&amp;amp; zipinfo -1 target/clj-welcome-plugin-0.1.0-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/MANIFEST.MF
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/leiningen/...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;META-INF/maven/...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_welcome_plugin/GreetingsPlugin.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_welcome_plugin/GreetingsPlugin$Welcome.class
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great!
Let&amp;rsquo;s see if our &lt;code&gt;GreetingsPlugin$Welcome.class&lt;/code&gt; actually decompiles to correct class:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clj_welcome_plugin&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* Clojure imports */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.example.Greeting&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;org.pf4j.Extension&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@Extension
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;GreetingsPlugin$Welcome&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;implements&lt;/span&gt; Greeting {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;/* Clojure stuff */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getGreeting&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      Var var10000 = getGreeting__var;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      Object var1 = getGreeting__var.isBound() ? var10000.get() : &lt;span style=&#34;font-weight:bold&#34;&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; (var1 != &lt;span style=&#34;font-weight:bold&#34;&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; (String)((IFn)var1).invoke(&lt;span style=&#34;font-weight:bold&#34;&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      } &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;font-weight:bold&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;new&lt;/span&gt; UnsupportedOperationException(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;getGreeting (clj-welcome-plugin.greetings-plugin/impl-getGreeting not defined?)&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And it is!
We can see the &lt;code&gt;@Extension&lt;/code&gt; annotation, and &lt;code&gt;public class GreetingsPlugin$Welcome&lt;/code&gt; that implements &lt;code&gt;Greeting&lt;/code&gt; extension point.
Later, after some Clojure internal code, we can see our &lt;code&gt;getGreeting&lt;/code&gt; method definition.&lt;/p&gt;
&lt;p&gt;However, if we try to use this plugin, it will not work just yet:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cp path/to/clj-welcome-plugin/target/clj-welcome-plugin-0.1.0-SNAPSHOT.jar ./plugins/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Failed to load class &amp;#34;org.slf4j.impl.StaticLoggerBinder&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Defaulting to no-operation (NOP) logger implementation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Found 1 extensions for extension point &amp;#39;org.example.Greeting&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hi from Java!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Still, only the Java plugin runs.
This took me some time to figure out why it doesn&amp;rsquo;t work - the &lt;code&gt;.class&lt;/code&gt; files layout of the resulting &lt;code&gt;.jar&lt;/code&gt; archives are the same.
Decompiled classes, except for the Clojure stuff, look the same as Java classes.&lt;/p&gt;
&lt;p&gt;The catch is, that when we&amp;rsquo;re building our Java plugin with &lt;code&gt;mvn package&lt;/code&gt;, the extra file &lt;code&gt;extensions.idx&lt;/code&gt; is created in the &lt;code&gt;META-INF&lt;/code&gt; directory of the archive.
Let&amp;rsquo;s look at this file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Generated by PF4J
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;org.example.GreetingsPlugin$Welcome
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aha!
This file contains the necessary info to detect the &lt;code&gt;@Extension&lt;/code&gt; annotated class in the &lt;code&gt;jar&lt;/code&gt; archive and is generated by processing Java annotation during compilation.
Unfortunately, the Clojure compiler doesn&amp;rsquo;t try to process our metadata as Java annotation, and hence no file is created.
But we can add this file by hand, by creating &lt;code&gt;META-INF/extensions.idx&lt;/code&gt; in the &lt;code&gt;resources&lt;/code&gt; directory with the following contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_welcome_plugin.GreetingsPlugin$Welcome
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, we&amp;rsquo;re indicating that our &lt;code&gt;@Extension&lt;/code&gt; class is &lt;code&gt;clj_welcome_plugin.GreetingsPlugin$Welcome&lt;/code&gt;.
Let&amp;rsquo;s re-package our plugin with &lt;code&gt;lein jar&lt;/code&gt;, and re-run our app:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cp path/to/clj-welcome-plugin/target/clj-welcome-plugin-0.1.0-SNAPSHOT.jar ./plugins/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Failed to load class &amp;#34;org.slf4j.impl.StaticLoggerBinder&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: Defaulting to no-operation (NOP) logger implementation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Clojure plugin start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Found 2 extensions for extension point &amp;#39;org.example.Greeting&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hi from Clojure!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hi from Java!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Java plugin stop
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Clojure plugin stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It works!
Now we can make a more complex app, and extend it with plugins written both in Java and Clojure.
Of course, more complex plugins will be bigger and have more code, but the general idea will be the same.&lt;/p&gt;
&lt;h2 id=&#34;some-ending-notes&#34;&gt;Some ending notes&lt;/h2&gt;
&lt;p&gt;You don&amp;rsquo;t have to put both the wrapper class and the Extension class in the same file.
I mainly did this because it is in line with the Java code, so sources could be compared mostly directly.
But a separate file, that sets the class name in a similar way is a more clean approach and should be preferred.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also no need to rename most of the classes, except for the &lt;code&gt;@Extension&lt;/code&gt; one, as we have to explicitly make it into a nested class via &lt;code&gt;$&lt;/code&gt; notation.
Again, I&amp;rsquo;ve mainly done this to keep more or less the same code structure with the Java examples, for easier direct comparison.&lt;/p&gt;
&lt;p&gt;Lastly, some automation may be needed to generate &lt;code&gt;extensions.idx&lt;/code&gt; file based on source code.
Unfortunately, I&amp;rsquo;ve not found any info on how to make Java annotation processing work with Clojure metadata annotations.
So I&amp;rsquo;ve done this manually, but I&amp;rsquo;ve also written this script, that analyzes Clojure source code as EDN, and searches for given extension point class, printing class name from &lt;code&gt;gen-class&lt;/code&gt; form if present:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;!/usr/bin/env&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &amp;#39;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.edn&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;edn&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;require&lt;/span&gt; &amp;#39;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.string&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-gen-class&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Tests if `form` is a `gen-class` and gets the `:name` or uses the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  `default` if `:name` is not set, but `:implements` matches the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  `query`.  Replaces all dashes with underscores in case the `default`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  name came from the `ns` form.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-gen-class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;default&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;list?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (#{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:gen-class&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;gen-class&lt;/span&gt;} (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;some &lt;/span&gt;#{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:implements&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gencl&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;drop &lt;/span&gt;1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;partition&lt;/span&gt; 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{} (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:implements&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gencl&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;get &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gencl&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:name&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;default&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;str/replace&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;#&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;-&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_&amp;#34;&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-ns&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;The `ns` form already contains class name as a namespace name,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  but we check inner `:gen-class` for a `:name` override.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;second &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;some &lt;/span&gt;#(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-gen-class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;name&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-form&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Check whether current `form` is a `gen-class` or `:gen-class` expression.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  If it is, check if gen-class has `:implements` key that is equal to
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  `query` and gets the value of the `:name` key.  If `form` is an `ns`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  form finds `:gen-class` in it and checks it as above.  Recursively
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  analyzes nested lists.  Terminates at first successful analysis.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;list?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cond &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#39;ns&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-ns&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;some &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;list?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;some &lt;/span&gt;#(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:else&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-gen-class&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*command-line-args*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doseq &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*input*&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;name &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;analyze-form&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;edn/read-string&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;query&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;form&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;name&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a &lt;a href=&#34;https://github.com/babashka/babashka&#34; target=&#34;_blank&#34;&gt;Babashka&lt;/a&gt; script, which analyzes S-expressions, and can be used together with another tool for parsing EDN - &lt;a href=&#34;https://github.com/borkdude/jet&#34; target=&#34;_blank&#34;&gt;Jet&lt;/a&gt; (huge thanks to Michiel Borkent for awesome Clojure tooling!):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ jet -c &amp;lt; src/clj_welcome_plugin/greetings_plugin.clj | ~/script.clj &amp;#34;[org.example.Greeting]&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_welcome_plugin.GreetingsPlugin$Welcome
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or, similarly for every &lt;code&gt;.clj&lt;/code&gt; file in the project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ find -name &amp;#39;*.clj&amp;#39; -exec sh -c &amp;#39;jet -c &amp;lt; &amp;#34;{}&amp;#34; | ~/script.clj &amp;#34;[org.example.Greeting]&amp;#34;&amp;#39; \;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clj_welcome_plugin.GreetingsPlugin$Welcome
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For this project, the script finds the extension class name correctly from the source code we&amp;rsquo;ve given to it, but it is more a proof of concept, and by far is not a well-tested solution.&lt;/p&gt;
&lt;p&gt;One particular point to improve is the fact that we have to pass &lt;code&gt;&amp;quot;[org.example.Greeting]&amp;quot;&lt;/code&gt; to the script, to help it find &lt;code&gt;gen-class&lt;/code&gt; entries that implement the interface we&amp;rsquo;re interested in.
A much better solution would be to parse metadata, but unfortunately, I was not able to make Jet keep metadata in the resulting EDN, and I&amp;rsquo;m not sure how to properly read Clojure source code files otherwise.
Although, it&amp;rsquo;s not really hard to check if all classes are present, as I highly doubt that there will be more than 5 extension classes presented in a single plugin, so this solution is good enough for now.&lt;/p&gt;
&lt;p&gt;Other than that, the process of using the PF4J library is pretty straightforward, and we can fully utilize this library from Clojure projects with some hand tweaking.
Thanks for reading!&lt;/p&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: PF4J and Clojure&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 10 Apr 2021 10:59:00 +0300</pubDate>
    </item><item>
      <title>Pretty-printing for Fennel Language</title>
      <link>https://andreyor.st/posts/2021-01-09-pretty-printing-for-fennel-language/</link>
      <guid>https://andreyor.st/posts/2021-01-09-pretty-printing-for-fennel-language/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;All the patches&lt;sup&gt;&lt;a href=&#34;https://git.sr.ht/~technomancy/fennel/commit/8cf5bb8eab82d80ffc2c135d32135d07f06ef61e&#34; target=&#34;_blank&#34;&gt;1​&lt;/a&gt;, &lt;a href=&#34;https://git.sr.ht/~technomancy/fennel/commit/9384d52c55b8b7076c067cf1b14bd025220e557d&#34; target=&#34;_blank&#34;&gt;2​&lt;/a&gt;&lt;/sup&gt; has been merged into the main branch of Fennel language, so expect to see improved fennelview in next stable release!
Some semantics have been altered, so I&amp;rsquo;ve updated the post a bit to reflect the changes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Prettyprint#Lisp_pretty-printer&#34; target=&#34;_blank&#34;&gt;Pretty-printing in Lisp&lt;/a&gt; is a way to represent data structures that we operate in our program in a human-readable way.
This technique is quite old and was part of many Lisp languages for a very long time.
Because Lisps usually are &lt;a href=&#34;https://en.wikipedia.org/wiki/Homoiconicity#In_Lisp&#34; target=&#34;_blank&#34;&gt;homoiconic&lt;/a&gt;, defining a pretty printer for Lisp&amp;rsquo;s main data structure in terms of the syntax expected by the &lt;a href=&#34;https://en.wikipedia.org/wiki/Lisp_reader&#34; target=&#34;_blank&#34;&gt;reader&lt;/a&gt;, we get a way to pretty-print Lisp&amp;rsquo;s code, thus making pretty-printer act as a formatter.
And as far as I know, this was originally the main purpose for pretty printer - code was written in a &amp;ldquo;compressed&amp;rdquo; form, e.g. no line breaks to save space, and then pretty-printed on some kind of display.
This was also handy to review outputs of programs that generate programs, another common property of Lisp languages.&lt;/p&gt;
&lt;p&gt;Fennel is a relatively young Lisp-like language, that compiles to Lua.
It uses Lua&amp;rsquo;s main data structure - a table, as its main data structure, and has its own pretty printer, called &lt;a href=&#34;https://git.sr.ht/~technomancy/fennel/tree/3dbee7d40bef802dcf58a07f2daea1db17e59dca/item/fennelview.fnl&#34; target=&#34;_blank&#34;&gt;fennelview&lt;/a&gt;.
It&amp;rsquo;s a pretty simple pretty printer, that is mostly based on another pretty printer for Lua, called &lt;a href=&#34;https://github.com/kikito/inspect.lua&#34; target=&#34;_blank&#34;&gt;inspect.lua&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;inspect.lua&lt;/code&gt; is oriented at producing Lua-style tables, &lt;code&gt;fennelview.fnl&lt;/code&gt; was altered to make it output tables in a Fennel&amp;rsquo;s syntax, so printed tables could be read back by the reader.
It is important to note, that &lt;code&gt;inspect.lua&lt;/code&gt; is not oriented at table serialization, hence this is not well suited for a Lisp-like language.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fennelview.lua&lt;/code&gt; also shared some problems, most of which were inherited from &lt;code&gt;inspect.lua&lt;/code&gt;, and one of which is indentation handling.
In Fennel v0.7.0, tables were printed like this in the REPL:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 3}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Indentation seems to be correct from a C-like language standpoint, but Lisp hackers usually expect the following notation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 3}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is more concise and takes less horizontal space.
It may seem like not a big deal, however, the main issue is that &lt;code&gt;fennelview&lt;/code&gt; can&amp;rsquo;t properly deal with nested tables.
For example, if we put the table from above into a sequential table with some elements, and possibly other tables, we&amp;rsquo;ll get an unpleasant result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; [1 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2} 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:e&lt;/span&gt; 6 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:f&lt;/span&gt; 7 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:g&lt;/span&gt; 8} 9]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } 2 3 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:e&lt;/span&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:f&lt;/span&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:g&lt;/span&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } 6]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Indentation no longer makes any sense, and while this is not an issue for Fennel&amp;rsquo;s reader, it is hard to read such data structure from a human perspective.
There are two other Lisps languages with quite a similar syntax - Janet and Clojure, each of which formats the table from above like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2} 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:e&lt;/span&gt; 6, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:f&lt;/span&gt; 7, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:g&lt;/span&gt; 8} 9]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Except in Janet parentheses are used in place of square brackets, and there are no commas in the table literal.)&lt;/p&gt;
&lt;p&gt;This is much better than the current behavior of &lt;code&gt;fennelview&lt;/code&gt;, however, I still find this kind of representation a bit hard to read, as we need to keep an eye on the inner object&amp;rsquo;s boundaries.
So I&amp;rsquo;ve decided to re-implement &lt;code&gt;fennelview&lt;/code&gt; from scratch, to make it smarter about indentation, and when to produce multi-line representations of the data structure it was passed.&lt;/p&gt;
&lt;h2 id=&#34;lua-tables-and-fennel-reader&#34;&gt;Lua tables, and Fennel reader&lt;/h2&gt;
&lt;p&gt;Tables in Lua are implemented as a combination of associative tables, and sequential array-like parts.
Lua actually has a single syntax for defining both kinds of tables, which uses curly braces:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- sequential table or array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; t1 = {1, 2, 3}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- associative table&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; t2 = {a = 1, b = 2}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- sequential table with nested tables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; t3 = {1, t2, 2, 3, {c = 4, d = 5}, 6}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- a combination of associative and sequential tables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; t4 = {1, 1, 2, 3, 5, kind = &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Fibonacci&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fennel defines different syntaxes for different table kinds - sequential tables are defined with &lt;code&gt;[]&lt;/code&gt;, and associative tables are defined with &lt;code&gt;{}&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt; [1 2 3])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t2&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t3&lt;/span&gt; [1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t2&lt;/span&gt; 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5} 6])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, combined tables are created as associative tables, by providing indexes as keys:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t4&lt;/span&gt; {1 1 2 1 3 2 4 3 5 5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:kind&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Fibonacci&amp;#34;&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; you can do the same in Lua, but it&amp;#39;s more verbose:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; local t4 = {[1] = 1, [2] = 1, [3] = 2, [4] = 3, [5] = 5, kind = &amp;#34;Fibonacci&amp;#34;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Another way of defining such a table is by using &lt;code&gt;set&lt;/code&gt; and mutating the existing sequential table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t4&lt;/span&gt; [1 1 2 3 5])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1 1 2 3 5]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t4.kind&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Fibonacci&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    1 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    2 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    3 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    4 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    5 5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:kind&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Fibonacci&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that until we&amp;rsquo;ve specified the non-sequential key in our table it was printed as a sequence.
However, when a table has non-sequential keys, it is printed as an associative table.
This has deep implications since the &lt;code&gt;ipairs&lt;/code&gt; function will only traverse the sequential part of the table, so by printing a table this way we also indicate that it has more to it than just the sequential part.&lt;/p&gt;
&lt;p&gt;But the indentation is not right.
I&amp;rsquo;ve thought about a small set of rules, which could be used to decide how to print tables.
This is what I got, and I&amp;rsquo;m pretty much pleased with the results:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Associative tables are printed within &lt;code&gt;{}&lt;/code&gt;
    &lt;ol&gt;
      &lt;li&gt;Opened and closed curly braces must stay at the same lines as the first and last key-value pair in the table respectively.&lt;/li&gt;
      &lt;li&gt;Associative tables printed as multi-line if a certain amount of key-value pairs are present. Currently the limit is &lt;code&gt;4&lt;/code&gt;.&lt;/li&gt;
      &lt;li style=&#34;text-decoration:line-through&#34;&gt;If any key or value itself is a table, multi-line output is produced.&lt;/li&gt;
      &lt;li value=&#34;3&#34;&gt;Strings in key position printed as colon-strings if possible.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Sequential tables are printed within
    &lt;ol&gt;
      &lt;li&gt;Opened and closed square brackets must stay at the same lines as the first and last values in the table respectively.&lt;/li&gt;
      &lt;li&gt;Sequential tables printed as multi-line if a certain amount of key-value pairs is present. Optimal limit is &lt;code&gt;10&lt;/code&gt;.&lt;/li&gt;
      &lt;li style=&#34;text-decoration:line-through&#34;&gt;If any value itself is a table, multi-line output is produced.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;If the single-line representation of the current data structure and its indentation is greater than a certain amount, a multi-line representation is printed.  Optimal width is &lt;code&gt;80&lt;/code&gt; characters.&lt;/li&gt;
  &lt;li&gt;Nested tables share parent&#39;s indentation level.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;The scratched rules above were considered initially but changed in the process of integrating the new fennelview into the language.
Therefore, the next part of this post is now irrelevant, because most of these tables were examples of that scratched rule, but the current implementation only checks for the outermost third rule, e.g. for the resulting line width.
Most of these examples would be single-line ones now, the &lt;a href=&#34;#comparison-to-other-lisp-pretty-printers&#34;&gt;comparison section&lt;/a&gt; has a more up-to-date variant of the formatting.
I&amp;rsquo;ve highlighted irrelevant code with cursive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s manually apply these rules to the table that I&amp;rsquo;ve used before to visualize &lt;code&gt;fennelview&lt;/code&gt;&amp;rsquo;s problems:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:e&lt;/span&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:f&lt;/span&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:g&lt;/span&gt; 8}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 9]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can see that the sequential table contains less than 10 elements, &lt;em&gt;but since the second associative table has more than 4 key-value pairs, we use multi-line output.&lt;/em&gt;
&lt;em&gt;On the other hand, the first associative table has only two key-value pairs in each, therefore is printed as a single line.&lt;/em&gt;
&lt;em&gt;And if the second associative table were to have fewer elements, the result would be printed as a one-liner:&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2} 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; 4 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:d&lt;/span&gt; 5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:e&lt;/span&gt; 6 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:f&lt;/span&gt; 7} 9]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Because neither of the inner tables is multiline, and the total line length is less than &lt;code&gt;80&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In my opinion, this is a very readable form for such kind of data structure - we can immediately see all sequential parts, and associative parts still stand out.
I&amp;rsquo;ve re-implemented &lt;code&gt;fenneview&lt;/code&gt; with these rules applied to sequential and associative tables, and with these changes whenever we pretty-print anything in the REPL we get a correctly indented result.
For example, here&amp;rsquo;s how the configuration file for &lt;a href=&#34;https://gitlab.com/andreyorst/fenneldoc&#34; target=&#34;_blank&#34;&gt;Fenneldoc&lt;/a&gt; is now printed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fennel.dofile&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;.fenneldoc&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:fennel-path&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;cljlib/?.fnl&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;src/?.fnl&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:function-signatures&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:insert-comment&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:insert-copyright&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:insert-license&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:insert-version&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:keys&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:copyright&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_COPYRIGHT&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:description&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_DESCRIPTION&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:doc-order&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_DOC_ORDER&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:license&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_LICENSE&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:module-name&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_MODULE_NAME&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:version&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;_VERSION&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:order&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;aplhabetic&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:out-dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;./doc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:silent&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:toc&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the exact way I would write it by hand (and I actually &lt;a href=&#34;https://gitlab.com/andreyorst/fenneldoc/-/blob/16fe52418b4b36d2b8c00a8a1a956522e56a47d8/.fenneldoc&#34; target=&#34;_blank&#34;&gt;did&lt;/a&gt;), and I think this way it looks and reads much better than with default &lt;code&gt;fennelview&lt;/code&gt; implementation.&lt;/p&gt;
&lt;p&gt;However there are some quirks in Lua VM related to tables, and we also need a way to produce correctly indented user-defined data structures, that can be nested in other data structures.&lt;/p&gt;
&lt;h2 id=&#34;cyclic-tables&#34;&gt;Cyclic tables&lt;/h2&gt;
&lt;p&gt;In Lua, it is possible to define a table that contains itself, and Fennel is no exception here.
Current implementation of &lt;code&gt;fennelview&lt;/code&gt; has an option named &lt;code&gt;detect-cycles&lt;/code&gt;, which is set to &lt;code&gt;true&lt;/code&gt; by default.
This means that when we try to print a table that contains itself, we will not go into infinity recursion:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt; [])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@1[#&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;table&lt;/span&gt; @1&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m not a big fan of this &lt;code&gt;#&amp;lt;table @1&amp;gt;&lt;/code&gt; thing, It mimics Lua&amp;rsquo;s internal string representation for a table for no reason.
More than that, if the table is associative, we&amp;rsquo;ll see exact same &lt;code&gt;#&amp;lt;table @id&amp;gt;&lt;/code&gt; notation, which is not ideal too.
I&amp;rsquo;ve re-implemented parts of the cycle detection algorithm, and now it can differentiate what table type the cycle appears in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt; [])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@1[@1[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cycles are printed either as &lt;code&gt;@id[...]&lt;/code&gt; for sequential tables, or as &lt;code&gt;@id{...}&lt;/code&gt; for associative tables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt; {})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t.v&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@1{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:v&lt;/span&gt; [@1{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;}]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@1[{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:v&lt;/span&gt; @1[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;...&lt;/span&gt;]}]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can disable this behavior by setting &lt;code&gt;:detect-cycles?&lt;/code&gt; option to &lt;code&gt;false&lt;/code&gt;, and if we encounter a cycle, we will go in until the depth limit is reached.
The depth limit is set to &lt;code&gt;128&lt;/code&gt; by default.&lt;/p&gt;
&lt;p&gt;This can also be done for user-defined data structures based on tables.
For example, I&amp;rsquo;ve &lt;a href=&#34;https://gitlab.com/andreyorst/fennel-cljlib/-/blob/d09ca41a9bd602028dda980a3ae4f36240959c24/init.fnl#L1063-1080&#34; target=&#34;_blank&#34;&gt;implemented this&lt;/a&gt; for &lt;code&gt;hash-set&lt;/code&gt; from &lt;a href=&#34;https://gitlab.com/andreyorst/fennel-cljlib&#34; target=&#34;_blank&#34;&gt;Cljlib&lt;/a&gt;, and now sets with cycles are printed as &lt;code&gt;@set1{...}&lt;/code&gt;, or with other IDs, depending on context.
This is done by specifying the custom implementation of &lt;code&gt;__fennelview&lt;/code&gt; metamethod in the table&amp;rsquo;s metatable.&lt;/p&gt;
&lt;h2 id=&#34;fennelview-metamethod&#34;&gt;&lt;code&gt;__fennelview&lt;/code&gt; metamethod&lt;/h2&gt;
&lt;p&gt;Set implementation from Cljlib is a bit overwhelming to explain here, so let&amp;rsquo;s instead define another non-existing data structure.
For example, Lua does not have linked lists, so we can implement &lt;a href=&#34;https://en.wikipedia.org/wiki/Cons&#34; target=&#34;_blank&#34;&gt;cons cells&lt;/a&gt; in terms of tables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur-print-list&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;head&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tail&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;head&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;match&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tail&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:table&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;?&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:cons&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-?&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tail&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getmetatable&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:__type&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur-print-list&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tail&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:nil&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;table.insert&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;. &amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tail&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt; 2)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pp-list&lt;/span&gt; [&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;list &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur-print-list&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;list &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;options&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;view&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;indent&lt;/span&gt; 1) [])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;icollect&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ipairs&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;elements&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; 1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;(&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt; 1) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tset&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lines&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cons-mt&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:__fennelview&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pp-list&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:__type&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:cons&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;h&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setmetatable&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;h&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cons-mt&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a rather basic implementation for cons list pretty printer, but it already allows us to print lists with a traditional notation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;1 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(1 &lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;2 3))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(1 2 &lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;2 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;3)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(1 2 3)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we encounter multiline tables we force multi-line output for the whole list.
And we can actually see, that the rules of the indentation that we&amp;rsquo;ve defined for tables still apply:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;2 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4})))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The associative table is correctly indented, because we manipulate the &lt;code&gt;indent&lt;/code&gt; argument inside &lt;code&gt;recur-print-list&lt;/code&gt;, and this even works correctly when our list itself is inside of another table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:list&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;2 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cons &lt;/span&gt;3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4})))}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:list&lt;/span&gt; (1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2})}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More complex data structures may require additional logic put in the pretty-printer function, but this example illustrates the idea of control you can have.&lt;/p&gt;
&lt;h2 id=&#34;comparison-to-other-lisp-pretty-printers&#34;&gt;Comparison to other Lisp pretty-printers&lt;/h2&gt;
&lt;p&gt;This implementation may not be as general as the one available in, say, Clojure.
For example, I&amp;rsquo;ve mentioned a rule, that if any nested element of a table is multiline, &lt;code&gt;fennelview&lt;/code&gt; will output multi-line representation.
This rule makes it a lot easier to reason about indentation.
Consider:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.pprint/pprint&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3}]})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3}]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clojure.pprint/pprint&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                            &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3}]})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; [1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4}]}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Clojure&amp;rsquo;s &lt;code&gt;pprint&lt;/code&gt; is smart enough to see that it can just put the second table on the second line, and not trigger the multi-line output of a vector.
My implementation of fennelview will print everything on a new line, because the length of single-line representation is big enough, and we can benefit from vertical alignment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3}]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2}]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1 2 3 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4}]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:seq&lt;/span&gt; [1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:and-yet-another-one&lt;/span&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:another-long-key&lt;/span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-long-key&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:some-other-key&lt;/span&gt; 2}]}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In practice, I find this easier to read, but this actually may make it a bit harder to implement code formatter on top of pretty-printer.
Also, I think that separating keys and values in associative data structure with newlines is a bad decision to make.
Clojure can use commas in printed representation, since they are completely ignored, which I think is a great way to indicate pairs, but does not justify newlines in this particular case at least for me.&lt;/p&gt;
&lt;p&gt;The source code of the formatter is available &lt;a href=&#34;https://gitlab.com/andreyorst/fennel-pprint&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, and I&amp;rsquo;ve submitted a patch to the Fennel language, so hopefully, we&amp;rsquo;ll see this implementation by default.
Thanks for reading!&lt;/p&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Pretty-printing for Fennel Language&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 09 Jan 2021 23:07:00 +0300</pubDate>
    </item><item>
      <title>We need to talk about parentheses</title>
      <link>https://andreyor.st/posts/2020-12-03-we-need-to-talk-about-parentheses/</link>
      <guid>https://andreyor.st/posts/2020-12-03-we-need-to-talk-about-parentheses/</guid>
      <description>&lt;p&gt;Programming languages come in all shapes and sizes.
There are pretty simple languages and really complex ones.
But what unites most of these languages is the syntax.
There are many languages so-called C-like, as they share many syntax ideas with C language, which includes consistent indentation, grouping, scoping, and infix notation.
And many other syntax aspects usually are common in a majority of languages.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s one language, that is different from the others.
It has a long story and research behind it.
This language, developed in the late 1950s, and evolved since, still being alive up to our days.
I&amp;rsquo;m talking about Lisp, of course.&lt;/p&gt;
&lt;p&gt;And one of the most well-known things about Lisp is:&lt;/p&gt;
&lt;div style=&#34;font-size: 3rem&#34;&gt;
  &lt;center&gt;
    &lt;b&gt;
      &lt;span&gt;
        P A R E N T H E S E S.
      &lt;/span&gt;
    &lt;/b&gt;
  &lt;/center&gt;
  &lt;br&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s gonna be today&amp;rsquo;s topic - why parentheses, how to deal with those, what features we can gain from those, and what tools we&amp;rsquo;ve come up with over the years of Lisp hacking.&lt;/p&gt;
&lt;p&gt;The thing is, Lisp is notoriously known for its parentheses, as for many this is its main feature they will defend at all costs.
However, for some reason, novice computer scientists fear these parentheses.
This produces a lot of various memes, like this one&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-12-03-we-need-to-talk-about-parentheses/how-to-save-the-princess-in-lisp.jpg&#34;/&gt;
&lt;/figure&gt;

&lt;center&gt;
  &lt;a href=&#34;https://toggl.com/blog/save-princess-8-programming-languages&#34;&gt;How To Save The Princess in 8 Programming Languages&lt;/a&gt;
&lt;/center&gt;
&lt;br&gt;
&lt;p&gt;I guess this pretty much illustrates how most programmers, who are unfamiliar with Lisp, see the idea of parentheses.
I often hear pretty common rants, that usually come down to one thing - there are too many parentheses even for the simplest things!
And I agree, sometimes Lisp can be overwhelmed with parentheses for &lt;strong&gt;seemingly&lt;/strong&gt; no reason.&lt;/p&gt;
&lt;p&gt;To explain why parentheses are important let&amp;rsquo;s look at this small part of Rust code from some imaginary program:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--rust-example-1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; foo = 10;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; bar = foo + 32;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;foo * bar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--rust-example-1&#34;&gt;Code Snippet 1&lt;/a&gt;:&lt;/span&gt;
  Rust example
&lt;/div&gt;
&lt;p&gt;In this code we declare two immutable variables: &lt;code&gt;foo&lt;/code&gt;, and &lt;code&gt;bar&lt;/code&gt;, and assign values &lt;code&gt;10&lt;/code&gt;, and &lt;code&gt;42&lt;/code&gt; to them respectively.
Then we compute their product and return it?..
Now let&amp;rsquo;s look at the same code but in Scheme, which is a dialect of Lisp:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--scheme-example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 32)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--scheme-example&#34;&gt;Code Snippet 2&lt;/a&gt;:&lt;/span&gt;
  Scheme example
&lt;/div&gt;
&lt;p&gt;This code does exactly the same thing as Rust code but has whopping twelve parentheses.
And for most programmers, this may seem ridiculous.
Why on earth someone would want to insert this amount of parentheses for a such simple task, as defining two variables and computing their product?
Yes, Lisp is old, and this may seem like some legacy that was carried by language since the 60s.
But there&amp;rsquo;s a good reason for parentheses to be part of the language, and once you understand their value, you&amp;rsquo;ll likely never be able to program without them.
Likely.
Because parentheses are &lt;em&gt;that good&lt;/em&gt;.
But why exactly?&lt;/p&gt;
&lt;h2 id=&#34;why-parentheses&#34;&gt;Why parentheses?&lt;/h2&gt;
&lt;p&gt;In this section, I will &lt;strong&gt;try&lt;/strong&gt; to convince you that parentheses are good.
However, I must warn you that this is a conclusion most programmers begin to agree with only after writing in Lisp for some time.
So while many things may seem silly, keep in mind that sometimes silly things only seem silly.&lt;/p&gt;
&lt;h3 id=&#34;scope&#34;&gt;Scope&lt;/h3&gt;
&lt;p&gt;As we saw, both Scheme and Rust examples do the same things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;declare the variable &lt;code&gt;foo&lt;/code&gt;, and assign a value of &lt;code&gt;10&lt;/code&gt; to it,&lt;/li&gt;
&lt;li&gt;declare the variable &lt;code&gt;bar&lt;/code&gt;, and assign a sum of &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;32&lt;/code&gt; to it,&lt;/li&gt;
&lt;li&gt;multiply &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt;, and return result to &lt;em&gt;outer scope&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But here&amp;rsquo;s the catch - &lt;em&gt;what scope&lt;/em&gt;?
In the Rust example, all we see are two definitions and expressions, and there&amp;rsquo;s the question: do we need &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; after we produce their product?&lt;/p&gt;
&lt;p&gt;In Scheme example we can directly see where variables are available, since Scheme uses lexical scope, the end of life of &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; will be at the last parenthesis of the &lt;code&gt;let*&lt;/code&gt; block:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;
&lt;pre style=&#34;background-color:#fff; color:#888&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;color:#ff4242&#34;&gt;(&lt;/span&gt;&lt;span&gt;let* &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;foo&lt;/span&gt; 10&lt;span&gt;)&lt;/span&gt;
       &lt;span&gt;(&lt;/span&gt;&lt;span&gt;bar&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;+ &lt;/span&gt;&lt;span&gt;foo&lt;/span&gt; 32&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
  &lt;span&gt;(&lt;/span&gt;&lt;span&gt;* &lt;/span&gt;&lt;span&gt;foo&lt;/span&gt; &lt;span&gt;bar&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff4242&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In Rust, we can&amp;rsquo;t really see the whole picture here and now, because Rust does not require explicit scoping for a definition to be part of the expression.
Although syntax implies that there&amp;rsquo;s nothing after the product is computed, thus &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; will go out of scope right after their product is computed (there&amp;rsquo;s no semicolon).
We can assume that the surroundings are as follows:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--rust-example-2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; result = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; foo = 10;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; bar = foo + 32;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    foo * bar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--rust-example-2&#34;&gt;Code Snippet 3&lt;/a&gt;:&lt;/span&gt;
  Explicitly scoping &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; and returning result of expression
&lt;/div&gt;
&lt;p&gt;Thus explicitly defining the scope for &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; as the part of &lt;code&gt;result&lt;/code&gt; computation process, just as in Scheme.
Which will then be used, but we will not be able to access &lt;code&gt;foo&lt;/code&gt; or &lt;code&gt;bar&lt;/code&gt; later in the program.
However, I see the following code much more often instead:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--rust-example-3&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; foo = 10;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; bar = foo + 32;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; result = foo * bar;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--rust-example-3&#34;&gt;Code Snippet 4&lt;/a&gt;:&lt;/span&gt;
  Using some outer scope
&lt;/div&gt;
&lt;p&gt;We let &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; live til the end of the outer scope, even though we might not use it at all.
And another question to ask is how long &lt;code&gt;result&lt;/code&gt; has to live?
Does it need to live til the end of the function?
These are questions that can be asked for both examples.
Usually, we don&amp;rsquo;t think about this much and don&amp;rsquo;t wrap each and every variable into explicit scope in such languages.
And Rust itself does a good job of keeping everything clean and dropping objects when those go out of scope.&lt;/p&gt;
&lt;p&gt;On the other hand, the Scheme example explicitly states that both &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; are local to the scope of the &lt;code&gt;let*&lt;/code&gt; and no one will expect to use those variables outside.
And this pattern is applied to all other places in the program because we must define scope, as some Schemes forbid inline definitions with &lt;code&gt;define&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This might seem like a small advantage, if any, for most developers, and a made-up example.
And this is, in fact, a made-up example but the thing is, I was a C programmer for the past 5 years, and I was working with low-level code (bare metal actually).
And I have &lt;strong&gt;never&lt;/strong&gt; seen the use of explicit scoping of variables.
Yes, there&amp;rsquo;s no standard way of doing what Rust does &lt;a href=&#34;#code-snippet--rust-example-2&#34;&gt;here&lt;/a&gt; unless we use &lt;a href=&#34;https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html&#34; target=&#34;_blank&#34;&gt;compiler extension&lt;/a&gt;, but this is not an option sometimes, and the syntax is kinda cumbersome.
I find this a major problem when dealing with C because I always see about 10 uninitialized variables at the start of each function, where half of those are used only once.
Somewhere.
And thank god, if there are no global variables.
In Lisp, I can directly see where the scope for a variable begins and ends, and this pleases me enough to bear with parentheses.&lt;/p&gt;
&lt;p&gt;But, well, even if we&amp;rsquo;re not talking about statement expressions, still in C or Rust we can define the scope with two curly braces, and in Scheme, we need &lt;strong&gt;twelve&lt;/strong&gt; in total.
Why?&lt;/p&gt;
&lt;p&gt;Up to this point, you already may think that Rust or even C is actually better in this regard, but Lisp has a secret sauce hidden in these parentheses, which a lot of languages strive to achieve.
And the reason for this is related to how Lisp was implemented in the first place.&lt;/p&gt;
&lt;p&gt;LISP itself is an abbreviation, that stands for &lt;b&gt;LIS&lt;/b&gt;t &lt;b&gt;P&lt;/b&gt;rocessor.
And everything that is enclosed by parentheses is a list in Lisp.
This enables one interesting property, which allows us to define an interpreter in a small set of recursive rules, which describe how to deal with lists.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going into details on how Lisp works, but roughly, all the code is transformed into real linked lists, like the one we have in other languages, except that such a linked list can hold anything in it.
So in the case of the expression above, the list holds an &lt;code&gt;let*&lt;/code&gt; name, and then it holds a list of lists, which in turn hold identifiers that the interpreter will later use to bind values.
This may not sound clear enough, so here&amp;rsquo;s an explanation of each and every parenthesis in the Scheme example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; start of the top level list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; the let* special form&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; list of binding lists&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; first binding list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; which binds the name foo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   10  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; to value 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of first inner list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; beginning of a second binding list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; that binds the name bar to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; another list, which is an expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; that computes the sum of&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; a value of binding foo, and&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    32 &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; literal value 32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of the expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of the second binding list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of the list of bindings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ( &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; body expression that uses those definitions, which is also a list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; that holds multiply function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; the name that is bound to 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; and the name that is bound to 42 - a sum of `foo&amp;#39; and 32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of body expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; end of the top-level list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So each parenthesis has its purpose in this small code block, but still, there are too many of those.
And this is the problem because when reading the code, it is easy to make a mistake.
Can you immediately see where&amp;rsquo;s the error in this snippet?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 32))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I know where it is, but even with this knowledge, it is kinda hard to spot it while going through the code.
This particular example will not work at all &amp;ndash; compiler/interpreter will probably indicate the error.
Experienced Lisp programmers also will notice this mistake, but this example indicates one glaring problem:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;humans can&amp;rsquo;t immediately parse structure with a glance, and sometimes we have to count parentheses by hand.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And sometimes it is possible for parenthesis to be in the wrong place, and the code will still work, but the results will be not the expected ones.&lt;/p&gt;
&lt;p&gt;It is fair to say that scoping is not a unique feature of Lisp, and is easily available in other languages, with fewer parentheses.
So why even bother with all these extra parentheses?
Sure, in this particular example the benefit is that we have to explicitly scope our code, in order to make it work.
And although the example above is not real code, explicit scoping saves me a lot of time every day, by making the code easier to reason about.&lt;/p&gt;
&lt;p&gt;But, remember, I&amp;rsquo;ve said that there&amp;rsquo;s a secret sauce hidden here, which is much more important, and this is why parentheses, are in fact kept to this day.
Its macro system is one of the most powerful Lisp features, if not the most.&lt;/p&gt;
&lt;h3 id=&#34;macros&#34;&gt;Macros&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s quickly recap what we know about Lisp syntax and its relationship with macros.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve mentioned that everything that is enclosed within parentheses is a list.
And not just any list, but exactly &lt;a href=&#34;https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list&#34; target=&#34;_blank&#34;&gt;singly linked list&lt;/a&gt;.
Yes, this is a pretty common data structure that is widely available in many languages and has certain uses and benefits.
Most languages are stored as text, and there is a special tool, bundled with the language, that analyzes this text, and produces an abstract syntax tree, or AST for short.
But Lisp is a bit different since all Lisp code is actually stored inside linked lists.
And linked lists &lt;strong&gt;are&lt;/strong&gt; our AST.
That&amp;rsquo;s why Lisp is a &lt;b&gt;lis&lt;/b&gt;t &lt;b&gt;p&lt;/b&gt;rocessor - it operates lists as it&amp;rsquo;s main data structure for code.
This is called &lt;a href=&#34;https://en.wikipedia.org/wiki/Homoiconicity&#34; target=&#34;_blank&#34;&gt;homoiconicity&lt;/a&gt;.
And I hope, we all know the common properties of a single linked list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recursive nature, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Persistent_data_structure&#34; target=&#34;_blank&#34;&gt;persistence&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ϴ(n)&lt;/em&gt; lookup time;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ϴ(n+1)&lt;/em&gt; insertion, deletion, or splicing at arbitrary element;&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;ϴ(1)&lt;/em&gt; for insertion and removal at the front of the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most notably, since we&amp;rsquo;re able to split and concatenate lists, and our code is stored within lists, we&amp;rsquo;re able to manipulate AST how we want because it&amp;rsquo;s just data.
Lisp, being a list processor, comes with a lot of functions for manipulating this data structure, which allows programs to modify other parts of the program, or write new programs.
This property is often called &lt;a href=&#34;https://en.wikipedia.org/wiki/Metaprogramming&#34; target=&#34;_blank&#34;&gt;Metaprogramming&lt;/a&gt;, and in Lisp programs writing or manipulating code is a very common thing.
And thanks to the ability of code to manipulate code, Lisp core is very small, and the rest of the language is defined in terms of macros.&lt;/p&gt;
&lt;p&gt;For example, think of how one could add an &lt;code&gt;and&lt;/code&gt; operator to their language if there is no &lt;code&gt;and&lt;/code&gt; built in.
First, let&amp;rsquo;s remember what &lt;code&gt;and&lt;/code&gt; does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a predicate is &lt;code&gt;true&lt;/code&gt;, we check the next predicate;&lt;/li&gt;
&lt;li&gt;If a predicate is &lt;code&gt;false&lt;/code&gt;, we stop the process and return &lt;code&gt;false&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;If all predicates are &lt;code&gt;true&lt;/code&gt;, we return the last term.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can implement these rules as a recursive macro:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defmacro &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pred&lt;/span&gt; &amp;amp; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;preds&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;empty?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;preds&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    `(&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;~&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pred&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p#&lt;/span&gt; ~&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pred&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p#&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;~@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;preds&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p#&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s what happens.
We declare &lt;code&gt;and&lt;/code&gt; macro that takes &lt;code&gt;pred&lt;/code&gt; as its first parameter, and rest predicates as &lt;code&gt;preds&lt;/code&gt;.
We check if &lt;code&gt;preds&lt;/code&gt; is empty, and if it is, this means that we need to check only one &lt;code&gt;pred&lt;/code&gt;.
If there are &lt;code&gt;preds&lt;/code&gt;, we check the &lt;code&gt;pred&lt;/code&gt;, and if it is &lt;code&gt;true&lt;/code&gt;, we call &lt;code&gt;and&lt;/code&gt; again with the rest &lt;code&gt;preds&lt;/code&gt;.
It &lt;code&gt;pred&lt;/code&gt; is false, we return it.&lt;/p&gt;
&lt;p&gt;This is a simple recursive process, that checks its arguments one by one until there is nothing left.
And keep in mind that this can&amp;rsquo;t be really done with the function, as we evaluate one argument at a time, while the function will first compute all predicates, and then iterate results.&lt;/p&gt;
&lt;p&gt;Another example is Clojure&amp;rsquo;s &lt;a href=&#34;https://clojure.org/guides/threading_macros#thread-first&#34; target=&#34;_blank&#34;&gt;threading macro&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;9)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;5))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Its definition is more complex, compared to &lt;code&gt;and&lt;/code&gt; macro, but the purpose of &lt;code&gt;-&amp;gt;&lt;/code&gt; is to remove a lot of nesting from our expressions and present them as computation steps.
What it does, is it takes &lt;code&gt;1&lt;/code&gt;, adds &lt;code&gt;2&lt;/code&gt;, multiplies the result by &lt;code&gt;9&lt;/code&gt;, and then divides the end result by &lt;code&gt;5&lt;/code&gt;.
Macros are evaluated at compile-time, so after compilation, there will be this expression instead:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2) 9) 5)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is exactly the same thing, but you can see that it is kind of backward, e.g. division goes first.
But since this is a tree, we know that reduction is going from the leafs up to the root.
And while the &lt;code&gt;-&amp;gt;&lt;/code&gt; variant has two more parentheses, there is actually only one depth level, whereas in expanded form the nest level is 3.
So macros can help us with that at the cost of some additional parentheses, there will be one more example &lt;a href=&#34;#code-snippet--macro-reduces-nesting&#34;&gt;later&lt;/a&gt; involving a custom macro.&lt;/p&gt;
&lt;p&gt;Macros are a very complex topic, that I&amp;rsquo;m not going to cover in this post, so if you&amp;rsquo;re interested you can start at &lt;a href=&#34;https://docs.racket-lang.org/guide/macros.html&#34; target=&#34;_blank&#34;&gt;Racket&amp;rsquo;s guide section for macros&lt;/a&gt;.
Macros in Racket are hygienic and have their advantages and limitations, but there are also plain AST macros, as in &lt;a href=&#34;https://clojure.org/reference/macros&#34; target=&#34;_blank&#34;&gt;Clojure&lt;/a&gt;, or &lt;a href=&#34;http://cl-cookbook.sourceforge.net/macros.html&#34; target=&#34;_blank&#34;&gt;Common Lisp&lt;/a&gt;.
It&amp;rsquo;s fair to say that it is possible to implement a macro system that does not require parentheses, as done in &lt;a href=&#34;https://elixir-lang.org/getting-started/meta/macros.html&#34; target=&#34;_blank&#34;&gt;Elixir&lt;/a&gt;, or &lt;a href=&#34;https://doc.rust-lang.org/book/ch19-06-macros.html&#34; target=&#34;_blank&#34;&gt;Rust&lt;/a&gt;.
However, Rust, for example, has hygienic macros, which are less powerful than the unhygienic ones, and uses a kinda different syntax from the main language.
Elixir has both hygienic and unhygienic macros, and macros overall look pretty similar because language is defined in terms of lists, like Lisp, although with a different syntax.&lt;/p&gt;
&lt;h3 id=&#34;operator-precedence&#34;&gt;Operator precedence&lt;/h3&gt;
&lt;p&gt;Most languages with infix operators have these complex operator precedence tables that you have to keep in mind every time you do something that involves multiple operators.
And we all know that parentheses enforce precedence.
So, what are the precedence rules for operators in Lisp?
The answer is… there&amp;rsquo;s none!&lt;/p&gt;
&lt;p&gt;As we saw in the previous section, the silly math example with addition, multiplication, and division had parentheses around each operator:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2) 9) 5)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You could write this in C like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;float&lt;/span&gt; res = (1 + 2) * 9.0 / 5.0;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But what if we look at this example?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;float&lt;/span&gt; res = 6 / 2 * (1 + 2);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What&amp;rsquo;s the answer?
&lt;code&gt;9&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;?
It depends… on operator precedence:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-12-03-we-need-to-talk-about-parentheses/precedence.jpg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;If someone will write this as a generic expression, like &lt;code&gt;a / b * (c + d)&lt;/code&gt;, what would the intention be?
In Lisp we would not have such a problem:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;6 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;2 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;6 2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; 9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When I was working on &lt;a href=&#34;https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/&#34;&gt;raycasting&lt;/a&gt; there was plenty of math with a lot of computations often going on in a &lt;a href=&#34;https://gitlab.com/andreyorst/raycasting-with-clojurescript/-/blob/aaad368f89c99787f2e69d42aedbfcf90417a237/src/raycasting/core.cljs#L66-73&#34; target=&#34;_blank&#34;&gt;single formula&lt;/a&gt;.
And I&amp;rsquo;ve actually was so glad that the formula I&amp;rsquo;ve translated this from was written with all parentheses in place, so the precedence was pretty clear.&lt;/p&gt;
&lt;p&gt;The other benefit of both parentheses and prefix notation is that we do not have to repeat the same operators more than once.&lt;/p&gt;
&lt;p&gt;C:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;int&lt;/span&gt; res = 1 + 2 + 3 + 4 + 5 + &lt;span style=&#34;&#34;&gt;…&lt;/span&gt; + N;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lisp:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 2 3 4 5 &lt;span style=&#34;&#34;&gt;…&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;N&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This seems like another minor advantage but actually lies deep inside Lisp&amp;rsquo;s core.
In Lisp, if we take the first element of such a list it will be a function &lt;code&gt;+&lt;/code&gt;, and if we take the rest of the list, we&amp;rsquo;ll have &lt;code&gt;(1 2 3 4 5 … N)&lt;/code&gt; list.
And in lisp we apply a function to a list of arguments, literally, so we can instead write &lt;code&gt;(apply + &#39;(1 2 3 4 5 … N))&lt;/code&gt;, and this will be the same as writing &lt;code&gt;(+ 1 2 3 … N)&lt;/code&gt; directly.
This is how most Lisp interpreters work under the hood, except apply is a core primitive, which is available for us as a function too.&lt;/p&gt;
&lt;p&gt;Now, still, there are a lot of parentheses if the examples I&amp;rsquo;ve shown above, so let&amp;rsquo;s think about how we can improve the situation.
One possible solution would be to change language in such a way that parentheses are not required, or required less often.&lt;/p&gt;
&lt;h2 id=&#34;fixing-the-problem-inside-the-language&#34;&gt;Fixing the problem inside the language&lt;/h2&gt;
&lt;p&gt;The problem of &lt;em&gt;too many parentheses&lt;/em&gt; in Lisp is real, and for a long time, people tried to solve it in different dialects.
So there are several ways to improve the situation, but if you ask me, the solution is &lt;em&gt;to learn to stop worrying and love the parentheses&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&#34;using-different-parentheses&#34;&gt;Using different parentheses&lt;/h3&gt;
&lt;p&gt;One solution is to use different parenthesis types, which are actually mean same thing, e.g. &lt;code&gt;(&lt;/code&gt; = &lt;code&gt;[&lt;/code&gt; = &lt;code&gt;{&lt;/code&gt;.
Some Scheme dialects, such as Racket, allow usage of other kinds of parentheses to make a structure more apparent as long as parentheses are matching depth level:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--racket-example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-racket&#34; data-lang=&#34;racket&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;font-weight:bold&#34;&gt;let*&lt;/span&gt; [(foo 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (bar (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; foo 32))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;*&lt;/span&gt; foo bar)}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--racket-example&#34;&gt;Code Snippet 5&lt;/a&gt;:&lt;/span&gt;
  Using different parentheses in Racket
&lt;/div&gt;
&lt;p&gt;While not as pretty as the single parenthesis type version, it is easier to see the structure because different expression boundaries are marked explicitly.
Also, curly braces will probably offend some die-hard Lisp hackers.&lt;/p&gt;
&lt;h3 id=&#34;using-fewer-parentheses-and-changing-parenthesis-semantics&#34;&gt;Using fewer parentheses and changing parenthesis semantics&lt;/h3&gt;
&lt;p&gt;Some dialects of Lisp use fewer parentheses for such expressions.
For example in Clojure, this code would look like this:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--clojure-example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 32)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--clojure-example&#34;&gt;Code Snippet 6&lt;/a&gt;:&lt;/span&gt;
  Using fewer parentheses, and different kinds for different expression types
&lt;/div&gt;
&lt;p&gt;Clojure uses both the reduction of unnecessary parentheses and different parenthesis kinds, but it is not just a stylistic change as in Racket.
In Clojure square brackets represent different data types, a vector to be precise, so you can&amp;rsquo;t write &lt;code&gt;let&lt;/code&gt; with ordinary parentheses around bindings.
While not as generic as in Scheme, this actually makes sense and provides nice semantics allowing humans to parse code easier.
And as we saw in Racket, it is common to wrap non-callable forms into square brackets, except in Clojure this is explicitly required for many forms.&lt;/p&gt;
&lt;h3 id=&#34;removing-parentheses&#34;&gt;Removing parentheses&lt;/h3&gt;
&lt;p&gt;There also were countless attempts of removing parentheses completely and using indentation with minimal syntax to represent structure.
The most recent attempt is &lt;a href=&#34;https://github.com/racket/rhombus-brainstorming&#34; target=&#34;_blank&#34;&gt;Project Rhombus&lt;/a&gt;, formerly known as Racket 2.
Here&amp;rsquo;s how the code above could look, accordingly to &lt;a href=&#34;https://github.com/racket/rhombus-brainstorming/pull/122&#34; target=&#34;_blank&#34;&gt;this RFC&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;org-example-block--rhombus-example&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;let (foo = 10,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     bar = (foo + 32)):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  foo * bar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#org-example-block--rhombus-example&#34;&gt;Code Snippet 1&lt;/a&gt;:&lt;/span&gt;
  Project Rhombus possible syntax
&lt;/div&gt;
&lt;p&gt;I, personally, do not like this, though this is just a proposal and not the final syntax.
But I think that the strength of Lisp in its parentheses is for one simple reason - &lt;strong&gt;Lisp syntax is based on data structures, not plain text&lt;/strong&gt;.
And the simpler the syntax for these data structures the better.
Representing lists via some syntax like colons, commas, and so on makes it harder to associate this with a simple list of things.
So whether we&amp;rsquo;re talking about macros, the reliability of the expression boundaries, and the generality of the syntax, this is all possible because of parentheses.&lt;/p&gt;
&lt;p&gt;And, since we&amp;rsquo;re not programming on punch cards anymore, instead of changing the syntax, we can use helper tools to deal with this &lt;em&gt;parenthesis problem&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&#34;editor-support&#34;&gt;Editor support&lt;/h3&gt;
&lt;p&gt;The most well-known editor for Lisp is Emacs.
Mainly because it is kind of a Lisp machine by itself, that implements its own Lisp dialect, called Emacs Lisp.
No wonder, Emacs has pretty good support for Lisp editing and a lot of packages that help with this task.&lt;/p&gt;
&lt;p&gt;Though I will use Emacs to show ways to interact with Lisp code, most of these features are available in other editors as well.
And the first thing I want to talk about is color.&lt;/p&gt;
&lt;h4 id=&#34;coloring-and-dimming&#34;&gt;Coloring and dimming&lt;/h4&gt;
&lt;p&gt;Some code editors have a so-called rainbow mode, to color parentheses in different colors, to make the structure more apparent.
This functionality is not unique to Lisps and can be used with any language that uses parentheses to declare scope, but I think it is most useful with Lisps, due to how many parentheses are usually stacked together on one line.
Here&amp;rsquo;s our &lt;code&gt;let&lt;/code&gt; &lt;a href=&#34;#code-snippet--scheme-example&#34;&gt;snippet&lt;/a&gt; with colored parentheses:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;
&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;color:#9b32a8&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;&lt;span style=&#34;color:#32a873&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a84c32&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 10&lt;span style=&#34;color:#a84c32&#34;&gt;)&lt;/span&gt;
       &lt;span style=&#34;color:#a84c32&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; &lt;span style=&#34;color:#81a832&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 32&lt;span style=&#34;color:#81a832&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a84c32&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#32a873&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#46d2eb&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt;&lt;span style=&#34;color:#46d2eb&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color:#9b32a8&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is close to using different parentheses as &lt;a href=&#34;#code-snippet--racket-example&#34;&gt;here&lt;/a&gt;, except works in any dialect of Lisp and does not require matching parentheses manually.&lt;/p&gt;
&lt;p&gt;After a certain period, this may not actually be needed, since many Lisp hackers indent their code with a set of well-established rules, so indentation represents structure.
Because of that, it is possible to dim parentheses away since they are not really needed to read properly formatted code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;
&lt;pre style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 10&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;
       &lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; &lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; 32&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#ccc&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color:#ccc&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is similar to the approach of ditching parentheses, but does not require re-implementing parsers, and rewriting all the code to use the new syntax.
Although, it does require proper formatting.&lt;/p&gt;
&lt;h4 id=&#34;formatting&#34;&gt;Formatting&lt;/h4&gt;
&lt;p&gt;Another one is also about indentation and formatting.
In Lisp, parentheses are usually stacked at the end of the expression, while in C-like languages, vertical alignment is preferred.
We can reformat that Racket code, and use only curly braces, to make it look more &lt;em&gt;traditional&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-racket&#34; data-lang=&#34;racket&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;let*&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            foo 10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            bar {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; foo 32
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;*&lt;/span&gt; foo bar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This may seem ridiculous, but this is still a valid Racket code.
I would recommend against doing this, but this is up to you to decide if you really want these C-like indentations in your code for some reason.&lt;/p&gt;
&lt;p&gt;Some other formatting rules are around as well, for example, here&amp;rsquo;s another one with C-like formatting, but less hideous:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;define &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or another one that suggests aligning parentheses on the separate line, but vertically aligning those with their opening scope:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;define &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)         ) ) )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which is an interesting approach, and makes it easy to see the structure, but makes it a bit harder to modify such code.
The main downside is that this will not work if different parentheses are used, because we&amp;rsquo;ll need to reverse their order:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-racket&#34; data-lang=&#34;racket&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;font-weight:bold&#34;&gt;define&lt;/span&gt; f (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda&lt;/span&gt; (x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;font-weight:bold&#34;&gt;lambda&lt;/span&gt; (y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; x y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&lt;/span&gt; x y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)         ] ) }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is valid but looks wrong because the parentheses are seemingly in a &lt;em&gt;reverse&lt;/em&gt; order.
This will not happen with a C-like approach though:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-racket&#34; data-lang=&#34;racket&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;font-weight:bold&#34;&gt;define&lt;/span&gt; f
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;lambda&lt;/span&gt; (x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [&lt;span style=&#34;font-weight:bold&#34;&gt;lambda&lt;/span&gt; (y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; x y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&lt;/span&gt; x y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This brings us to the point of making it easier not only to read but also to write Lisp code, with editing tools.&lt;/p&gt;
&lt;h4 id=&#34;structural-editing&#34;&gt;Structural editing&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://www.emacswiki.org/emacs/ParEdit&#34; target=&#34;_blank&#34;&gt;Paredit&lt;/a&gt;, &lt;a href=&#34;https://github.com/Fuco1/smartparens&#34; target=&#34;_blank&#34;&gt;Smartparens&lt;/a&gt;, and &lt;a href=&#34;https://github.com/abo-abo/lispy&#34; target=&#34;_blank&#34;&gt;Lispy&lt;/a&gt; are three most popular (AFAIK) packages for Lisp editing in Emacs.&lt;/p&gt;
&lt;p&gt;Their main on-the-surface difference is in that Lispy adheres to shorter commands, while Paredit sticks to Emacs-style keybindings&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, and Smartparens has both its own set and Paredit-like set:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Paredit command&lt;/th&gt;
&lt;th&gt;Paredit binding&lt;/th&gt;
&lt;th&gt;Lispy binding&lt;/th&gt;
&lt;th&gt;Lispy command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-forward&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-M-f&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;j&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-down&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-backward&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-M-b&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;k&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-up&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-backward-up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-M-u&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;h&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-left&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-forward-up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-M-n&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;l&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-right&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-raise-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;M-r&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;r&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-raise&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-convolute-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;M-?&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-convolute&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-forward-slurp-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-)&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;&amp;gt;&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-slurp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-forward-barf-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-}&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;&amp;laquo;/kbd&amp;gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-barf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-backward-slurp-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-(&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;&amp;gt;&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-slurp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;paredit-backward-barf-sexp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;C-{&lt;/kbd&gt;&lt;/td&gt;
&lt;td&gt;&lt;kbd&gt;&amp;laquo;/kbd&amp;gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lispy-barf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These tools prove that Lisp code is actually its AST.
And just like parentheses allow us to write macros, with tools like Paredit, we are able to manipulate AST in our editor mostly the same way.&lt;/p&gt;
&lt;h4 id=&#34;automatic-parenthesis-insertion&#34;&gt;Automatic parenthesis insertion&lt;/h4&gt;
&lt;p&gt;But the number of key bindings you need to know by heart with Paredit or Lispy may scare some programmers.
I&amp;rsquo;m one of those, and I didn&amp;rsquo;t really want to learn Paredit.
For people like us, there are modes that automatically insert matching closing parentheses when we insert opening one.&lt;/p&gt;
&lt;p&gt;There are many of these in Emacs, here are a few:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Fuco1/smartparens#usage&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;smartparens&lt;/code&gt;&lt;/a&gt; - great package, that has a lot of commands and Paredit-style commands for editing and navigation,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;electric-pair-mode&lt;/code&gt; - builtin mode, that works fairly well for non-Lisp languages, but is still usable with Lisps,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/joaotavora/autopair&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;auto-pair&lt;/code&gt;&lt;/a&gt; - another good package for automatic insertion of pair symbols.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These packages are fewer friction alternatives for Paredit and Lispy, but are more general and will work for most languages.
But what if we combine the idea of removing parentheses from Lisp and using indentation to represent the structure, without actually removing parentheses?&lt;/p&gt;
&lt;h4 id=&#34;parinfer&#34;&gt;Parinfer&lt;/h4&gt;
&lt;p&gt;Created by Shaun Lebron, &lt;a href=&#34;https://shaunlebron.github.io/parinfer/&#34; target=&#34;_blank&#34;&gt;Parinfer&lt;/a&gt; was what brought me into Lisp.
Since my first line of Lisp code, I was using &lt;span style=&#34;color:black;weight:bold&#34;&gt;Par&lt;/span&gt;&lt;span style=&#34;color:#999;weight=normal&#34;&gt;infer&lt;/span&gt;, and therefore it&amp;rsquo;s &lt;strong&gt;fair to say that I am&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&#34;font-size: 4rem&#34;&gt;
  &lt;center&gt;
    &lt;b&gt;
      &lt;span style=&#34;background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
                   -webkit-background-clip: text;
                   -webkit-text-fill-color: transparent;
                   -moz-background-clip: text;
                   -moz-text-fill-color: transparent;&#34;&gt;
        B I A S E D.
      &lt;/span&gt;
    &lt;/b&gt;
  &lt;/center&gt;
&lt;/div&gt;
&lt;p&gt;But even though, Parinfer is a great tool, that allows me to focus on editing code without thinking about trees all the time, as in structural editing.
And still allows me to reason about trees with simple indentation editing.&lt;/p&gt;
&lt;p&gt;Someone said that Parinfer turns Lisp into Python.
Well, this is half true.
Parinfer is more like this &lt;a href=&#34;https://srfi.schemers.org/srfi-49/srfi-49.html&#34; target=&#34;_blank&#34;&gt;SRFI:49&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;define (fac x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  if (&amp;lt;= x 0) 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      * x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        fac (- x 1)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s the same code, but with all parentheses in place:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;define &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fac&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0) 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fac&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 1))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we dim all parentheses completely, we&amp;rsquo;ll have problems with inline expression boundaries, so this is not an option.
For example, &lt;code&gt;if&lt;/code&gt; in Scheme accepts any amount of arguments, so here (human) interpreter would think that we compare &lt;code&gt;x&lt;/code&gt; against &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;define  fac x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  if  &amp;lt;= x 0  1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      * x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        fac  - x 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Python has &lt;em&gt;syntax&lt;/em&gt; that provides a way to express inline boundaries without parentheses:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fac&lt;/span&gt;(x):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; x &amp;lt;= 0: &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;else&lt;/span&gt;: &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; x * fac(x - 1)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So no, Parinfer won&amp;rsquo;t turn your Lisp code into Python but will allow thinking less about parentheses most of the time, because it uses indentation to infer those for you.&lt;/p&gt;
&lt;p&gt;But what exactly Parinfer does?
It&amp;rsquo;s a bit complicated to explain, but it infers closing parentheses based on indentation, by enforcing a line invariant.
So, whenever you insert spaces, in smart mode Parinfer preserves the structure, while also moving parentheses around if needed.
&lt;a href=&#34;https://shaunlebron.github.io/parinfer/#tools-for-writing-lisp&#34; target=&#34;_blank&#34;&gt;This section&lt;/a&gt; of Parinfer&amp;rsquo;s site explains it by using gears.
And you can try &lt;a href=&#34;http://shaunlebron.github.io/parinfer/demo&#34; target=&#34;_blank&#34;&gt;Parinfer demo editor&lt;/a&gt;.
Here&amp;rsquo;s a recording of me messing around:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-12-03-we-need-to-talk-about-parentheses/parinfer-demo.gif&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;From my point of view, this is the nicest way to write Lisp code*, because it is both transparent and highly predictable.
It does not require learning complex commands, and you still have a lot of automation, while being in full control of your code and indentation style.
The only thing Parinfer enforces is line invariant, which can be simplified down to these examples:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&#34;background-color:#acf2bd; border-top-left-radius: .2em; border-bottom-left-radius: .2em; border-top-right-radius: .2em; border-bottom-right-radius: .2em;&#34;&gt;Correct&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&#34;background-color:#fdb8c0; border-top-left-radius: .2em; border-bottom-left-radius: .2em; border-top-right-radius: .2em; border-bottom-right-radius: .2em;&#34;&gt;Incorrect&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;Line invariant notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;pre&gt;(&lt;br&gt;&lt;span style=&#34;background-color:#acf2bd; border-top-left-radius: .2em; border-bottom-left-radius: .2em; border-top-right-radius: .2em; border-bottom-right-radius: .2em;&#34;&gt; &lt;/span&gt;[])&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;&lt;pre&gt;(&lt;br&gt;[])&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;Indentation specifies that &lt;code&gt;[]&lt;/code&gt; is inner part of &lt;code&gt;()&lt;/code&gt; form&amp;lt;br&amp;gt;Structure doesn&amp;rsquo;t match indentation in incorrect example.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;pre&gt;()&lt;br&gt;[]&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;&lt;pre&gt;()&lt;br&gt;&lt;span style=&#34;background-color:#fdb8c0; border-top-left-radius: .2em; border-bottom-left-radius: .2em; border-top-right-radius: .2em; border-bottom-right-radius: .2em;&#34;&gt; &lt;/span&gt;[]&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;Absence of indentation means that &lt;code&gt;[]&lt;/code&gt; and &lt;code&gt;()&lt;/code&gt; are separate forms&amp;lt;br&amp;gt;Indentation doesn&amp;rsquo;t match structure in incorrect example.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Remembering this, you can understand what will happen when you insert or delete indentation, which makes it quite easy to make predictable edits without shortcuts.&lt;/p&gt;
&lt;p&gt;Although Shaun Lebron has &lt;a href=&#34;https://github.com/shaunlebron/parinfer/tree/master/lib&#34; target=&#34;_blank&#34;&gt;archived the Parinfer library repository&lt;/a&gt;, there&amp;rsquo;s an excellent &lt;a href=&#34;https://github.com/eraserhd/parinfer-rust&#34; target=&#34;_blank&#34;&gt;Rust port of Parinfer&lt;/a&gt;, with support for Vim and Kakoune.
There&amp;rsquo;s also great Emacs &lt;a href=&#34;https://github.com/justinbarclay/parinfer-rust-mode&#34; target=&#34;_blank&#34;&gt;package&lt;/a&gt; that uses this library, which has fully fledged Smart mode and works great.&lt;/p&gt;
&lt;p&gt;However, I&amp;rsquo;ve put an asterisk here for a reason:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From my point of view, this is the nicest way to write Lisp code*, because it is both transparent and highly predictable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As transparent and predictable as it is, Parinfer has one huge downside.
The code &lt;strong&gt;must&lt;/strong&gt; be formatted properly.
This is not a problem when you&amp;rsquo;re the only one working on the project, and you format your code properly.
But when working on a real-world application with a team, where everyone has their own view on how code should be formatted, there will be a lot of commits that just fix the indentation.
Because Lisp is a free-form language, which is another property we get for free by using parentheses.&lt;/p&gt;
&lt;h3 id=&#34;being-a-good-programmer&#34;&gt;Being a good programmer&lt;/h3&gt;
&lt;p&gt;The last thing, that we can probably address is the programmers themselves.
That is, we are also responsible for /too many parentheses/problems.
For example, I&amp;rsquo;ve seen some inexperienced Scheme programmers, who do not know about &lt;code&gt;let*&lt;/code&gt;, and write this code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt; 10))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt; 10)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var2&lt;/span&gt; 3) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which uses 26 parentheses.
Instead of:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let* &lt;/span&gt;((&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt; 10))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var2&lt;/span&gt; 3) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;var3&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which uses 18 parentheses.&lt;/p&gt;
&lt;p&gt;Or not using &lt;code&gt;cond&lt;/code&gt; instead of nested &lt;code&gt;if&lt;/code&gt; forms:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; good&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cond &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;1 2) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;what?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;2 2)) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;WHAT?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;) 1) 10) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;THIS IS NOT JAVASCRIPT!!!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:else&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;all good&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; Why?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;1 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;what?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;2 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;WHAT?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;) 1) 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;THIS IS NOT JAVASCRIPT!!!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;all good&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Actually, &lt;code&gt;cond&lt;/code&gt; and &lt;code&gt;let*&lt;/code&gt; are just a macro, that transforms to nested &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt; forms respectively, so why would you write this by hand?
Macros can save us &lt;strong&gt;a lot&lt;/strong&gt; of parentheses.
Here&amp;rsquo;s an example from &lt;a href=&#34;https://www.braveclojure.com&#34; target=&#34;_blank&#34;&gt;Clojure for the Brave and True&lt;/a&gt; book chapter 9:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--macro-reduces-nesting&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;promise&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;future&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;deliver&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 100 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Cheerio!&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  @(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying2&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;promise&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;future&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;deliver&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying2&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 400 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Pip pip!&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     @(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;promise&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;future&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;deliver&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 200 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&amp;#39;Ello, gov&amp;#39;na!&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By defining &lt;code&gt;enquene&lt;/code&gt; macro we can transform this code into:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enqueue&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 200 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&amp;#39;Ello, gov&amp;#39;na!&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enqueue&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 400 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Pip pip!&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;enqueue&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wait&lt;/span&gt; 100 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Cheerio!&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;println &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;saying&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which is both more generic, less entangled, uses fewer parentheses, and in fact, produces the very same code in the end.&lt;/p&gt;
&lt;p&gt;There are a lot of helpful macros in Lisps, which expand language and allow you to do the same.
However, we need to remember that macros are complex beasts, and often reading macro is really hard, so it&amp;rsquo;s better to document its complex transformations.
So as a rule of thumb it&amp;rsquo;s not often feasible to write one when a function will do.
But being able to do this is still a huge deal, as we are able to shape the language into our application instead of just using it as a tool.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;While I do not find jokes in this comic funny (except maybe C one), the Lisp part is pretty representative of how non-Lispers see Lisps in general, which is unfortunate.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/abo-abo/lispy#introduction&#34; target=&#34;_blank&#34;&gt;https://github.com/abo-abo/lispy#introduction&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: We need to talk about parentheses&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 03 Dec 2020 22:51:00 +0300</pubDate>
    </item><item>
      <title>Raymarching with Fennel and LÖVE</title>
      <link>https://andreyor.st/posts/2020-10-15-raymarching-with-fennel-and-love/</link>
      <guid>https://andreyor.st/posts/2020-10-15-raymarching-with-fennel-and-love/</guid>
      <description>&lt;p&gt;Previously I decided to implement a rather basic &lt;a href=&#34;https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/&#34;&gt;raycasting engine in ClojureScript&lt;/a&gt;.
It was a lot of fun, an interesting experience, and ClojureScript was awesome.
I&amp;rsquo;ve implemented a small &lt;a href=&#34;https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/#labyrinth-game&#34;&gt;labyrinth game&lt;/a&gt; and thought about adding more features to the engine, such as camera shake, and wall height change.
But when I started working on these, I quickly understood, that I&amp;rsquo;d like to move on to something more interesting, like a real 3D rendering engine, that also uses rays.
&amp;lt;!&amp;ndash;more&amp;ndash;&amp;gt;
Obviously, my first thought was about writing a ray-tracer&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.
This technique is widely known and gained a lot of traction recently.
With native hardware support for ray tracing, a lot of games are using it, and there are a lot of tutorials teaching how to implement one&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.
In short, we cast a bunch of rays in 3D space, and calculate their trajectories, looking for what ray will hit and bounce off.
Different materials have different bounce properties, and by tracing rays from the camera to the source of light, we can imitate illumination.
There are also a lot of different approaches how to calculating bouncing, e.g. for global illumination, and ambient light, but I&amp;rsquo;ve felt that it is a rather complicated task, for a weekend post.
And unlike raycasting, most ray-tracers require polygonal information in order to work, whereas raycasting only needs to know wall start and end points.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve wanted a similar approach for 3D rendering, where we specify an object in terms of its mathematical representation.
Like for a sphere, we&amp;rsquo;ll just specify coordinates of a center, and a radius, and our rays will find intersection points with it, providing us sufficient data to draw this sphere on screen.
And recently, I&amp;rsquo;ve read about a similar technique, that uses rays for drawing on the screen, but instead of casting infinite rays as in raycasting, it marches a ray in terms of steps.
And it also uses a special trick, to make this process very optimized, therefore we can use it for rendering real 3D objects.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve decided to structure this post similarly to the one about raycasting, so this will be another long-read, often more about Fennel rather than raymarching, but at the end, I promise that we&amp;rsquo;ll get something that looks like this:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/end-result.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;So, just as in raycasting, first we need to do is to understand how the raymarching engine works &lt;em&gt;on paper&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;raymarching-basics&#34;&gt;Raymarching basics&lt;/h2&gt;
&lt;p&gt;Raymarching can be illustrated similarly to raycaster, except it requires more steps until we could render our image.
First, we need a camera, and an object to look at:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/camera-and-circle.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Our first step would be to cast a ray, however, unlike with raycasting, we&amp;rsquo;ll cast a portion of a ray:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/camera-and-circle-short-ray.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We then check if the ray intersects with the sphere.
It&amp;rsquo;s not, so we do one more step:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/camera-and-circle-two-steps.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;It&amp;rsquo;s not intersecting yet, so we repeat again:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/camera-and-circle-ray-overshoot.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Oops, the ray overshot and is now inside the sphere.
This is not really good option for us, as we want our rays to end directly at the object&amp;rsquo;s surface, without calculating the intersection point with the object itself.
We can fix this by casting a shorter ray:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/camera-and-circle-small-rays.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;However, this is very inefficient!
And besides, if we&amp;rsquo;ll change the angle a bit or move the camera, we will overshoot again.
This means that we&amp;rsquo;ll either have an incorrect result or require a very small step size, which will blow up the computation process.
How we can fix this?&lt;/p&gt;
&lt;h3 id=&#34;distance-estimation&#34;&gt;Distance estimation&lt;/h3&gt;
&lt;p&gt;The solution to this is a signed distance function or a so-called Distance Estimator.
Imagine if we knew how far we are from the object at any point in time?
This would mean that we can shoot a ray of this length in any direction and still don&amp;rsquo;t hit anything.
Let&amp;rsquo;s add another object to the scene:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/scene-with-two-objects.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Now, let&amp;rsquo;s draw two circles, which will represent distances from the objects to the point from where we&amp;rsquo;ll cast rays:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/distances.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can see, that there are two circles, and one is bigger than another.
This means, that if we choose the shortest safe distance, we can safely cast rays in any direction and not overshoot anything.
For example, let&amp;rsquo;s cast a ray towards the square:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/ray-in-safe-zone.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can see, that we haven&amp;rsquo;t reached the square, but more importantly, we did not overshoot it.
Now we need to march the ray again, but what distance should it cover?
To answer this question, we need to take another distance estimation from the ray end to the objects in the scene:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/second-safe-march.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Once again we choose a shorter distance, and march towards the square, then get the distance again, and repeat the whole process:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/another-safe-match.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;You can see that with each step the distance to the object becomes smaller, and thus we will never overshoot the object.
However, this also means, that we will take a lot of really small steps until we finally fully hit the object if we ever do.
This is not a good idea, because it is even more inefficient than using fixed distance, and produces too accurate results, which we don&amp;rsquo;t really need.
So instead of marching up until we exactly hit the object, we will march &lt;em&gt;enough&lt;/em&gt; times.
E.g., until the distance to the object is small enough, then there&amp;rsquo;s no real point to continue marching, as it is clear that we will hit the object soon.
But this also means, that if the ray goes near the edge of an object, we do a lot of expensive steps of computing distance estimations.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a ray that is parallel to the side of the square, and marches towards the circle:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/expensive-marching.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We do a lot of seemingly pointless measurements, and if a ray was closer to the square&amp;rsquo;s side, we would do even more steps.
However, this also means, that we can use this data (since we&amp;rsquo;re already computed it) to render such things as glow, or ambient occlusion.
But more on this later.&lt;/p&gt;
&lt;p&gt;Once a ray hit an object we have all the data we need.
Ray represents a point on the screen, and the more rays we cast the higher resolution of our image will be.
And since we&amp;rsquo;re not using triangles to represent objects, our spheres will always be smooth, no matter how close we are to them, because there are no polygons involved.&lt;/p&gt;
&lt;p&gt;This is basically it.
Ray marching is a quite simple concept, just like raycaster, although it&amp;rsquo;s a bit more complicated, as we do have to compute things in 3D space now.
So let&amp;rsquo;s begin implementing it by installing the required tools, and setting up the project.&lt;/p&gt;
&lt;h2 id=&#34;project-structure&#34;&gt;Project structure&lt;/h2&gt;
&lt;p&gt;As you know from the title we will use two main tools to create ray-marcher, which are &lt;a href=&#34;https://love2d.org/&#34; target=&#34;_blank&#34;&gt;LÖVE&lt;/a&gt;, a free game engine, and &lt;a href=&#34;https://fennel-lang.org/&#34; target=&#34;_blank&#34;&gt;Fennel&lt;/a&gt; the programming language.
I&amp;rsquo;ve chosen Fennel, because it is a Lisp-like language, that compiles to Lua, and I&amp;rsquo;m quite a fan of Lisps.
But we also needed to draw somewhere, and I know no GUI toolkit for Lua.
But there is LÖVE - a game engine that runs Lua code, which is capable of running on all systems, thus a perfect candidate for our task.&lt;/p&gt;
&lt;p&gt;Installation steps may differ per operating system, so please refer to manuals&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;, &lt;/sup&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.
At the time of writing this post, I&amp;rsquo;m using Fedora GNU/Linux, so for me it means:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo dnf install love luarocks readline-devel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ luarocks install --local fennel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ luarocks install --local readline &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;# requires readline-devel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;PATH&lt;/span&gt;=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$PATH&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;$HOME&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;/.luarocks/bin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s better to permanently add &lt;code&gt;$HOME/luarocks/bin&lt;/code&gt; (or another path, if your installation differs) to the &lt;code&gt;PATH&lt;/code&gt; variable in your shell, in order to be able to use installed utilities without specifying the full path every time.
You can test if everything is installed correctly, by running &lt;code&gt;fennel&lt;/code&gt; in your command line.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ fennel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Welcome to Fennel 0.5.0 on Lua 5.3!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Use (doc something) to view documentation.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;&amp;gt; (+ 1 2 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For other distributions, installation steps may vary, and for Windows, I think it&amp;rsquo;s safe to skip the &lt;code&gt;readline&lt;/code&gt; part, which is fully optional but makes editing in a REPL a bit more comfortable.&lt;/p&gt;
&lt;p&gt;Once everything is installed, let&amp;rsquo;s create the project directory and the &lt;code&gt;main.fnl&lt;/code&gt; file, where we will write our code.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir love_raymarching
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cd&lt;/span&gt; love_raymarching
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ touch main.fnl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And that&amp;rsquo;s it!
We can test if everything works by adding this code to &lt;code&gt;main.fnl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.draw&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.graphics.print&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;It works!&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can compile it with &lt;code&gt;fennel --compile main.fnl &amp;gt; main.lua&lt;/code&gt;, thus producing the &lt;code&gt;main.lua&lt;/code&gt; file, and run &lt;code&gt;love .&lt;/code&gt; (dot is intentional, it indicates current directory).&lt;/p&gt;
&lt;p&gt;A window should appear, with white text &lt;code&gt;It works!&lt;/code&gt; in the upper left corner:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/love-works.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Now we can begin implementing our ray marcher.&lt;/p&gt;
&lt;h2 id=&#34;scene-setup&#34;&gt;Scene setup&lt;/h2&gt;
&lt;p&gt;Just as in raycaster, we need a camera that will shoot rays, and some objects to look at.
Let&amp;rsquo;s begin by creating a camera object, that will store coordinates and rotation information.
We can do so, by using &lt;code&gt;var&lt;/code&gt; to declare a variable that is local to our file, and that we can later change with &lt;code&gt;set&lt;/code&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--camera-unit&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [0.0 0.0 0.0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x-rotate&lt;/span&gt; 0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z-rotate&lt;/span&gt; 0.0})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;For those unfamiliar with Lisps, and especially Clojure, let me quickly explain what this syntax is.
If you know this stuff, feel free to &lt;a href=&#34;#org-target--end-of-syntax-explanation&#34;&gt;skip this part&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We start by using a &lt;code&gt;var&lt;/code&gt; special form, that binds a value to a name like this: &lt;code&gt;(var name value)&lt;/code&gt;.
So if we start the REPL, using the &lt;code&gt;fennel&lt;/code&gt; command in the shell, and write &lt;code&gt;(var a 40)&lt;/code&gt;, a new variable &lt;code&gt;a&lt;/code&gt; will be created.
We then can check, that it has the desired value by typing &lt;code&gt;a&lt;/code&gt;, and pressing return:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 40)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;40
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then alter the contents of this variable by using &lt;code&gt;set&lt;/code&gt; special form, which works like this &lt;code&gt;(set name new-value)&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;42
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now to curly and square brackets.
Everything enclosed in curly braces is a hashmap.
We can use any Lua value as our key, and the most common choice is a string, but Fennel has additional syntax for defining keys - a colon followed by a word: &lt;code&gt;:a&lt;/code&gt;.
This is called a keyword, and in Fennel, it is essentially the same as &lt;code&gt;&amp;quot;a&amp;quot;&lt;/code&gt;, but we don&amp;rsquo;t need to write a pair of quotes.
However, keywords can&amp;rsquo;t contain spaces and some other symbols.&lt;/p&gt;
&lt;p&gt;So writing this &lt;code&gt;{:a 0 :b 2 :c :hello}&lt;/code&gt; in the REPL will make a new table, that holds three key-value pairs, which we can later get with another syntax - the dot &lt;code&gt;.&lt;/code&gt;.
Combining it with &lt;code&gt;var&lt;/code&gt;, we can see that it works:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:c&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:hello&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s also a shorthand for this syntax, that is, we can type &lt;code&gt;m.b&lt;/code&gt; and access the &lt;code&gt;:b&lt;/code&gt; key&amp;rsquo;s value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m.b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m.c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that even though we&amp;rsquo;ve specified the value for &lt;code&gt;:c&lt;/code&gt; as &lt;code&gt;:hello&lt;/code&gt;, the REPL printed it to us as &lt;code&gt;&amp;quot;hello&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re left with square brackets now, and this is a plain simple vector.
It can grow and shrink, and store any Lua values in it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; [0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;b c&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;b c&amp;#34;&lt;/span&gt; #&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;function&lt;/span&gt;&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; 0&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x56482230e090&amp;gt;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However Lua doesn&amp;rsquo;t really have vectors or arrays, and it utilizes tables for this, where keys are simply indexes.
So the code above is equivalent to this Fennel expression &lt;code&gt;{1 0 2 &amp;quot;a&amp;quot; 3 &amp;quot;b c&amp;quot; 4 (fn [x] x)}&lt;/code&gt;, but we can use square brackets for convenience.&lt;/p&gt;
&lt;p&gt;Note, that we can combine indexed tables (vectors) and ordinary tables (hashmaps) together.
We can do it as shown above, by specifying indexes as keys, or defining a vector var and &lt;code&gt;set&lt;/code&gt; a key in it to some value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt; [0 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v.a&lt;/span&gt; 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 1 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 2 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 3 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--end-of-syntax-explanation&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So camera is essentially a &lt;a href=&#34;https://www.lua.org/pil/2.5.html&#34; target=&#34;_blank&#34;&gt;Lua table&lt;/a&gt;, that stores keys &lt;code&gt;:pos&lt;/code&gt;, &lt;code&gt;:x-rotate&lt;/code&gt;, and &lt;code&gt;:y-rotate&lt;/code&gt;, each storing a respective value.
We use a vector as our position, and two floats as our rotation angles.
Now we can make objects, but before that, we need a scene to store those objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; [])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yep, that&amp;rsquo;s our scene.
Nothing fancy, simply an empty vector to which we will later add objects.&lt;/p&gt;
&lt;p&gt;Now we can create these objects, so let&amp;rsquo;s start with perhaps the simplest one - a sphere.
And I&amp;rsquo;ll also briefly explain what makes raymarching different from other methods of creating 3D graphics.&lt;/p&gt;
&lt;h3 id=&#34;creating-objects&#34;&gt;Creating objects&lt;/h3&gt;
&lt;p&gt;What is a sphere?
That depends on the domain, we&amp;rsquo;re working in.
Let&amp;rsquo;s open up &lt;a href=&#34;https://www.blender.org/&#34; target=&#34;_blank&#34;&gt;Blender&lt;/a&gt;, remove the default cube, and create sphere with &lt;kbd&gt;Shift+a&lt;/kbd&gt;, Mesh, UV Sphere:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/blender-uv-sphere.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;To me, this looks nothing like a sphere, because it consists of rectangles.
However, if we subdivide the surface, we can get a more correct representation:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/blender-uv-sphere-subdivided.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;This looks more like a sphere, but this is still just an approximation.
Theoretically, if we move very close to it, we will see the edges and corners, especially with flat shading.
Also, each subdivision adds more points, and it gets more and more expensive to compute:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/subdivisions.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We have to make these trade-offs because we don&amp;rsquo;t need very accurate spheres when we need real-time processing.
But raymarching doesn&amp;rsquo;t have this limitation, because the sphere in raymarching is defined by the point and radius length.
Which we can then work with by using the signed distance function.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s create a function, that will produce a sphere:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radius&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; [1 1 1])]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:radius&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radius&lt;/span&gt; 5)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; 0)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 0)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:sdf&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere-distance&lt;/span&gt; &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s a lot of stuff going on, so let&amp;rsquo;s dive into it.&lt;/p&gt;
&lt;p&gt;This is a so-called constructor - a function, that takes some parameters and constructs an object with these parameters applied, then returns it.
In most typed languages we would define a class, or structure to represent this object, however, in Fennel (and hence in Lua) we can just use a table.
And this is my favorite part of such languages.&lt;/p&gt;
&lt;p&gt;So we used &lt;code&gt;fn&lt;/code&gt; special form to create a function named &lt;code&gt;sphere&lt;/code&gt;, that takes three parameters: &lt;code&gt;radius&lt;/code&gt;, position in space &lt;code&gt;pos&lt;/code&gt;, and &lt;code&gt;color&lt;/code&gt; ➊.
Then we see another special form &lt;code&gt;let&lt;/code&gt;.
It is used to introduce locally scoped variables and has another nice property - destructuring ➋.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s quickly understand how &lt;code&gt;let&lt;/code&gt; works in this case.
If you know how destructuring works, you can &lt;a href=&#34;#org-target--end-of-let-breakdown&#34;&gt;skip this part&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a simple example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve introduced two local variables &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, which hold values &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; respectively.
Then we computed their sum and returned it as a result.&lt;/p&gt;
&lt;p&gt;This is good, but what if we wanted to compute a sum of three vector elements multiplied by &lt;code&gt;b&lt;/code&gt;?
Let&amp;rsquo;s put a vector into &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; [1 2 3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;???&amp;gt;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are many ways to do this, such as &lt;code&gt;reduce&lt;/code&gt; over a vector with a function that sums elements, or getting values from the vector in a loop and putting those into some local variable.
However, in the case of our project, we always know exactly how many elements there will be, so we can just take these out by indexes without any kind of loop:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; [1 2 3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 3)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a3&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yet, this is very verbose, and not really good.
We can make it a bit less verbose by skipping local variable definitions and using values directly in the sum:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; [1 2 3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;value of the second element is &amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 1) (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 2) (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 3)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;of&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;second &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;element&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;is&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, again, this isn&amp;rsquo;t really great, as we have to repeat the same syntax three times, and what if we want to use the second value from the vector in several places?
Like here, I&amp;rsquo;ve added &lt;code&gt;print&lt;/code&gt; since I particularly about the second element&amp;rsquo;s value, and want to see it in the log, but I have to repeat myself and get the second element twice.
We could use a local binding for this, but we don&amp;rsquo;t want to do this manually.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where destructuring comes in handy, and trust me, it is a very handy thing.
We can specify a pattern, that is applied to our data, and binds variables for us like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a3&lt;/span&gt;] [1 2 3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;value of the second element is &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a3&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;of&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;second &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;element&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;is&lt;/span&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works somewhat like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1  2  3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ↓  ↓  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[a1 a2 a3]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is much shorter than any of the previous examples and allows us to use any vector values in several places.&lt;/p&gt;
&lt;p&gt;We can also destructure maps like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a-key&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b-key&lt;/span&gt; 2})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a-key&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b-key&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And this also has a shorthand for when the name of the key and the name of desired local binding will match:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:a&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:b&lt;/span&gt; 2})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which is even shorter.&lt;/p&gt;
&lt;p&gt;All this essentially boils down to this kind of Lua code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- vector destructuring&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- (let [[a b] [1 2]] (+ a b))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; _0_ = {1, 2}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; a = _0_[1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; b = _0_[2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; (a + b)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- hashmap destructuring&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- (let [{: a : b} {:a 1 :b 2}] (+ a b))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; _0_ = {a = 1, b = 2}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; a = _0_[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; b = _0_[&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;b&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; (a + b)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is nothing special really, but this example still shows the power of Lisp&amp;rsquo;s macro system, in which destructuring is implemented.
But it gets really cool when we use this in function forms, as we will see later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--end-of-let-breakdown&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If we were to call &lt;code&gt;(sphere)&lt;/code&gt; now, we would get an error, because we specified a value ➌ for a key &lt;code&gt;:sdf&lt;/code&gt;, that doesn&amp;rsquo;t yet exist.
SDF stands for &lt;a href=&#34;https://en.wikipedia.org/wiki/Signed_distance_function&#34; target=&#34;_blank&#34;&gt;Signed Distance Function&lt;/a&gt;.
That is a function, that will return the distance from a given point to an object.
The distance is positive when the point is outside of the object and negative when the point is inside the object.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s define an SDF for a sphere.
What&amp;rsquo;s great about spheres, is that to compute the distance to the sphere&amp;rsquo;s surface, we only need to compute the distance to the center of the sphere, and subtract the sphere&amp;rsquo;s radius from this distance.&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_9184447246721f1ac8fa15ea8fc4c62e5817d1d9.svg&#34; alt=&#34;\[d(P,S)=\sqrt{(S_x-P_x)^2+(S_y-P_y)^2+(S_z-P_z)^2}-S_r\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;Let&amp;rsquo;s implement this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.sqrt&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere-distance&lt;/span&gt; [{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sy&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sz&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radius&lt;/span&gt;} [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]] &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) 2) (^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sy&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;) 2) (^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sz&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;) 2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radius&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;a href=&#34;https://www.lua.org/gems/sample.pdf&#34; target=&#34;_blank&#34;&gt;performance reasons&lt;/a&gt; we declare &lt;code&gt;math.sqrt&lt;/code&gt; as a &lt;code&gt;local&lt;/code&gt; variable &lt;code&gt;sqrt&lt;/code&gt;, that holds function value, to avoid repeated table lookup.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As was later pointed out, Luajit does optimize such calls, and there is no repeated lookup for method calls.
This is still true for plain Lua, so I&amp;rsquo;m going to keep this as is, but you can skip all these local definitions if you want and use methods directly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And at ➋ we again see destructuring, however not in the &lt;code&gt;let&lt;/code&gt; block, but in the function argument list.
What essentially happens here is this - function takes two parameters, the first of which is a hashmap, which must have a &lt;code&gt;:pos&lt;/code&gt; keyword associated with a vector of three numbers, and a &lt;code&gt;:radius&lt;/code&gt; keyword with a value.
The second parameter is simply a vector of three numbers.
We immediately destructured these parameters into a set of variables local to the function body.
Hashmap is being destructured into sphere position vector, which is immediately destructured to &lt;code&gt;sx&lt;/code&gt;, &lt;code&gt;sy&lt;/code&gt;, and &lt;code&gt;sz&lt;/code&gt;, and a &lt;code&gt;radius&lt;/code&gt; variable storing sphere&amp;rsquo;s radius.
Second parameter is destructured to &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt;.
We then compute the resulting value by using the formula above.
However, Fennel and Lua only understand definitions in the order from the top to the bottom, so we need to define &lt;code&gt;sphere-distance&lt;/code&gt; before &lt;code&gt;sphere&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s test our function by passing several points and a sphere of radius 5:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere-distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 5) [5 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere-distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 5) [0 15 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere-distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 5) [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-5.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great!
First, we check if we&amp;rsquo;re on the sphere&amp;rsquo;s surface, because the radius of our sphere is &lt;code&gt;5&lt;/code&gt;, and we&amp;rsquo;ve set &lt;code&gt;x&lt;/code&gt; coordinate to &lt;code&gt;5&lt;/code&gt; as well.
Next, we check if we&amp;rsquo;re &lt;code&gt;10&lt;/code&gt; something away from the sphere, and lastly, we check that we&amp;rsquo;re &lt;em&gt;inside&lt;/em&gt; the sphere because the sphere&amp;rsquo;s center and our point both are at the origin.&lt;/p&gt;
&lt;p&gt;But we also can call this function as a method with &lt;code&gt;:&lt;/code&gt; syntax:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;s&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;s&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:sdf&lt;/span&gt; [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works because methods in Lua are syntactic sugar.
When we write &lt;code&gt;(s:sdf p)&lt;/code&gt; it is essentially equal to &lt;code&gt;(s.sdf s p)&lt;/code&gt;, and our distance function takes sphere as its first parameter, which allows us to utilize method syntax.&lt;/p&gt;
&lt;p&gt;Now we need a distance estimator - a function that will compute distances to all objects and will return the shortest one, so we could then safely extend our ray by this amount.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt; 1000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;each&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;object&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ipairs&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;object&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:sdf&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;min&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;object&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;values&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function will compute the distance to &lt;code&gt;each&lt;/code&gt; object in the &lt;code&gt;scene&lt;/code&gt; from given &lt;code&gt;point&lt;/code&gt;, using our signed distance functions, and will choose the minimum distance and the color of this ray.
Even though it makes little sense to return color from the distance-estimator, we&amp;rsquo;re doing this here because we don&amp;rsquo;t want to compute this whole process again just to get the color of the endpoint.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s check if this function works:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [5 4 0] [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 2 [5 7 0] [0 1 0])])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1.0     [0 1 0]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It works, we obtained the distance to the second sphere, and its color because the point we specified was closer to this sphere than to the other.&lt;/p&gt;
&lt;p&gt;With the camera, object, a scene, and this function we have all we need to start shooting rays and rendering this on screen.&lt;/p&gt;
&lt;h2 id=&#34;marching-ray&#34;&gt;Marching ray&lt;/h2&gt;
&lt;p&gt;Just as in raycaster, we cast rays from the camera, but now we do it in 3D space.
In raycasting, our horizontal resolution was specified by a number of rays, and our vertical resolution was basically infinite.
For 3D this is not an option, so our resolution now depends on the 2D matrix of rays, instead of the 1D matrix.&lt;/p&gt;
&lt;p&gt;Quick math.
How many rays we&amp;rsquo;ll need to cast in order to fill up 512 by 448 pixels?
The answer is simple - multiply width and height and here&amp;rsquo;s the amount of rays you&amp;rsquo;ll need:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;512 448)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;229376
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A stunning &lt;code&gt;229376&lt;/code&gt; rays to march.
And each ray has to do many distance estimations as it marches away from the point.
Suddenly, all that micro-optimizations, like locals for functions do not feel that unnecessary.
Let&amp;rsquo;s hope for the best and that LÖVE will handle real-time rendering.
We can begin by creating a function that marches a single ray in the direction our camera looks.
But first, we need to define what we would use to specify coordinates, directions, and so on in our 3D space.&lt;/p&gt;
&lt;p&gt;My first attempt was to use &lt;a href=&#34;https://en.wikipedia.org/wiki/Spherical_coordinate_system&#34; target=&#34;_blank&#34;&gt;spherical coordinates&lt;/a&gt; to define ray direction and move points in 3D space relative to the camera.
However, it had a lot of problems, especially when looking at objects at angles different from 90 degrees.
Like here&amp;rsquo;s a screenshot of me looking at the sphere from the &amp;ldquo;front&amp;rdquo;:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/spherical-ok.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;And here&amp;rsquo;s when looking from &amp;ldquo;above&amp;rdquo;:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/spherical-not-ok.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;And when I added the cube object, I noticed a &lt;em&gt;slight&lt;/em&gt; fish-eye distortion effect:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/spherical-distortion.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Which was not great at all.
So I&amp;rsquo;ve decided that I would remake everything with vectors, and make a proper camera, with a &amp;ldquo;look-at&amp;rdquo; point, will compute projection plane, and so on.&lt;/p&gt;
&lt;p&gt;And to do this we need to be able to work with vectors - add those, multiply, normalize, e.t.c.
I&amp;rsquo;ve wanted to refresh my knowledge on this topic, and decided not to use any existing library for vectors, and implement everything from scratch.
It&amp;rsquo;s not that hard.
Especially when we already have vectors in the language, and can destructure it to variables with ease.&lt;/p&gt;
&lt;p&gt;So we need these basic functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vec3&lt;/code&gt; - a constructor with some handy semantics,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vec-length&lt;/code&gt; - function that computes magnitude of vector,&lt;/li&gt;
&lt;li&gt;arithmetic functions, such as &lt;code&gt;vec-sub&lt;/code&gt;, &lt;code&gt;vec-add&lt;/code&gt;, and &lt;code&gt;vec-mul&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;and other unit vector functions, mainly &lt;code&gt;normalize&lt;/code&gt;, &lt;code&gt;dot-product&lt;/code&gt;, and &lt;code&gt;cross-product&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the source code of each of these functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) [0 0 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;)) [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; 0)]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-length&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(^ &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 2) (^ &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 2) (^ &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; 2))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;)])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;)])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;)])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;len&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;len&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;len&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;len&lt;/span&gt;)]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dot&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cross&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt;))])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since we already know how destructuring works, it&amp;rsquo;s not hard to see what these functions do.
&lt;code&gt;vec3&lt;/code&gt;, however, has some logic in it, and you can notice that &lt;code&gt;if&lt;/code&gt; has three outcomes.
&lt;code&gt;if&lt;/code&gt; in Fennel is more like &lt;code&gt;cond&lt;/code&gt; in other lisps, which means that we can specify as many &lt;code&gt;else if&lt;/code&gt; as we want.&lt;/p&gt;
&lt;p&gt;Therefore, calling it without arguments produces a zero-length vector &lt;code&gt;[0 0 0]&lt;/code&gt;.
If called with one argument, it returns a vector where each coordinate is set to this argument: &lt;code&gt;(vec 3)&lt;/code&gt; will produce &lt;code&gt;[3 3 3]&lt;/code&gt;.
In other cases we either specified or not specified &lt;code&gt;z&lt;/code&gt;, so we can simply create a vector with &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and either &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;z&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You may wonder, why this is defined as functions, and why I didn&amp;rsquo;t implement operator overloading, so we could simply use &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;*&lt;/code&gt; to compute values?
I&amp;rsquo;ve tried this, however, this is extremely slow, since on each operation we have to do a lookup in meta-table, and this is like really slow.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a quick benchmark:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;macro&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;body&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;os.clock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;start#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res#&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;body&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Elapsed &amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;1000 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;start#&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; ms&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res#&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; operator overloading&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;vector &lt;/span&gt;{})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector.__index&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3-meta&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;setmetatable&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector.__add&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z2&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3-meta&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z2&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v0&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3-meta&lt;/span&gt; 1 1 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0 1000000] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v0&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; basic functions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector-add&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z2&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z2&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; 1 1 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0 1000000] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector-add&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector-add&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vector-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v1&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v1&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;v1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we run it with &lt;code&gt;lua&lt;/code&gt; interpreter, we&amp;rsquo;ll see the difference:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ fennel --compile test.fnl | lua
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Elapsed 1667.58 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Elapsed 1316.078 ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Testing this with &lt;code&gt;luajit&lt;/code&gt; claims that this way is actually faster, &lt;strong&gt;however&lt;/strong&gt;, I&amp;rsquo;ve experienced a major slowdown in the renderer - everything ran about 70% slower, according to the frame per second count.
So functions are okay, even though are much more verbose.&lt;/p&gt;
&lt;p&gt;Now we can define a &lt;code&gt;march-ray&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MARCH-DELTA&lt;/span&gt; 0.0001)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MAX-STEPS&lt;/span&gt; 500)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;march-ray&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;&#34;&gt;➍&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-distance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-color&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MARCH-DELTA&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MAX-STEPS&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-distance&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt; 1))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;values&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Not much, but we have some things to discuss.&lt;/p&gt;
&lt;p&gt;First, we define a function to move points in 3D space ➊.
It accepts a &lt;code&gt;point&lt;/code&gt;, which is a three-dimensional vector, a direction vector &lt;code&gt;dir&lt;/code&gt;, which must be normalized, and a &lt;code&gt;distance&lt;/code&gt;.
We then multiply the direction vector by a vector that consists of our distances and add it to the point.
Simple and easy.&lt;/p&gt;
&lt;p&gt;Next, we define several constants, and the &lt;code&gt;march-ray&lt;/code&gt; function itself.
It Defines some local vars, that hold initial values, and uses a &lt;code&gt;while&lt;/code&gt; loop to march a given ray enough times.
You can notice, that at ➋ we created a &lt;code&gt;not-done?&lt;/code&gt; var, that holds &lt;code&gt;true&lt;/code&gt; value, and then use it in the &lt;code&gt;while&lt;/code&gt; loop as our test.
And you also can notice that at ➌ we have a test, in case of which we &lt;code&gt;set&lt;/code&gt; &lt;code&gt;not-done?&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; and exit the loop.
So you may wonder, why not use &lt;code&gt;for&lt;/code&gt; loop instead?
Lua supports index-based &lt;code&gt;for&lt;/code&gt; loops.
Fennel also has support for these.
So why use &lt;code&gt;while&lt;/code&gt; with a &lt;code&gt;variable&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Because Fennel has no &lt;code&gt;break&lt;/code&gt; special form for some reason.&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--break-rant&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here&amp;rsquo;s a little rant.
You &lt;a href=&#34;#org-target--end-of-break-rant&#34;&gt;can skip it&lt;/a&gt; if you&amp;rsquo;re not interested in me making unconfirmed inferences about Fennel :).&lt;/p&gt;
&lt;p&gt;I think that Fennel doesn&amp;rsquo;t support &lt;code&gt;break&lt;/code&gt; because Fennel is influenced by Clojure (correct me if I&amp;rsquo;m wrong), and Clojure doesn&amp;rsquo;t have &lt;code&gt;break&lt;/code&gt; either.
However, looping in Clojure is a bit more controllable, as we &lt;em&gt;choose&lt;/em&gt; when we want to go to the next iteration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; do stuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which means that &lt;code&gt;when&lt;/code&gt; &lt;code&gt;i&lt;/code&gt; is less then &lt;code&gt;10&lt;/code&gt; I want you to perform another iteration.&lt;/p&gt;
&lt;p&gt;In Fennel, however, the concept isn&amp;rsquo;t quite like this, because we have to define a &lt;code&gt;var&lt;/code&gt; explicitly, and put it into the &lt;code&gt;while&lt;/code&gt; test position:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; do stuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may not see the difference, but I do.
This also can be trivially expressed as a &lt;code&gt;for&lt;/code&gt; loop: &lt;code&gt;(for [i 0 10] (do-stuff))&lt;/code&gt;.
However, not every construct can be defined as &lt;code&gt;for&lt;/code&gt; loop, when we don&amp;rsquo;t have &lt;code&gt;break&lt;/code&gt;.
And in Clojure we don&amp;rsquo;t have to declare a variable outside the loop, since &lt;code&gt;loop&lt;/code&gt; does it for us, but the biggest difference is here:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 100)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;some-foo&lt;/span&gt;) 1000))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;inc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice, that we&amp;rsquo;re looping until &lt;code&gt;i&lt;/code&gt; reaches &lt;code&gt;100&lt;/code&gt;, &lt;strong&gt;or&lt;/strong&gt; until &lt;code&gt;some-foo&lt;/code&gt; returns something greater than 1000.
We can easily express this as &lt;code&gt;for&lt;/code&gt; loop in Lua:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;for&lt;/span&gt; i = 0, 100 &lt;span style=&#34;font-weight:bold&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt; some_foo() &amp;gt; 1000 &lt;span style=&#34;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, we can&amp;rsquo;t do the same in Fennel, because there&amp;rsquo;s no &lt;code&gt;break&lt;/code&gt;.
In this case we could define &lt;code&gt;i&lt;/code&gt; var, put &lt;code&gt;some_foo() &amp;lt; 1000&lt;/code&gt; to the &lt;code&gt;while&lt;/code&gt; loop test, and then use break when &lt;code&gt;i&lt;/code&gt; reaches &lt;code&gt;100&lt;/code&gt;, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 100)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;some-foo&lt;/span&gt;) 1000))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is almost like the Clojure example, and you may wonder why I complain, but in the case of &lt;code&gt;march-ray&lt;/code&gt; function, we can&amp;rsquo;t do this either!
Because the function we call returns multiple values, we need to destructure ➍ to be able to test those.
Or in some loops, such a function may depend on the context of the loop, so it has to be inside the loop, not in the test.&lt;/p&gt;
&lt;p&gt;So not having &lt;code&gt;break&lt;/code&gt;, or the ability to control when to go to the next iteration is a serious disadvantage.
Yes, Clojure&amp;rsquo;s &lt;code&gt;recur&lt;/code&gt; is also limited, since it must be in the tail position, so you can&amp;rsquo;t use it as &lt;code&gt;continue&lt;/code&gt; or something like that.
But it&amp;rsquo;s still a bit more powerful construct.
I&amp;rsquo;ve actually thought about writing a &lt;code&gt;loop&lt;/code&gt; macro, but it seems that it&amp;rsquo;s not as easy to do in Fennel, as in Clojure, because Fennel lacks some inbuilt functions to manipulate sequences.
I mean it&amp;rsquo;s totally doable, but requires way too much work compared to defining a Boolean &lt;code&gt;var&lt;/code&gt; and setting it in the loop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class=&#34;org-target&#34; id=&#34;org-target--end-of-break-rant&#34;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At ➍ we see the syntax that I didn&amp;rsquo;t cover before: &lt;code&gt;(let [(a b) (foo)] ...)&lt;/code&gt;.
Many of us, who are familiar with Lisp and especially Racket may be confused.
You see, in Racket, and other Scheme implementations (that allow using different kinds of parentheses) &lt;code&gt;let&lt;/code&gt; has this kind of syntax:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-racket&#34; data-lang=&#34;racket&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let&lt;/span&gt; [(a 1)   &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; In Scheme square brackets around bindings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (b 41)] &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; are replaced with parentheses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+&lt;/span&gt; a b))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or more generally, &lt;code&gt;(let ((name1 value1) (name2 value2) ...) body)&lt;/code&gt;.
However, in the case of the &lt;code&gt;march-ray&lt;/code&gt; function, we see a similar form, except the second element has no value specified.
This is again a valid syntax in some lisps (Common Lisp, for example), as we can make a binding that holds &lt;em&gt;nothing&lt;/em&gt; and later &lt;code&gt;set&lt;/code&gt; it, but this is not what happens in this code, as we don&amp;rsquo;t use &lt;code&gt;foo&lt;/code&gt; at all:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;foo&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, since in Fennel we don&amp;rsquo;t need parentheses, and simply specify bindings as a vector &lt;code&gt;[name1 value1 name2 value2 ...]&lt;/code&gt;, another possible confusion may happen.
You may think that &lt;code&gt;(a b)&lt;/code&gt; is a function call that returns a &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;(foo)&lt;/code&gt; is a function call that produces a &lt;code&gt;value&lt;/code&gt;.
But then we &lt;strong&gt;somehow&lt;/strong&gt; use &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;.
What is happening here?&lt;/p&gt;
&lt;p&gt;But this is just another kind of destructuring available in Fennel.&lt;/p&gt;
&lt;p&gt;Lua has 1 universal data type, called a table.
However Lua doesn&amp;rsquo;t have any special syntax for destructuring, so when a function needs to return several values, you have two options.
First, you can return a table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns_table&lt;/span&gt;(a, b)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; {a, b}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But the user of such function will have to get values out of the table themselves:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; res = returns_table(1, 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; a, b = unpack(res) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- or use indexes, e.g. local a = res[1]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a: &amp;#34;&lt;/span&gt; .. a .. &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, b: &amp;#34;&lt;/span&gt; .. b)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- a: 1, b: 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But this is extra work, and it ties values together into a data structure, which may not be really good for you.
So Lua has a shorthand for this - you can return multiple values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns_values&lt;/span&gt;(a, b)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;font-weight:bold&#34;&gt;return&lt;/span&gt; a, b
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; a, b = returns_values(1, 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a: &amp;#34;&lt;/span&gt; .. a .. &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, b: &amp;#34;&lt;/span&gt; .. b)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;-- a: 1, b: 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is shorter and more concise.
Fennel also support this multivalue return with &lt;code&gt;values&lt;/code&gt; special form:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns-values&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;values&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is equivalent to the previous code, but how do we use these values?
All binding forms in Fennel support destructuring, so we can write this as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns-values&lt;/span&gt; 1 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, b: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; a: 1, b: 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Same can be done with vectors or maps when defining, &lt;code&gt;local&lt;/code&gt;, &lt;code&gt;var&lt;/code&gt;, or &lt;code&gt;global&lt;/code&gt; variables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns-vector&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; returns [1 2 3]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns-map&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; returns {:x 1 :y 2 :z 3}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;global&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bar&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;baz&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;returns-values&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; returns (values 1 2)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And all of this works in &lt;code&gt;let&lt;/code&gt; or when defining a function!&lt;/p&gt;
&lt;p&gt;OK.
We&amp;rsquo;ve defined a function that marches a ray, now we need to shoot some!&lt;/p&gt;
&lt;h2 id=&#34;shooting-rays&#34;&gt;Shooting rays&lt;/h2&gt;
&lt;p&gt;As with math functions, let&amp;rsquo;s define some local definitions somewhere at the top of the file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-points&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.graphics.points&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-dimensions&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.graphics.getDimensions&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.graphics.setColor&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.keyboard.isDown&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-get-joysticks&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.joystick.getJoysticks&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is pretty much all we&amp;rsquo;ll need from LÖVE - two functions to draw colored pixels, one function to get the resolution of the window, and input handling functions for the keyboard and gamepad.
We&amp;rsquo;ll also define some functions in &lt;code&gt;love&lt;/code&gt; &lt;em&gt;namespace table&lt;/em&gt; (IDK how it is called properly in Lua, because it is a table that acts like a namespace) - &lt;code&gt;love.load&lt;/code&gt;, &lt;code&gt;love.draw&lt;/code&gt;, and others along the way.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s begin by initializing our window:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-width&lt;/span&gt; 512)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-height&lt;/span&gt; 448)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-flags&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:resizable&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:vsync&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:minwidth&lt;/span&gt; 256 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:minheight&lt;/span&gt; 224})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.load&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.window.setTitle&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;LÖVE Raymarching&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.window.setMode&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;window-flags&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will set our window&amp;rsquo;s default width and height to &lt;code&gt;512&lt;/code&gt; by &lt;code&gt;448&lt;/code&gt; pixels and set the minimum width and height to &lt;code&gt;256&lt;/code&gt; by &lt;code&gt;224&lt;/code&gt; pixels respectively.
We also add title &lt;code&gt;&amp;quot;LÖVE Raymarching&amp;quot;&lt;/code&gt; to our window, but it is fully optional.&lt;/p&gt;
&lt;p&gt;Now we can set &lt;code&gt;love.draw&lt;/code&gt; function, which will shoot 1 ray per pixel, and draw that pixel with the appropriate color.
However, we need a way of saying in which direction we want to shoot our ray.
To define the direction we will first need a projection plane and a look-at point.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create a look-at point as a simple zero vector &lt;code&gt;[0 0 0]&lt;/code&gt; for now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lookat&lt;/span&gt; [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we need to understand how we define our projection plane.
In our case, a projection plane is a plane that is our screen, and our camera is some distance away from the screen.
We also want to be able to change our field of view, or FOV for short, so we need a way of computing the distance to projection, since the closer we are to the projection plane, the wider our field of view:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/distances-to-projection-plane.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can easily compute the distance if we have an angle, which we also can define as a &lt;code&gt;var&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 60)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can compute our projection distance (PD), by using this formula:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_32b13e61133b5f79cc4ee40a35afa13e72a8e735.svg&#34; alt=&#34;\[PD=\frac{1}{\tan{(fov/2)}}\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;Where &lt;code&gt;fov&lt;/code&gt; is in Radians.
And to compute radians we&amp;rsquo;ll need this constant:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;RAD&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.pi&lt;/span&gt; 180.0))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can transform any angle into radians by multiplying it by this value.&lt;/p&gt;
&lt;p&gt;At this point, we know what is the distance to our projection plane, but we don&amp;rsquo;t know its size and position.
First, we need a ray origin (&lt;code&gt;RO&lt;/code&gt;), and we already have it as our camera, so our &lt;code&gt;ro&lt;/code&gt; will be equal to the current value of &lt;code&gt;camera.pos&lt;/code&gt;.
Next, we need a look-at point, and we have it as a &lt;code&gt;lookat&lt;/code&gt; variable, which is set to &lt;code&gt;[0 0 0]&lt;/code&gt;.
Now we can define a direction vector, that will specify our &lt;em&gt;forward direction&lt;/em&gt;:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_ff94fdb25712c79044bfb62102c21558e710b0cc.svg&#34; alt=&#34;\[\overrightarrow{F}=normalize(\overrightarrow{lookat}-\overrightarrow{ro})\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;And with this vector &lt;code&gt;F&lt;/code&gt; if we move our point the distance that we&amp;rsquo;ve computed previously, we&amp;rsquo;ll navigate the center of our projection plane, which we can call &lt;code&gt;C&lt;/code&gt;:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_c12545f0f21b7028183e58e928fa64ce358535e6.svg&#34; alt=&#34;\[\overrightarrow{C}=\overrightarrow{RO}+\overrightarrow{F}\cdot{PD}\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;The last thing we need to know, in order to get our orientation in space, is where is &lt;em&gt;up&lt;/em&gt; and &lt;em&gt;right&lt;/em&gt;.
We can compute this by specifying an upward vector and taking a cross product of it and our forward vector, thus producing a vector that is perpendicular to both of these vectors, and pointing to the right.
To do this we need an up vector, which we define like this &lt;code&gt;[0 0 -1]&lt;/code&gt;.
You may wonder why it is defined with the z-axis negative, but this is done so positive z values actually go up as we look from the camera, and the right is to the right.
We then compute the right vector as follows:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_bb975b5a9462d9d4d29cb464c294a9c493a095d2.svg&#34; alt=&#34;\[\overrightarrow{R}=normalize(cross(\overrightarrow{F},\begin{bmatrix}0&amp;amp;amp;0&amp;amp;amp;-1\end{bmatrix}))\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;And the up vector &lt;code&gt;U&lt;/code&gt; is a cross product of &lt;code&gt;R&lt;/code&gt; and &lt;code&gt;F&lt;/code&gt;. Let&amp;rsquo;s write this down as in &lt;code&gt;love.draw&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.draw&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-dimensions&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;1 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tan&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;RAD&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lookat&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cross&lt;/span&gt; [0 0 -1] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;u&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cross&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; TBD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Currently, we only compute these values but do not use those, hence the &lt;code&gt;nil&lt;/code&gt; at the end of the &lt;code&gt;let&lt;/code&gt;.
But now, as we know where our projection plane is, and where our right and up are, we can compute the intersection point, where at given &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates of a plane in unit vector coordinates, thus defining a direction vector.&lt;/p&gt;
&lt;p&gt;So, &lt;code&gt;for&lt;/code&gt; each &lt;code&gt;x&lt;/code&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;width&lt;/code&gt; and each &lt;code&gt;y&lt;/code&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;height&lt;/code&gt; we will compute a &lt;code&gt;uv-x&lt;/code&gt; and &lt;code&gt;uv-y&lt;/code&gt; coordinates, and find the direction vector &lt;code&gt;rd&lt;/code&gt;.
To find the &lt;code&gt;uv-x&lt;/code&gt; we need to make sure it is between &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; by dividing current &lt;code&gt;x&lt;/code&gt; by &lt;code&gt;width&lt;/code&gt; and subtracting &lt;code&gt;0.5&lt;/code&gt; from it, then multiplying by &lt;code&gt;x/width&lt;/code&gt;.
For &lt;code&gt;uv-y&lt;/code&gt; we only need to divide current &lt;code&gt;y&lt;/code&gt; by height, and subtract &lt;code&gt;0.5&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;) 0.5) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;) 0.5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; TBD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now as we have &lt;code&gt;uv-x&lt;/code&gt; and &lt;code&gt;uv-y&lt;/code&gt;, we can compute intersection point &lt;code&gt;i&lt;/code&gt;, by using the up and right vectors and the center of the plane:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_a69b83ebed3bcf5eca644e7d65e9b0d62504bb41.svg&#34; alt=&#34;\[\overrightarrow{I}=\overrightarrow{C}\cdot(\overrightarrow{R}\cdot{X_{UV}}+\overrightarrow{U}\cdot{Y_{UV}})\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;And finally, compute our direction vector &lt;code&gt;RD&lt;/code&gt;:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_e500d651acc2ee6f01323734028400ea32660648.svg&#34; alt=&#34;\[\overrightarrow{RD}=normalize(\overrightarrow{I}-\overrightarrow{RO})\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;And now we can use our &lt;code&gt;march-ray&lt;/code&gt; procedure to compute the distance and color of the pixel.
Let&amp;rsquo;s wrap everything up:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tan&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.tan&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.draw&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;1 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;tan&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;RAD&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lookat&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cross&lt;/span&gt; [0 0 -1] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;u&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cross&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-dimensions&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;) 0.5) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;) 0.5)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;u&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;uv-y&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;march-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; 0 0 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-points&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, if we set the &lt;code&gt;scene&lt;/code&gt; to contain a default &lt;code&gt;sphere&lt;/code&gt;, and place our camera at &lt;code&gt;[20 0 0]&lt;/code&gt;, we should see this:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/results-so-far.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;This is correct because our default sphere has white as the default color.&lt;/p&gt;
&lt;p&gt;You can notice, that we compute &lt;code&gt;distance&lt;/code&gt; and &lt;code&gt;color&lt;/code&gt; by calling &lt;code&gt;(march-ray ro rd scene)&lt;/code&gt;, and then check if &lt;code&gt;distance&lt;/code&gt; is less than &lt;code&gt;DRAW-DISTANCE&lt;/code&gt;.
If this is the case, we set the pixel&amp;rsquo;s color to the &lt;code&gt;color&lt;/code&gt; found by &lt;code&gt;march-ray&lt;/code&gt; function, otherwise, we set it to black.
Lastly, we draw the pixel to the screen and repeat the whole process for the next intersection point, thus the next pixel.&lt;/p&gt;
&lt;p&gt;But we don&amp;rsquo;t have to draw black pixels if we didn&amp;rsquo;t hit anything!
Remember, that in the beginning, I&amp;rsquo;ve written, that if we go past the object, we do many steps, and we can use this data to render glow.
So if we modify &lt;code&gt;love.draw&lt;/code&gt; function a bit, we will be able to see the glow around our sphere.
And the closer the gay got to the sphere, the stronger the glow will be:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[ &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;march-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;steps&lt;/span&gt; 100))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-points&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, I&amp;rsquo;m setting the color to the number of steps divided by &lt;code&gt;100&lt;/code&gt;, which results in this glow effect:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/glow.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Similarly to this glow effect, we can create a fake ambient occlusion - the more steps we did before hitting the surface, the more complex it is, hence less ambient light should be able to pass.
Unfortunately, the only object we have at this moment is a sphere, so there&amp;rsquo;s no way of showing this trick on it, as its surface isn&amp;rsquo;t very complex.&lt;/p&gt;
&lt;p&gt;All this may seem expensive, and it actually is.
Unfortunately, Lua doesn&amp;rsquo;t have real multithreading to speed this up, and the &lt;a href=&#34;https://love2d.org/wiki/love.thread&#34; target=&#34;_blank&#34;&gt;threads&lt;/a&gt; feature, provided by LÖVE results in even worse performance than computing everything in a single thread.
Well, at least the way I&amp;rsquo;ve tried it.
There&amp;rsquo;s a &lt;a href=&#34;https://love2d.org/wiki/Shader&#34; target=&#34;_blank&#34;&gt;shader DSL&lt;/a&gt; in LÖVE, which could be used to compute this stuff on GPU, but this is currently out of the scope of this project, as I wanted to implement this in Fennel.&lt;/p&gt;
&lt;p&gt;Speaking of shaders, now, that we can draw pixels on the screen, we also can shade those, and compute lighting and reflections!&lt;/p&gt;
&lt;h2 id=&#34;lighting-and-reflections&#34;&gt;Lighting and reflections&lt;/h2&gt;
&lt;p&gt;Before we begin implementing lighting, let&amp;rsquo;s add two more objects - a ground plane, and an arbitrary box.
Much like a sphere object, we first define the signed distance function, and then the constructor for the object:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;abs&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.abs&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-distance&lt;/span&gt; [{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-z&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dimensions&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-side&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y-side&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-side&lt;/span&gt;]}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sqrt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;max &lt;/span&gt;0 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-side&lt;/span&gt; 2))) 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;max &lt;/span&gt;0 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y-side&lt;/span&gt; 2))) 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (^ (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;max &lt;/span&gt;0 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-side&lt;/span&gt; 2))) 2))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sides&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; [0 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-side&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y-side&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-side&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sides&lt;/span&gt; [10 10 10])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; [1 1 1])]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dimensions&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-side&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y-side&lt;/span&gt; 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-side&lt;/span&gt; 10)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; 0)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 0)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:sdf&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box-distance&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ground-plane&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; [1 1 1])]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt; 0) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b&lt;/span&gt; 0)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:sdf&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plane&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;plane.z&lt;/span&gt;))}))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In case of &lt;code&gt;ground-plane&lt;/code&gt; we incorporate &lt;code&gt;:sdf&lt;/code&gt; as a anonymous function, because it is a simple one-liner.&lt;/p&gt;
&lt;p&gt;Now, as we have more objects, let&amp;rsquo;s add those to the scene and see if those work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [20.0 50.0 0.0]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x-rotate&lt;/span&gt; 0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z-rotate&lt;/span&gt; 0.0})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; [-6 0 0] [1 0 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt; [6 0 0] [0 1 0])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ground-plane&lt;/span&gt; -10 [0 0 1])])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this &lt;code&gt;scene&lt;/code&gt; and &lt;code&gt;camera&lt;/code&gt; we should see this:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/more-objects.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;It&amp;rsquo;s a bit sadistic in the eyes, but we can at least be sure that everything works correctly.
Now we can implement lighting.&lt;/p&gt;
&lt;p&gt;In order to calculate lighting, we&amp;rsquo;ll need to know a normal to the surface at the point.
Let&amp;rsquo;s create &lt;code&gt;get-normal&lt;/code&gt; function, that receives the &lt;code&gt;point&lt;/code&gt;, and our &lt;code&gt;scene&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-normal&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;py&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pz&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MARCH-DELTA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;py&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pz&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dx&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;py&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pz&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dy&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;px&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;py&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pz&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dz&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance-estimator&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;py&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pz&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dx&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dy&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dz&lt;/span&gt;)])))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is a nice trick, since we create three more points around our original point, use the existing distance estimation function, and get a normalized vector of subtraction of each axis from the original point, with the distance to the new point.
Let&amp;rsquo;s use this function to get normal for each point, and use the normal as our color:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-normal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; 0 0 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that in order to get endpoint of our ray we &lt;code&gt;move-point&lt;/code&gt; &lt;code&gt;ro&lt;/code&gt; along the direction &lt;code&gt;rd&lt;/code&gt; using the computed &lt;code&gt;distance&lt;/code&gt;.
We then pass the resulting point into &lt;code&gt;get-normal&lt;/code&gt;, and our &lt;code&gt;scene&lt;/code&gt;, thus computing the normal vector, which we then pass to &lt;code&gt;love-set-color&lt;/code&gt;, and it gives us this result:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/colored-normals.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;You can see that the &lt;code&gt;ground-plane&lt;/code&gt; remained blue, and this isn&amp;rsquo;t an error.
Blue in our case is &lt;code&gt;[0 0 1]&lt;/code&gt;, and since in our world, positive &lt;code&gt;z&lt;/code&gt; coordinates indicate &lt;em&gt;up&lt;/em&gt;, we can see it directly in the resulting color of the plane.
The top of the cube and the sphere are also blue, and the front side is green, which means that our normals are correct.&lt;/p&gt;
&lt;p&gt;Now we can compute basic lighting.
For that we&amp;rsquo;ll need a light object:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt; [70 40 100])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s create a &lt;code&gt;shade-point&lt;/code&gt; function, that will accept a &lt;code&gt;point&lt;/code&gt;, point &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;light&lt;/code&gt; position, and a &lt;code&gt;scene&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shade-point&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point-lightness&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It may seem that this function&amp;rsquo;s only purpose is to call &lt;code&gt;point-lightness&lt;/code&gt;, which we will define a bit later, and return a new color.
And this is true, at least for now.
Let&amp;rsquo;s create &lt;code&gt;point-lightness&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clamp&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;above-surface-point&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;normal&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;normal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;MARCH-DELTA&lt;/span&gt; 2)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point-lightness&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;normal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-normal&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light-vec&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;march-ray&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;above-surface-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;normal&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light-vec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lightness&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clamp&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dot&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;normal&lt;/span&gt;) 0 1)] &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lightness&lt;/span&gt; 0.5)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lightness&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What this function does, is simple.
We compute the &lt;code&gt;normal&lt;/code&gt; ➊ for given &lt;code&gt;point&lt;/code&gt;, then we find a point that is just above the surface, using &lt;code&gt;above-surface-point&lt;/code&gt; function ➋.
And we use this point as our new ray origin to march towards the &lt;code&gt;light&lt;/code&gt;.
We then get the &lt;code&gt;distance&lt;/code&gt; from the &lt;code&gt;march-ray&lt;/code&gt; function and check if we&amp;rsquo;ve gone all the way to the max distance or not.
If not, this means that there was a hit, and we divide total &lt;code&gt;lightness&lt;/code&gt; by 2 thus creating a shadow.
In the other case, we return &lt;code&gt;lightness&lt;/code&gt; as is.
And &lt;code&gt;lightness&lt;/code&gt; is a dot product between &lt;code&gt;light-vec&lt;/code&gt; and &lt;code&gt;normal&lt;/code&gt; to the surface ➌, where &lt;code&gt;light-vec&lt;/code&gt; is a normalized vector from the &lt;code&gt;point&lt;/code&gt; to the &lt;code&gt;light&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we again modify our &lt;code&gt;love.draw&lt;/code&gt; function like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shade-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; 0 0 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We should see the shadows:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/shadows.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;This already looks like real 3D, and it is.
But we can do a bit more, so let&amp;rsquo;s add reflections.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create a &lt;code&gt;reflection-color&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reflection-count&lt;/span&gt; 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reflection-color&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; 0 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-normal&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)]) &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reflection-count&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dot&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;) [2 2 2])) &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-color&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;march-ray&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;above-surface-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;)] &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;get-normal&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➍&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g0&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b0&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new-color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point-lightness&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;) 2)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r0&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt;)) 0.66)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g0&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt;)) 0.66)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b0&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l&lt;/span&gt;)) 0.66)]) &lt;span style=&#34;&#34;&gt;➎&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;not-done?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;) &lt;span style=&#34;&#34;&gt;➏&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;i&lt;/span&gt; 1)) &lt;span style=&#34;&#34;&gt;➐&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is quite a big function, so let&amp;rsquo;s look at it piece by piece.&lt;/p&gt;
&lt;p&gt;First, we use destructuring to define several &lt;code&gt;vars&lt;/code&gt; ➊, which we will be able to change using &lt;code&gt;set&lt;/code&gt; later in the function.
Next, we go into the &lt;code&gt;while&lt;/code&gt; loop, which checks both for maximum reflections reached, and if the ray went to infinity.
The first thing we do in the loop, computes the reflection vector &lt;code&gt;r&lt;/code&gt; ➋, by using this formula:&lt;/p&gt;
&lt;img src=&#34;https://andreyor.st/ltximg/2020-10-15-raymarching-with-fennel-and-love_dc97ecd084b47c4884333ad30190962c2093b2a7.svg&#34; alt=&#34;\[\overrightarrow{R}=\overrightarrow{D}-\overrightarrow{N}\cdot{dotproduct}(\overrightarrow{D},\overrightarrow{N})\cdot{2}\]&#34; class=&#34;org-svg&#34; /&gt;
&lt;p&gt;This is our new direction, which we will march from new &lt;code&gt;above-surface-point&lt;/code&gt; ➌.
If we&amp;rsquo;ve hit something, and our &lt;code&gt;distance&lt;/code&gt; will be less than &lt;code&gt;DRAW-DISTANCE&lt;/code&gt;, we&amp;rsquo;ll &lt;code&gt;set&lt;/code&gt; our point &lt;code&gt;p&lt;/code&gt; to new point, compute new normal &lt;code&gt;n&lt;/code&gt;, and set direction &lt;code&gt;d&lt;/code&gt; to previous direction, which was reflection vector &lt;code&gt;r&lt;/code&gt; ➍.
Next, we compute the resulting color.
I&amp;rsquo;m doing a simple color addition here, which is not an entirely correct way of doing it, but for now, I&amp;rsquo;m fine with that.
We also compute &lt;code&gt;lightness&lt;/code&gt; of the reflection point, and divide it by &lt;code&gt;2&lt;/code&gt;, so our reflections appear slightly darker.
Then we add each channel and make sure it is not greater than &lt;code&gt;1&lt;/code&gt;, by multiplying it by &lt;code&gt;0.66&lt;/code&gt; ➎.
The trick here is that maximum &lt;code&gt;lightness&lt;/code&gt; we can get is &lt;code&gt;0.5&lt;/code&gt;, so if we add two values, one of which is multiplied by &lt;code&gt;0.5&lt;/code&gt; overall result can be averaged by multiplying by &lt;code&gt;0.66&lt;/code&gt;.
This way we do not lose brightness all the way and the reflection color blends with the original color nicely.&lt;/p&gt;
&lt;p&gt;In case we don&amp;rsquo;t hit anything, it means that this is the final reflection, therefore we can end ➏ the &lt;code&gt;while&lt;/code&gt; loop on this iteration.
Lastly, since I&amp;rsquo;ve &lt;a href=&#34;#org-target--break-rant&#34;&gt;already ranted&lt;/a&gt; on the absence of &lt;code&gt;break&lt;/code&gt; in Fennel, we have to increase the loop counter manually ➐ at the end of the loop.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s change &lt;code&gt;shade-point&lt;/code&gt; so it will pass color into this function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shade-point&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-mul&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point-lightness&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reflection-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;direction&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can notice that I&amp;rsquo;ve added the &lt;code&gt;direction&lt;/code&gt; parameter, as we need it for computing reflections, so we also have to change the call to &lt;code&gt;shade-point&lt;/code&gt; in &lt;code&gt;love.draw&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;DRAW-DISTANCE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ro&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shade-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rd&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;light&lt;/span&gt;))) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rd is our initial direction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-set-color&lt;/span&gt; 0 0 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s try this out (I&amp;rsquo;ve brought &lt;code&gt;ground-plane&lt;/code&gt; a bit closer to objects so we could better see reflections):&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/reflections.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can see reflections, and reflections of reflections in reflections, because previously we&amp;rsquo;ve set &lt;code&gt;reflection-count&lt;/code&gt; to &lt;code&gt;3&lt;/code&gt;.
Currently, our reflections are pure mirrors, as we reflect everything at a perfect angle, and shapes appear just as real objects.
This can be changed by introducing materials, that have different qualities like roughness, and by using better reflection algorithms like &lt;a href=&#34;https://en.wikipedia.org/wiki/Phong_reflection_model&#34; target=&#34;_blank&#34;&gt;Phong shading&lt;/a&gt;, but maybe next time.
Refractions also kinda need materials, as refraction angles can be different, depending on what kind of material it goes through.
E.g. glass and still pool of water should have different refraction angles.
And some surfaces should reflect rays at certain angles, and let them go through at other angles, which will also require certain modifications in the reflection algorithm.&lt;/p&gt;
&lt;p&gt;Now, if we would set our &lt;code&gt;camera&lt;/code&gt;, &lt;code&gt;lookat&lt;/code&gt;, and &lt;code&gt;light&lt;/code&gt; to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lookat&lt;/span&gt; [19.75 49 19.74])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [20 50 20]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x-rotate&lt;/span&gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z-rotate&lt;/span&gt; 0})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;scene&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box&lt;/span&gt; [5 5 5] [-2.7 -2 2.5] [0.79 0.69 0.59])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box&lt;/span&gt; [5 5 5] [2.7 2 2.5] [0.75 0.08 0.66])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;box&lt;/span&gt; [5 5 5] [0 0 7.5] [0.33 0.73 0.42])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 2.5 [-2.7 2.5 2.5] [0.56 0.11 0.05])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sphere&lt;/span&gt; 10 [6 -20 10] [0.97 0.71 0.17])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ground-plane&lt;/span&gt; 0 [0.97 0.27 0.35])])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We would see an image from the beginning of this post:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-10-15-raymarching-with-lua-and-love/end-result.png&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;For now, I&amp;rsquo;m pretty happy with the current result, so lastly let&amp;rsquo;s make it possible to move into our 3D space.&lt;/p&gt;
&lt;h2 id=&#34;user-input&#34;&gt;User input&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll be doing two different ways of moving in our scene - with keyboard and gamepad.
The difference mostly is in the fact, that gamepads can give us floating point values, so we can move slower or faster depending on how we move the analogs.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already specified needed functions from LÖVE as our locals, but to recap, we&amp;rsquo;ll need only two:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.keyboard.isDown&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-get-joysticks&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.joystick.getJoysticks&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But first, we&amp;rsquo;ll need to make changes to our &lt;code&gt;camera&lt;/code&gt;, as currently, it can only look at the origin.&lt;/p&gt;
&lt;p&gt;How will we compute the look-at point for our camera so we will be able to move it around in a meaningful way?
I&amp;rsquo;ve decided that a good way will be to &amp;ldquo;move&amp;rdquo; the camera forward a certain amount, and then rotate this point around the camera by using some angles.
Luckily for us, we&amp;rsquo;ve already specified that our &lt;code&gt;camera&lt;/code&gt; has two angles &lt;code&gt;:x-rotate&lt;/code&gt;, and &lt;code&gt;z-rotate&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:pos&lt;/span&gt; [20 50 20]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x-rotate&lt;/span&gt; 255
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:z-rotate&lt;/span&gt; 15})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And it is also declared as a &lt;code&gt;var&lt;/code&gt;, which means that we can &lt;code&gt;set&lt;/code&gt; new values into it.
Let&amp;rsquo;s write a function that will compute a new &lt;code&gt;lookat&lt;/code&gt; point for current &lt;code&gt;camera&lt;/code&gt; position and rotation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.cos&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;local&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;math.sin&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rotate-point&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;az&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-angle&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;az&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-angle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;RAD&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-angle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;RAD&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-x&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-angle&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-x&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x-angle&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-z&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-angle&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-z&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-angle&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-x&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;sin-z&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cos-z&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;az&lt;/span&gt;)]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;forward-vec&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rotate-point&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; [1 0 0]) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.x-rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first function &lt;code&gt;rotate-point&lt;/code&gt; will rotate one point around another point by using two degrees.
It is based on &lt;a href=&#34;https://en.wikipedia.org/wiki/Aircraft_principal_axes&#34; target=&#34;_blank&#34;&gt;aircraft principal axes&lt;/a&gt;, but we only have two axes, so we do not need to &amp;ldquo;roll&amp;rdquo;, hence we do little fewer computations here.&lt;/p&gt;
&lt;p&gt;Next is the &lt;code&gt;forward-vec&lt;/code&gt; function, that computes current &amp;ldquo;forward&amp;rdquo; vector for &lt;code&gt;camera&lt;/code&gt;.
Forward, in this case, means the direction camera is &amp;ldquo;facing&amp;rdquo;, which is based on two angles we specify in the &lt;code&gt;camera&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With this function we can implement basic movement and rotation functions for the camera:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-forward&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;norm&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-sub&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;forward-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-elevate&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;vec-add&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.pos&lt;/span&gt; [0 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;])))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.x-rotate&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.x-rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;) 360)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-z&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clamp&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z&lt;/span&gt;) -89.9 89.9)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-strafe&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; 90)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; -90)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera.z-rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;z-rotate&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And if we modify our &lt;code&gt;love.draw&lt;/code&gt; again, we&amp;rsquo;ll be able to use our computed look-at point as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.draw&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lookat&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;forward-vec&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; rest of love.draw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we don&amp;rsquo;t need a global &lt;code&gt;lookat&lt;/code&gt; variable, and it is actually enough for us to compute new &lt;code&gt;lookat&lt;/code&gt; every frame.&lt;/p&gt;
&lt;p&gt;As for movement, let&amp;rsquo;s implement a simple keyboard handler:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle-keyboard-input&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;w&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-forward&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;s&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-forward&lt;/span&gt; -1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lshift&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-strafe&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lshift&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-strafe&lt;/span&gt; -1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; -1)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;q&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-z&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;e&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-z&lt;/span&gt; -1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;r&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-elevate&lt;/span&gt; 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love-key-pressed?&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;f&amp;#34;&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-elevate&lt;/span&gt; -1)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Similarly, we can implement controller support:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle-controller&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-x&lt;/span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;leftx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-y&lt;/span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;lefty&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;triggerleft&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-x&lt;/span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rightx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-y&lt;/span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;righty&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r2&lt;/span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:getGamepadAxis&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;triggerright&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-y&lt;/span&gt; -0.2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-y&lt;/span&gt; 0.2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-forward&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;2 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-y&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-x&lt;/span&gt; -0.2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-x&lt;/span&gt; 0.2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-strafe&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;2 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;lstick-x&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-x&lt;/span&gt; -0.2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-x&lt;/span&gt; 0.2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;4 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-x&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-y&lt;/span&gt; -0.2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-y&lt;/span&gt; 0.2)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-rotate-z&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;4 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rstick-y&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r2&lt;/span&gt; -0.8))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-elevate&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;r2&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt; -0.8))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera-elevate&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;1 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt;)))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Only for a controller, we make sure that our &lt;code&gt;l2&lt;/code&gt; and &lt;code&gt;r2&lt;/code&gt; axes are from 0 to 2, since by default these axes are from &lt;code&gt;-1&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;, which isn&amp;rsquo;t going to work for us.
Similarly to this, we can add the ability to change the field of view or reflection count, but I&amp;rsquo;ll leave this out for those who are interested in trying it themselves.
It&amp;rsquo;s not hard.&lt;/p&gt;
&lt;p&gt;As a final piece, we need to detect if the controller was inserted and handle keys somewhere.
So let&amp;rsquo;s add these two final functions that we need for everything to work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;var &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.joystickadded&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;set &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gamepad&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;g&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;love.update&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dt&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle-keyboard-input&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;handle-controller&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;love.joystickadded&lt;/code&gt; will take care of watching for new controllers, and &lt;code&gt;love.update&lt;/code&gt; will ask for new input every now and then.&lt;/p&gt;
&lt;p&gt;By this moment we should have a working raymarching 3D renderer with basic lighting and reflections!&lt;/p&gt;
&lt;h2 id=&#34;final-thoughts&#34;&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve decided to write this post because I was interested in three topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fennel, a Lisp-like language, which is a lot like Clojure syntax-wise, and has great interop with Lua (because it IS Lua)&lt;/li&gt;
&lt;li&gt;LÖVE, is a nice game engine I&amp;rsquo;ve been watching for a long time already and played some games written with it, which were quite awesome,&lt;/li&gt;
&lt;li&gt;and Lua itself, a nice, fast scripting language, with the cool idea that everything is a table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although I didn&amp;rsquo;t use much of Lua here, I&amp;rsquo;ve actually tinkered with it a lot during the whole process, testing different things, reading Fennel&amp;rsquo;s compiler output, and benchmarking various constructs, like field access, or unpacking numeric tables versus multiple return values.
Lua has some really cool semantics of defining modules as tables and incorporating special meaning to tables via &lt;code&gt;setmetatable&lt;/code&gt;, which is really easy to understand in my opinion.&lt;/p&gt;
&lt;p&gt;Fennel is a great choice if you don&amp;rsquo;t want to learn Lua syntax (which is small, but, you know, it &lt;em&gt;exists&lt;/em&gt;).
For me, Fennel is a great language, because I don&amp;rsquo;t have to deal with Lua syntax AND because I can write macros.
And even though I didn&amp;rsquo;t write any macro for this project, because everything is already presented in Fennel itself, the possibility of doing this is worth something.
Also, during benchmarking various features, I&amp;rsquo;ve used self-written &lt;code&gt;time&lt;/code&gt; macro:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;macro&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;time &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;body&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  `(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;os.clock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;start#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res#&lt;/span&gt; ,&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;body&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end#&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clock#&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;print &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Elapsed: &amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;1000 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end#&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;start#&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34; ms&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;res#&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So the ability to define such things is a good thing.&lt;/p&gt;
&lt;p&gt;LÖVE is a great engine, and although I&amp;rsquo;ve used a very little bit of it, I still think that this is a really cool project, because there is so much more in it.
Maybe someday I&amp;rsquo;ll make a game that will realize LÖVE&amp;rsquo;s full potential.&lt;/p&gt;
&lt;p&gt;On a downside note&amp;hellip;
The resulting raymarching is &lt;strong&gt;very slow&lt;/strong&gt;.
I&amp;rsquo;ve managed to get around 25 FPS for a single object in the scene, and a 256 by 224 pixel resolution.
Yes, this is because it runs in a single thread, and does a lot of expensive computations.
Lua itself isn&amp;rsquo;t a very fast language, and even though LÖVE uses Luajit - a just-in-time compiler that emits machine code, it&amp;rsquo;s still not fast enough for certain operations, or techniques.
For example, if we implement operator overloading for vectors we&amp;rsquo;ll lose a lot of performance for constant table lookups.
This is an existing problem in Lua, since it does its best of being small and embeddable, so it could work nearly on anything, therefore it doesn&amp;rsquo;t do a lot of caching and optimizations.&lt;/p&gt;
&lt;p&gt;But hey, this is a raymarching in ~350 lines of code with some cool tricks like destructuring!
I&amp;rsquo;m fine with the results.
A slightly more polished version of the code from this article is available at &lt;a href=&#34;https://gitlab.com/andreyorst/love-raymarching&#34; target=&#34;_blank&#34;&gt;this repository&lt;/a&gt;, so if anything doesn&amp;rsquo;t work in the code above, or you got lost and just want to play with the final result, you know where to go :)&lt;/p&gt;
&lt;p&gt;Till next time, and thanks for reading!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29&#34; target=&#34;_blank&#34;&gt;https://en.wikipedia.org/wiki/Ray_tracing_(graphics)&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ssloy/tinyraytracer&#34; target=&#34;_blank&#34;&gt;https://github.com/ssloy/tinyraytracer&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://fennel-lang.org/setup&#34; target=&#34;_blank&#34;&gt;https://fennel-lang.org/setup&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://love2d.org/wiki/Getting_Started&#34; target=&#34;_blank&#34;&gt;https://love2d.org/wiki/Getting_Started&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;there&amp;rsquo;s no need to declare a variable as &lt;code&gt;var&lt;/code&gt; if it is a table and we&amp;rsquo;re only going to change the values stored inside the table, not the table itself.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Raymarching with Fennel and LÖVE&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 15 Oct 2020 20:33:00 +0300</pubDate>
    </item><item>
      <title>Simple Ray Casting with ClojureScript</title>
      <link>https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/</link>
      <guid>https://andreyor.st/posts/2020-06-04-simple-ray-casting-with-clojurescript/</guid>
      <description>&lt;p&gt;Ray casting is quite an old technique, that was heavily used in the early days of game development in a lot of games to create an illusion of 3D space.
The most known example, and perhaps the first widely successful game that used this technique, was Wolfenstein 3D, made by ID Software in 1992.
There were a lot of other games for all kinds of platforms, that used ray casting, for example, I remember playing the labyrinth game on Siemens C35 in around 2001:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/labyrinth-game-on-siemens-c35.jpg&#34;/&gt;
&lt;/figure&gt;

&lt;center&gt;Yup, this phone is still alive, and still has this labyrinth game&lt;/center&gt;
&lt;br&gt;
&lt;p&gt;There&amp;rsquo;s probably no reason to use ray casting for rendering pseudo-3D environments today, since this technique is very limited, and modern hardware is heavily optimized for working with triangles, which allows us to create very complex geometry that is impossible to model with ray casting.
But I think that ray casting is a kinda cool idea, a simple concept, and definitively was a very smart move in the nineties game development.
Additionally, ray casting has a lot more use cases than a simple rendering engine.
Also, &lt;em&gt;raycasting&lt;/em&gt; seems not to be a real word, but I&amp;rsquo;m going to refer to this technique like that further on, because it is convenient, and the engine itself can be referred to as &lt;em&gt;raycaster&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;For this project, I&amp;rsquo;ve chosen ClojureScript because I want to get into it, and into Clojure as well.
Although my experience with Lisps is not very rich, the main usage right now is for writing functions in Emacs Lisp, but those are rather basic.
I&amp;rsquo;m also going through &lt;a href=&#34;https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html&#34; target=&#34;_blank&#34;&gt;SICP&lt;/a&gt; with GNU Guile and Racket, and though exercises in this book are sometimes brutal, this is not real programming experience.
So the real goal of this post is rather not to implement a basic raycaster, but learn some Clojure.
What, you thought we&amp;rsquo;re here for games?
Just kidding, we&amp;rsquo;ll make a simple maze game too, which will be playable on this page.&lt;/p&gt;
&lt;p&gt;But first, let&amp;rsquo;s understand what raycasting is, by going through some basic examples.&lt;/p&gt;
&lt;h2 id=&#34;ray-casting-basics&#34;&gt;Ray casting basics&lt;/h2&gt;
&lt;p&gt;The general idea behind this technique is that we can imitate a 3D environment based only on 2D information.
This is done by casting rays from the point, where the camera stands, and measuring the length of each ray until it hits any of the line segments, that represent walls on a 2D plane.
I&amp;rsquo;ve prepared some pictures to illustrate this idea:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;figure--example-stage&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/two-lines-and-a-camera.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can look at this as a top-down view of our scene.
But how would we convert it to a first-person pseudo-3D view?
The answer, &lt;em&gt;as you might expect&lt;/em&gt;, is rays.
Our camera will shoot a certain amount of rays in front of it, and we will see which rays have intersection points with our red and green walls.
Let&amp;rsquo;s shoot 6 rays:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/rays.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Now we can find intersections with our walls.
I&amp;rsquo;ve cut those rays, and calculated their lengths - this is the only information we need to make this 2D plane into a pseudo-3D scene.
Going from left to right, lengths are roughly &lt;code&gt;23.7&lt;/code&gt;, &lt;code&gt;24.2&lt;/code&gt;, &lt;code&gt;inf&lt;/code&gt;, &lt;code&gt;34.8&lt;/code&gt;, &lt;code&gt;30.3&lt;/code&gt;, &lt;code&gt;27.5&lt;/code&gt; pixels each:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/rays-intersected.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;So, in order to make a 3D scene out of these lengths we, first, have to create an empty scene.
Let&amp;rsquo;s make it &lt;code&gt;256&lt;/code&gt; by &lt;code&gt;224&lt;/code&gt; pixels.
We then divide this scene&amp;rsquo;s width by amount of rays, to compute the width of each ray, and fill this scene with rectangles of this width, which gives us roughly &lt;code&gt;42.7&lt;/code&gt; pixels wide rectangles:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/rectangles.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;This doesn&amp;rsquo;t look like 3D yet, and you can notice that there are only 5 out of the total 6 rectangles presented.
This is due to the fact that one ray had infinity length, since it did not intersect with anything, so we don&amp;rsquo;t draw anything there.
And to make it look 3D we need to change the height of each rectangle accordingly to the length of each ray.
General rule &amp;ndash; the shorter the ray, the bigger the height:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/rectangles-adjusted.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Now, this looks more like a 3D scene, isn&amp;rsquo;t it?
But the walls don&amp;rsquo;t exactly look like walls, more like a set of rectangles.
We can fix this by increasing our resolution, which we do by casting more rays.
Also, let&amp;rsquo;s add background and remove rectangle outlines:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/16-rays.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;We can also change the field of view, by keeping the same amount of rays but changing the angle between those:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/16-rays-fov.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Which is more convincing, but still not as smooth as it could be.
But, we can think about rays as our resolution, so if we would cast 256 rays, one ray for each pixel of image width, we would get something like this:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/256-rays.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;More advanced raycasting engines can produce various perspective corrections for such rectangles, making things appear at different heights.
This is often used to imitate a camera shake while walking.
Textures can be mapped to walls and the floor, and very basic lighting can be achieved by changing texture brightness depending on the distance.
Even more advanced engines allow changing the vertical angle of the camera to imitate looking up and down.
But we will implement pretty basic untextured raycasting, extending it further can be an interesting task, but I don&amp;rsquo;t feel like doing it with canvas.
Maybe later, with WebGL.&lt;/p&gt;
&lt;h2 id=&#34;project-structure&#34;&gt;Project structure&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll be using &lt;a href=&#34;https://github.com/thheller/shadow-cljs&#34; target=&#34;_blank&#34;&gt;shadow-cljs&lt;/a&gt; to manage my project.
I&amp;rsquo;ve found this one very straightforward and simple to set up with &lt;a href=&#34;https://leiningen.org/&#34; target=&#34;_blank&#34;&gt;Leiningen&lt;/a&gt;.
To create &lt;code&gt;cljs&lt;/code&gt; project via &lt;code&gt;lein&lt;/code&gt; type this in the command line (I&amp;rsquo;m using Linux, so) some details on project setup may vary for different operating systems:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ lein new shadow-cljs raycasting
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As a result, it should create the following file structure for us:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;raycasting/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── package.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── public
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── css
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   │   └── style.css
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── index.html
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── shadow-cljs.edn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── src
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── raycasting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        └── core.cljs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s look at &lt;code&gt;shadow-cljs.edn&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; shadow-cljs configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:source-paths&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dependencies&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binaryage/devtools&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.9.7&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reagent&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.8.0-alpha2&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; set a nrepl port for connection to a REPL.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:nrepl&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:port&lt;/span&gt; 8777}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:builds&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:app&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:browser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:output-dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;public/js/compiled&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:asset-path&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/js/compiled&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:modules&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:main&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:entries&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&lt;/span&gt;]}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:devtools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;; before live-reloading, any code calls this function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:before-load&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core/stop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; after live-reloading finishes call this function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:after-load&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core/start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; serve the public directory over http at port 8700&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:http-root&lt;/span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:http-port&lt;/span&gt;    8700
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:preloads&lt;/span&gt;     [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;devtools.preload&lt;/span&gt;]}}}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Probably you won&amp;rsquo;t need to change much here, but I&amp;rsquo;ve removed &lt;code&gt;reagent&lt;/code&gt; dependency, because I don&amp;rsquo;t need it, so my &lt;code&gt;shadow-cljs.edn&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:source-paths&lt;/span&gt; [&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:dependencies&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;binaryage/devtools&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0.9.7&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:nrepl&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:port&lt;/span&gt; 8777}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:builds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:app&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:target&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:browser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:output-dir&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;public/js/compiled&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:asset-path&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;/js/compiled&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:compiler-options&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:optimizations&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:advanced&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:modules&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:entries&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&lt;/span&gt;]}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:devtools&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:http-root&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;public&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:http-port&lt;/span&gt; 8700
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:preloads&lt;/span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;devtools.preload&lt;/span&gt;]}}}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve also added &lt;code&gt;:compiler-options {:optimizations :advanced}&lt;/code&gt; to produce smaller &lt;code&gt;js&lt;/code&gt; file, and removed &lt;code&gt;:before-load&lt;/code&gt; and &lt;code&gt;:after-load&lt;/code&gt; functions, because I don&amp;rsquo;t think we need those, and script initialization on page load is sufficient enough.&lt;/p&gt;
&lt;p&gt;One last thing - we need a test page to see the results of our code, so let&amp;rsquo;s create &lt;code&gt;public/index.html&lt;/code&gt; file, where we will add our canvas, and other elements as we go.&lt;/p&gt;
&lt;p&gt;With the project setup and ready we now can begin working on ray casting by creating a camera.&lt;/p&gt;
&lt;h2 id=&#34;creating-a-camera&#34;&gt;Creating a camera&lt;/h2&gt;
&lt;p&gt;Since we&amp;rsquo;re going to cast rays out from the camera, we need a camera in the first place.
Camera will be represented as a single point on the plane with &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates, and &lt;code&gt;degree&lt;/code&gt; parameter.
Let&amp;rsquo;s create a file &lt;code&gt;src/raycasting/camera.cljs&lt;/code&gt; and define camera by using &lt;code&gt;atom&lt;/code&gt; so we could later update it:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--camera.cljs&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;atom&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0.0}))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--camera.cljs&#34;&gt;Code Snippet 1&lt;/a&gt;:&lt;/span&gt;
  Contents of &lt;code&gt;src/raycasting/camera.cljs&lt;/code&gt;
&lt;/div&gt;
&lt;p&gt;Our &lt;code&gt;camera&lt;/code&gt; is a hash map with three key-value pairs for each of its parameters.
We can later access these parameters by calling keys on this map like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is quite handy, and we can update our map with &lt;code&gt;assoc&lt;/code&gt; procedure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 45.0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 45.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or use &lt;code&gt;merge-with&lt;/code&gt; procedure to change the value currently stored in the map, by using some procedure, which is &lt;code&gt;+&lt;/code&gt; in our case:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;merge-with + &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90.0})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can notice that while I&amp;rsquo;ve used &lt;code&gt;assoc&lt;/code&gt; to change my &lt;code&gt;:degree&lt;/code&gt; to &lt;code&gt;45.0&lt;/code&gt; and then used &lt;code&gt;merge-with&lt;/code&gt; with &lt;code&gt;+&lt;/code&gt; to add &lt;code&gt;90.0&lt;/code&gt; degrees to current &lt;code&gt;:degree&lt;/code&gt;, I&amp;rsquo;ve still got &lt;code&gt;90.0&lt;/code&gt; as the result, and not the expected &lt;code&gt;135.0&lt;/code&gt;.
This is because &lt;code&gt;camera&lt;/code&gt; is a &lt;em&gt;value&lt;/em&gt;, and can&amp;rsquo;t really change, and instead we&amp;rsquo;re producing a new value based on old one.
And since our old value never changed, it still had &lt;code&gt;0.0&lt;/code&gt; as &lt;code&gt;:degree&lt;/code&gt;.
To understand how this works we need to understand what is considered a value and why.
You can &lt;a href=&#34;#moving-the-camera&#34;&gt;skip&lt;/a&gt; explanations of this if you want, since it mostly has nothing to do with raycasting itself, but this still may explain certain things that we will see later in the code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In Clojure, we mostly work with values, and there are no &lt;em&gt;variables&lt;/em&gt; as presented in other languages.
To make it more clear, let&amp;rsquo;s talk about what is considered a value.
For example, in Rust &lt;code&gt;42&lt;/code&gt; is a value, that we can assign to a variable like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;mut&lt;/span&gt; a = 42;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve created a mutable variable &lt;code&gt;a&lt;/code&gt;, and put &lt;code&gt;42&lt;/code&gt; into it.
We can later &lt;em&gt;mutate&lt;/em&gt; &lt;code&gt;a&lt;/code&gt; to hold another value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a -= 15;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key here is &lt;em&gt;mutate&lt;/em&gt; - we&amp;rsquo;re not magically transforming &lt;code&gt;42&lt;/code&gt; itself into &lt;code&gt;27&lt;/code&gt;, we&amp;rsquo;re changing the contents of &lt;code&gt;a&lt;/code&gt;.
So &lt;code&gt;a&lt;/code&gt; is like a box that contains a value.
You can&amp;rsquo;t really do anything to &lt;code&gt;42&lt;/code&gt; itself &amp;ndash; it is and always will be &lt;code&gt;42&lt;/code&gt;, that&amp;rsquo;s why it is a value.
So when we did &lt;code&gt;a -= 15&lt;/code&gt;, we&amp;rsquo;ve produced a new value based on the old one, and put it into &lt;code&gt;a&lt;/code&gt;.
So values &lt;strong&gt;never change&lt;/strong&gt;, only variables that hold these values change what they are holding.&lt;/p&gt;
&lt;p&gt;As an example of something that is not a value in Rust, we can look at the Vector collection:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;mut&lt;/span&gt; b = vec![1, 2, 3];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a dynamic array, that holds three elements.
And we can actually change this array by using different methods that it provides, like &lt;code&gt;push&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;b.push(4); &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;// now collection holds these four elements [1, 2, 3, 4]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After this &lt;code&gt;push&lt;/code&gt;, whenever we refer to &lt;code&gt;b&lt;/code&gt; it will hold four elements.
We&amp;rsquo;ve declared &lt;code&gt;b&lt;/code&gt; as &lt;code&gt;mut&lt;/code&gt;, but we&amp;rsquo;re not mutating &lt;code&gt;b&lt;/code&gt; itself, but the collection that &lt;code&gt;b&lt;/code&gt; holds - and because of that this is not a value.
&lt;code&gt;mut&lt;/code&gt; keyword only specifies that we can mutate collection.
But even if we were to drop the &lt;code&gt;mut&lt;/code&gt; keyword in both examples, e.g. &lt;code&gt;let a = 42&lt;/code&gt;, &lt;code&gt;let b = vec![1, 2, 3]&lt;/code&gt;, we would not be able to mutate both of these, but it still would not turn &lt;code&gt;[1, 2, 3]&lt;/code&gt; into a value, although we can treat it as a value, underlying semantics of a collection has not changed.&lt;/p&gt;
&lt;p&gt;(Semi-)real-world example - I give you an apple, and ask you to give me back half of it.
You slice the apple and give me back one half.
This apple is not a value, because you&amp;rsquo;ve literally changed it by slicing, and now the original apple is no longer available for both of us.
You now hold half of the apple, and I hold another half.
This is what happens when you modify a vector or any other collection.&lt;/p&gt;
&lt;p&gt;Then I give you an apple made out of a material that &lt;a href=&#34;https://en.wikipedia.org/wiki/Adamantium#History_and_properties&#34; target=&#34;_blank&#34;&gt;once cast, can&amp;rsquo;t be destroyed&lt;/a&gt;, and ask you to give me half of it.
You can&amp;rsquo;t slice it, or do anything to it at all, so you take very precise measures of this apple, cast a new piece out of the same material, and give it back to me.
We now have the original apple and an apple slice.
Then you can throw this apple in the garbage because you can&amp;rsquo;t really do anything with it.
This is what essentially happens when you do math with numbers - you can&amp;rsquo;t change &lt;code&gt;42&lt;/code&gt;, you can take the measure (&lt;code&gt;15&lt;/code&gt;) and produce &lt;code&gt;27&lt;/code&gt; by subtraction.
And this is what makes such an apple to be a value.&lt;/p&gt;
&lt;p&gt;So in Clojure, we work with such type of data, and all Clojure collections are immutable.
But the other major aspect of Clojure&amp;rsquo;s collections is persistence.
The apple I&amp;rsquo;ve described isn&amp;rsquo;t really persistent, because once you&amp;rsquo;ve made a new slice, nothing really tells me what its past state was - was it a whole apple or 3/4 of an apple?
So in order to make things persistent, we must provide additional information with apple, like a serial number for example.
When you cast a new slice, you create a new serial number, that contains information about the old serial number.
This way we can look at our piece, and determine what apple was used as a reference.&lt;/p&gt;
&lt;p&gt;Now, whenever we create new copies, we encode the previous serial number into the current serial number, and from any point, we are able to trace back to the original state of the apple.&lt;/p&gt;
&lt;p&gt;You can argue, that this can be done with an ordinary apple just as with an indestructible one, but the difference is, that an ordinary apple can be changed.
Imagine that you&amp;rsquo;ve made a new apple based on it, added a serial number, that encodes that it was derived from the original apple, and then someone bit off a piece of the original apple.
Then any holder of your copy of apple will try to refer to the original one and will find out not what they expected.
Or maybe what they expected, since the apple could have been bitten before and you&amp;rsquo;ve restored the original form of an apple when made it.
There&amp;rsquo;s no way to tell and preserve correct history.
So even though we can enforce mutation restrictions in Rust, this does not make the vector into a value.&lt;/p&gt;
&lt;p&gt;This is kinda what Clojure does with its collections.
But instead of using identifiers, Clojure uses path copying for sharing structure between states.
So newer state refers to some point in the old state.
There are many different ways to maintain persistence, which are nicely described on this Wikipedia &lt;a href=&#34;https://en.wikipedia.org/wiki/Persistent_data_structure&#34; target=&#34;_blank&#34;&gt;page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A very simple example of persistent collection we can refer to is a single linked list, that grows at the front.
Let&amp;rsquo;s start with a list of these three items &lt;code&gt;(1 2 3)&lt;/code&gt;.
This can be represented as boxes that hold values, and have pointers to what should be the next value:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/single-linked-list.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;So &lt;code&gt;1&lt;/code&gt; refers to &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; refers to &lt;code&gt;3&lt;/code&gt;, and &lt;code&gt;3&lt;/code&gt; refers to nothing, which indicates end of the list.
Now we add another element to it at the front, which produces a new list &lt;code&gt;(0 1 2 3)&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/new-single-linked-list.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;You can see that all we did is created a box to hold &lt;code&gt;0&lt;/code&gt; and told it to point to a box that holds &lt;code&gt;1&lt;/code&gt;.
The rest thing is our old list, marked with green boxes, and we did not copy anything from it.
And old list did not change at all, only a new node was added to it at the front, but the old list knows nothing about it.
So if we stored our original list somewhere, and added &lt;code&gt;0&lt;/code&gt; to it, our original list was not changed.&lt;/p&gt;
&lt;p&gt;Furthermore, if we check the identity of our new list without its first element, it will be the same as in the original list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;identical? &lt;/span&gt;&amp;#39;(1 2 3) &amp;#39;(1 2 3))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; &amp;#39;(1 2 3))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;identical? &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;conj &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a&lt;/span&gt; 0)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First &lt;code&gt;identical?&lt;/code&gt; test gives us &lt;code&gt;false&lt;/code&gt; because these are two different &lt;em&gt;objects&lt;/em&gt;, even though their &lt;em&gt;values&lt;/em&gt; are the same.
The second &lt;code&gt;identical?&lt;/code&gt; test gives us &lt;code&gt;true&lt;/code&gt;, because, as I&amp;rsquo;ve said, by adding a new value to the list, and then removing it, we get back the original list.&lt;/p&gt;
&lt;p&gt;And all of the collections in Clojure work this way, with a promise of fast change and low memory cost.
Although such collections are not as fast as mutable non-persistence collections, they are much more reliable, especially when it comes to concurrent programming, and reliability is much more important than speed most of the time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But in our raycasting we will have to really change camera position, so how do we do it if collections can&amp;rsquo;t be changed, and we&amp;rsquo;re using a hash map to hold camera coordinates and angle?&lt;/p&gt;
&lt;h2 id=&#34;moving-the-camera&#34;&gt;Moving the camera&lt;/h2&gt;
&lt;p&gt;When we&amp;rsquo;ve created &lt;code&gt;camera&lt;/code&gt; we&amp;rsquo;ve used the &lt;code&gt;atom&lt;/code&gt; procedure to produce a reference type that can be later atomically swapped to hold another value, and the swapping mechanism is concurrently safe.
So, in order to update our map, all we need to do is to call &lt;code&gt;swap!&lt;/code&gt; procedure, and pass our atom and a procedure that will update the value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 45.0)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 45.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, when we dereference &lt;code&gt;camera&lt;/code&gt; with &lt;code&gt;@&lt;/code&gt;, we can actually see the updated value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&amp;gt;&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 45.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using swap with anonymous procedures is kinda tedious, so instead, let&amp;rsquo;s create a set of procedures that we will use to move the camera around:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radian&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/PI&lt;/span&gt; 180.0)) &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;radian&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;)))]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Move `camera` forward given `amount` respecting the `degree`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-point&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This procedure will move our camera &lt;em&gt;forward&lt;/em&gt; relatively to where the camera is pointed at.
We compute ➊ only once, to later convert degrees to radians by multiplication.
The &lt;code&gt;move-point&lt;/code&gt; ➋ procedure will later be used in several places of our program, so it is good to have it as a separate procedure, while &lt;code&gt;move-forward&lt;/code&gt; is used exclusively for camera movement.
And inside we have weird construction ➌ which is called &lt;a href=&#34;https://clojure.org/guides/destructuring#_associative_destructuring&#34; target=&#34;_blank&#34;&gt;Associative Destructuring&lt;/a&gt;.
We essentially bind &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;degree&lt;/code&gt; within our &lt;code&gt;let&lt;/code&gt; block, to the values contained in &lt;code&gt;camera&lt;/code&gt;.
Now let&amp;rsquo;s try to move our camera around:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0.0) 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 10, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90.0) 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 10, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 6.123233995736766&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;e-16&lt;/span&gt;, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Uh oh.
Moving forward with 0 degrees was fine, but when we&amp;rsquo;ve turned 90 degree, we&amp;rsquo;ve got &lt;code&gt;6.123233995736766e-16&lt;/code&gt; as our &lt;code&gt;y&lt;/code&gt; coordinate.
This value is very close to &lt;code&gt;0&lt;/code&gt;, but we don&amp;rsquo;t really need such precision, and there are some problems with such small values in JavaScript.
Let&amp;rsquo;s write a macro, that will truncate it to three decimal places, which would be more than enough for our needs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defmacro &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;three-decimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Truncate `double` to three decimal places.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;num&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  `(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;1000 ~&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;num&lt;/span&gt;)) 1000.0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Move `camera` forward given `amount` respecting the `degree`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/PI&lt;/span&gt; 180.0))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;merge-with + &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;))}))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will not work though.
The problem is, that we can&amp;rsquo;t just define a macro in the same file that we&amp;rsquo;ve declared procedure.
This is a &lt;a href=&#34;https://clojurescript.org/about/differences#_macros&#34; target=&#34;_blank&#34;&gt;difference&lt;/a&gt; between Clojure and ClojureScript, so we have to create new file &lt;code&gt;src/raycasting/macros.cljc&lt;/code&gt;, and use &lt;code&gt;:require-macros&lt;/code&gt; in our namespace definition for &lt;a href=&#34;#code-snippet--camera.cljs&#34;&gt;camera.cljs&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require-macros&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.macros&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can update &lt;code&gt;move-forward&lt;/code&gt; to refer to macro:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Move `camera` forward given `amount` respecting the `degree`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 1))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/PI&lt;/span&gt; 180.0))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;merge-with + &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/sin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rad&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;))}))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s try it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0.0) 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 10, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-forward&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;@&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90.0) 10)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 10, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nice.
Now, we can do the same thing to rotate the camera:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rotate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Rotate `camera` by a `degree`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 0.5))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mod&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt;) 360.0))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And if we call this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rotate&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 420)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0.0, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0.0, &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 60.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The rotate procedure ensures that our &lt;code&gt;:degree&lt;/code&gt; stays inside 360 degrees, so when we specify a turn that is more than 360 degrees, we wrap around.
These are two main procedures we will later use.&lt;/p&gt;
&lt;h2 id=&#34;drawing&#34;&gt;Drawing&lt;/h2&gt;
&lt;p&gt;Now we can draw our camera on &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.
Let&amp;rsquo;s add this to our &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;html lang=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;en-US&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;meta charset=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;script src=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;js/compiled/main.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;canvas id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;raycaster&amp;#34;&lt;/span&gt; width=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;512&amp;#34;&lt;/span&gt; height=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;224&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/canvas&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;window&lt;/span&gt;.onload = &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        raycasting.core.init();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve added our &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and gave it an &lt;code&gt;id&lt;/code&gt;.
We will later be able to refer to this canvas via this &lt;code&gt;id&lt;/code&gt;, so let&amp;rsquo;s create two vars to hold the canvas object, and its context:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;raycaster&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-getContext&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getContext&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We use &lt;code&gt;defonce&lt;/code&gt; here, so when we save file, and shadow-cljs hot reloads the code, we will not redefine our &lt;code&gt;*canvas*&lt;/code&gt; and &lt;code&gt;*ctx*&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;.
And &lt;code&gt;init&lt;/code&gt; procedure will run on &lt;code&gt;onload&lt;/code&gt; event, and set our &lt;code&gt;*canvas*&lt;/code&gt; and &lt;code&gt;*ctx*&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create &lt;code&gt;draw-camera&lt;/code&gt; procedure, that will take current &lt;code&gt;camera&lt;/code&gt; state, and draw it to canvas:&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--draw-camera&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ([[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-strokeStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.beginPath&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.moveTo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.lineTo&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.stroke&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt;] [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pointer&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) 7)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; 5]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pointer&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; 2)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; 2)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, if we write this to the REPL:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We should see our camera:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example1&#34; width=&#34;256&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Now let&amp;rsquo;s add some walls to look at.&lt;/p&gt;
&lt;h2 id=&#34;creating-walls&#34;&gt;Creating walls&lt;/h2&gt;
&lt;p&gt;I need to mention, that many raycasting engines define stages in terms of squares on the grid.
This is useful because we can check intersections a lot faster since we only need to perform checks along the ray in fixed points of space.
While this is quite fast, I want arbitrarily placed walls in my raycaster.
Because of this, our algorithm will not be as optimal, but we will be able to handle more complex wall placement.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create new file &lt;code&gt;src/raycasting/stage.cljs&lt;/code&gt;.
In this file, we will define our stages.
Each stage is a vector, with line segments, that have three components - beginning coordinate, endpoint, and color.
Let&amp;rsquo;s define stage, as on our &lt;a href=&#34;#figure--example-stage&#34;&gt;example picture&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.stage&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;example-stage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [ &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [ &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [23.468 126.290] &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [106.189 87.527] &lt;span style=&#34;&#34;&gt;➍&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#89a02c&amp;#34;&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➎&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   [[124.947 40.268] [166.507 95.415] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#916f6f&amp;#34;&lt;/span&gt;] &lt;span style=&#34;&#34;&gt;➏&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So what we&amp;rsquo;re doing here is, we begin by creating a vector ➊.
This vector will hold all lines that our stage uses.
We define another vector ➋, that will hold beginning point ➌, ending point ➍, and wall color ➎.
Lastly, we specify another line ➏, and this process can continue on and on.
Bigger stages will require a lot of walls, and this can be a performance hit, but we&amp;rsquo;re not aiming for the best efficiency.&lt;/p&gt;
&lt;p&gt;Now we can implement wall drawing with our &lt;code&gt;draw-line&lt;/code&gt; procedure, that we&amp;rsquo;ve already used in &lt;a href=&#34;#code-snippet--draw-camera&#34;&gt;&lt;code&gt;draw-camera&lt;/code&gt; procedure&lt;/a&gt;.
Let&amp;rsquo;s create &lt;code&gt;draw-stage&lt;/code&gt; procedure, that will walk through our vector of walls and draw each on the canvas:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doseq &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;line&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;doseq&lt;/code&gt; is a great way to iterate on a collection for producing side effects, such as drawing on the screen.
Let&amp;rsquo;s move our camera to the position &lt;code&gt;119.5,180&lt;/code&gt;, and rotate it to 180 so it is placed as on our example.
Now if we call this procedure, we should see our stage:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; #(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 119.5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 180 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 180))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 119.5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 180 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 180}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage/example-stage&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example2&#34; width=&#34;256&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;While we are at this, notice how awkward we&amp;rsquo;ve been setting our position for &lt;code&gt;camera&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; #(&lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 119.5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 180 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 180))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;➊ &lt;code&gt;#()&lt;/code&gt; is a shorthand for creating an anonymous procedure.
This procedure will call &lt;code&gt;assoc&lt;/code&gt; ➋, and &lt;code&gt;%&lt;/code&gt; ➌ will be our &lt;code&gt;cam/camera&lt;/code&gt;.
A more elaborate way to write the same code would be &lt;code&gt;(fn [camera] (assoc camera …))&lt;/code&gt;.
We could simplify this by using &lt;code&gt;reset!&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reset!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 119.5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 180 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 180})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which is much simpler, but still very error-prone, because we&amp;rsquo;ll have to remember what keys should be in the map.
This is not an issue for three key-value pair maps, but for huge maps, it will be better to create some kind of initialization procedure.
Let&amp;rsquo;s create one in &lt;code&gt;raycasting.camera&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set-position&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Set position of the `camera` to a certain `x`, `y`, and `degree`.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set-position&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 0 0 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set-position&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; 0))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➌&lt;/span&gt; ([&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;mod&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 360.0)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is called &lt;a href=&#34;https://clojure.org/guides/learn/functions#_multi_arity_functions&#34; target=&#34;_blank&#34;&gt;Multi-arity function&lt;/a&gt;, we&amp;rsquo;ve been using it before, but I&amp;rsquo;ve never explained what it is.
In Clojure and ClojureScript it is possible to define procedure overloading based on the number of given arguments.
In this example we create three possible ways to call our procedure: ➊ - we only pass our &lt;code&gt;camera&lt;/code&gt; parameter, and it resets its position to &lt;code&gt;0,0&lt;/code&gt; coordinates, and set&amp;rsquo;s &lt;code&gt;0&lt;/code&gt; degree angle, ➋ - we specify coordinates, but we don&amp;rsquo;t care about our angle, so we reset it, and ➌ - we provide all needed parameters, and set those accordingly with &lt;code&gt;assoc&lt;/code&gt;.
The beauty of multi-arity procedures is that it can call itself with another amount of arguments, so in this case, there&amp;rsquo;s only one real body, that does the work (➌), and others (➊, ➋) are only calling it with all needed parameters.
With this procedure we can quickly set the desired position for our camera:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/set-position&lt;/span&gt;) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; reset&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/set-position&lt;/span&gt; 10 20) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; set coordinates&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 10 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 20 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 0}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/set-position&lt;/span&gt; 10 20 90) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; fully specify position&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; 10 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; 20 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can use this later when we initialize our stages in the game.&lt;/p&gt;
&lt;h2 id=&#34;casting-rays&#34;&gt;Casting rays&lt;/h2&gt;
&lt;p&gt;Now, when we have our camera and walls, we can finally cast some rays.
Although, we&amp;rsquo;re not casting rays, but really long line segments because our algorithm will check for intersections between line segments of stage walls, and our rays.&lt;/p&gt;
&lt;p&gt;First, we need some linear algebra.
In particular, we need to check if two line segments intersect or not.
This is done by three procedures.
First one checks if a point lies on the line segment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-segment?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Checks if point `[ax ay]` lies on segment defined by two points `[b
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  c]`, where each point is defined as a vector `[x y]`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;] [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;]]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;max &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;max &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This procedure accepts a point, and a line segment defined as two points and checks whenever the point lies on that line segment.
We will need this procedure because when we will check for intersections, we need to ensure, that we&amp;rsquo;re staying inside line segments.&lt;/p&gt;
&lt;p&gt;Next bit is &lt;code&gt;orientation&lt;/code&gt; procedure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;cond &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; 0) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:cw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; 0) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:cc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:else&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:colinear&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This procedure checks the relationship of point &lt;code&gt;a&lt;/code&gt;, and points &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;.
These relationships can be &lt;code&gt;:cw&lt;/code&gt; (for clockwise), &lt;code&gt;:cc&lt;/code&gt; (for counter clockwise), and &lt;code&gt;:colinear&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/orientation.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Now we can check for the intersection itself:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersect?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Checks if two line segments intersect. Line segments are defined as
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  vector of two points `[a1 a2]`, and each point is a vector of two
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;  coordinates `[x y]`.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o2&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o3&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o4&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;orientation&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o4&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o1&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:colinear&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-segment?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o2&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:colinear&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-segment?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o3&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:colinear&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-segment?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a1&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;o4&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:colinear&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-segment?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;a2&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;b2&lt;/span&gt;])))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To find the point of the intersection itself, we need to calculate these two formulas:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andreyor.st/ltximg/2020-06-04-simple-ray-casting-with-clojurescript_2b9facc8d9bb825db7236d3992da31243e3b576b.svg&#34; alt=&#34;\[x=\frac{(x_1\cdot{y_2}-y_1\cdot{x_2})\cdot(x_3-x_4)-(x_1-x_2)\cdot(x_3\cdot{y_4}-y_3\cdot{x_4})}
{(x_1-x_2)\cdot(y_3-y_4)-(y_1-y_2)\cdot(x_3-x_4)}\]&#34; class=&#34;org-svg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andreyor.st/ltximg/2020-06-04-simple-ray-casting-with-clojurescript_390fe82895e7837d319616f6718408f327ed848e.svg&#34; alt=&#34;\[y=\frac{(x_1\cdot{y_2}-y_1\cdot{x_2})\cdot(y_3-y_4)-(y_1-y_2)\cdot(x_3\cdot{y_4}-y_3\cdot{x_4})}
{(x_1-x_2)\cdot(y_3-y_4)-(y_1-y_2)\cdot(x_3-x_4)}\]&#34; class=&#34;org-svg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s write those as &lt;code&gt;intersection&lt;/code&gt; procedure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;intersection &lt;/span&gt;[[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;] [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;] &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;)) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve added &lt;code&gt;:as ray&lt;/code&gt; and &lt;code&gt;:as wall&lt;/code&gt; to make it more clear what these points are related to.
The order doesn&amp;rsquo;t really matter, since we&amp;rsquo;re computing a point, but I think it gives a slight idea of what this procedure expects.&lt;/p&gt;
&lt;p&gt;As a final piece, we need a procedure, that will find all intersections for our ray, and return those in some form, that will be usable for us later.
I&amp;rsquo;ve created this procedure, that takes our stage, and two points as &lt;code&gt;ray&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersect?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;font-weight:bold&#34;&gt;new &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;intersection &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                [10000000 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end&lt;/span&gt;])))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{})))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we&amp;rsquo;re using &lt;a href=&#34;https://clojure.org/guides/threading_macros#thread-last&#34; target=&#34;_blank&#34;&gt;thread last macro&lt;/a&gt; ➊, which essentially takes the result of our expression, and puts it in the last position in the next expression.
We then map with an anonymous procedure, that takes &lt;code&gt;wall&lt;/code&gt;, from our &lt;code&gt;stage&lt;/code&gt;, and checks if it &lt;code&gt;intersects?&lt;/code&gt; with our &lt;code&gt;ray&lt;/code&gt;.
If it does, we calculate &lt;code&gt;new&lt;/code&gt; intersection point, and return a vector of the distance between ray origin and intersection point, and this new point.
When map finishes, it produces this kind of list &lt;code&gt;([10 [0 15]] [11 [4.2 22.8]] … [length [x y]])&lt;/code&gt;.
We then convert it into a hash map, where a length will be our key, and a set of coordinates will be our value.
The distance procedure is defined as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/sqrt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/pow&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;) 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/pow&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) 2)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we finally can cast our rays.
First, let&amp;rsquo;s cast a set of rays and draw those without truncation at the intersection point:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count&lt;/span&gt; 16
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 2.0))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 5000)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#ffe680&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt;)))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now if we call our procedures for drawing rays, camera, and stage like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stages/example-stage&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.core&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We should see this result:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example3&#34; width=&#34;556&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Now let&amp;rsquo;s change this procedure, so it will find ray ends before drawing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 2.0))))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 5000)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply min &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;keys &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#ffe680&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt;)))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, we compute a map of intersections ➊, then find the shortest intersection length from the map by applying the &lt;code&gt;min&lt;/code&gt; procedure to the list of keys in the map ➋, and lastly get the closest endpoint for given ray ➌.&lt;/p&gt;
&lt;p&gt;This way we can find all intersections of the given ray with all walls, but we will draw only the shortest one, like this:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example4&#34; width=&#34;556&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;To illustrate this a bit better, let&amp;rsquo;s create simple animation by making our camera rotate:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example5&#34; width=&#34;556&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Now we can use the &lt;code&gt;cast-rays&lt;/code&gt; procedure to make our pseudo-3D image.&lt;/p&gt;
&lt;h2 id=&#34;making-a-3d-view-of-our-scene&#34;&gt;Making a 3D view of our scene&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll need to modify our &lt;code&gt;cast-rays&lt;/code&gt; procedure, so it would return a list of rays instead of drawing it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-between&lt;/span&gt; [[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;]] [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;]]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/atan2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta2&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/atan2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta2&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;180 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) 100)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov&lt;/span&gt; 2.0))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; ()]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 5000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply min &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;keys &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-between&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               &lt;span style=&#34;&#34;&gt;➍&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;conj &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;]))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;&#34;&gt;➎&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doseq &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-line&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;pos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#ffe680&amp;#34;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First, we&amp;rsquo;ve defined an &lt;code&gt;angle-between&lt;/code&gt; ➊ procedure, which takes two line segments and computes the angle between those in radians.
We then added one extra computation before we cast rays - we compute &lt;code&gt;central-ray&lt;/code&gt; ➋, a direction where the camera is looking.
Then, we compute the angle between the current ray we&amp;rsquo;re casting and the central ray ➌.
After that we&amp;rsquo;re &lt;code&gt;conj&lt;/code&gt;ing ➍ vector with endpoint, shortest length, angle, and ray number to a list of rays.
Finally, we return a list of rays ➎ to the caller.
&lt;code&gt;draw-rays&lt;/code&gt; will later use these rays afterward and draw each one ray by ray.&lt;/p&gt;
&lt;p&gt;Now, whenever we call this procedure, we get all the useful information that we will later need to produce an image.
First, let&amp;rsquo;s create another procedure, that will render all our elements on screen in a sequence:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clearRect&lt;/span&gt; 0 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-rays&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;requestAnimationFrame&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a skeleton, not a fully realized procedure.
Note that at ➊, we request another frame to be drawn on our canvas.
So this is more like a game loop, though not quite.
We will use it as our game loop though.&lt;/p&gt;
&lt;p&gt;So, what we do here, is we create a set of bindings on each frame, and we dereference our &lt;code&gt;cam/camera&lt;/code&gt; to get its position and angle, and then cast rays from the camera on our stage.
Later we clear canvas and call &lt;code&gt;draw-rays&lt;/code&gt;, &lt;code&gt;draw-camera&lt;/code&gt;, and &lt;code&gt;draw-stage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Calling this procedure should initiate an animation sequence, so if we add &lt;code&gt;(swap! cam/camera cam/rotate 1)&lt;/code&gt;, at some point we will have an animation of the rotating camera.
Now let&amp;rsquo;s create a 3D view:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-3d-stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rayCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2)])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#333&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#666&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;empty?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➌&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;&#34;&gt;➍&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rgb(&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;&#34;&gt;➎&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ctx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; 1) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; extra pixel for border&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This procedure first fills background ➊, then, we &lt;code&gt;loop&lt;/code&gt; through each ray, we calculate wall height by simply subtracting canvas height and distance to the wall ➌, and since our canvas is 256 pixels high, we use this value as our color as well ➍.
Not really a pretty solution, but will do it for now.
Then we fill a rectangle of this height, and width, with an offset of half of the canvas width plus the number of the ray, times its width.
Calling this procedure in our &lt;code&gt;render&lt;/code&gt; procedure gives us such a view:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example6&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Sure this gives us the desired 3d view, but something is not right.
When we look at our walls we can see that we get some kind of fish eye effect, which we can see in its full form if we look directly at the wall:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example7&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;There&amp;rsquo;s a good reason for this, which we can fix, although it requires a few additional calculations.&lt;/p&gt;
&lt;h2 id=&#34;fisheye-compensation&#34;&gt;Fisheye compensation&lt;/h2&gt;
&lt;p&gt;The reason for this effect is the method we&amp;rsquo;re using to calculate wall heights.
Here&amp;rsquo;s how we currently view our would:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/fish-eye.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;This curve is our screen, so if we were to display this on a non-flat screen with the opposite curve, our image would look natural.
However our screens are flat, so we need to compensate for this.
In order to do this, we need to compute distances while taking into account the number of degrees between camera direction and the ray we currently casting.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s declare &lt;code&gt;angle-between&lt;/code&gt; procedure, that will return the angle between two line segments, one of which will be the direction where the camera is facing, and the other one is the ray we currently casting:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-between&lt;/span&gt; [[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;]] [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;]]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta1&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/atan2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y2&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta2&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/atan2&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y4&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x3&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x4&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;theta2&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;min &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/abs&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;180 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;diff&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can use it in our &lt;code&gt;cast-rays&lt;/code&gt; procedure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) 100)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; 2.0))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; ()]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 5000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply min &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;keys &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-between&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;&#34;&gt;➋&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;conj &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;]))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We store calculated angle ➊, and then add it to our ray and &lt;code&gt;conj&lt;/code&gt; it to our &lt;code&gt;rays&lt;/code&gt; collection.
This vector already is quite big, so it would be better to use some associative collection instead.
Let&amp;rsquo;s change it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;conj &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, that &lt;code&gt;cast-rays&lt;/code&gt; returns a list of hash maps, we need to update our other procedures that expected a list of vectors.
I&amp;rsquo;ll omit these steps, as it ain&amp;rsquo;t much different from what I&amp;rsquo;ve previously described, and this post is already way longer than I&amp;rsquo;ve thought, but using hash maps will prove more usable when we will need to incorporate other information into our ray, such as color.&lt;/p&gt;
&lt;p&gt;Now we can use angles in &lt;code&gt;draw-3d-scene&lt;/code&gt; procedure.
We&amp;rsquo;ll change our &lt;code&gt;distance&lt;/code&gt; computation to use &lt;code&gt;Math/cos&lt;/code&gt; procedure, to compute corrected distance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should give us the such result:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example8-1&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;This looks correct when we face the wall at a 90-degree angle.
But if we&amp;rsquo;re aligned with the wall, we get this:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example8-2&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Which is not right.
Wall is curved for some reason.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: To be completely honest, up to this point I did everything without using existing raycasting tutorials.
But when I applied a seemingly correct fisheye compensation, and it has gone away only partially, I got stuck for a while.
So in order to find a correct way to compensate for this fisheye effect, I&amp;rsquo;ve read &lt;a href=&#34;https://www.permadi.com/tutorial/raycast/rayc5.html&#34; target=&#34;_blank&#34;&gt;this one&lt;/a&gt;, but for some reason the formula there didn&amp;rsquo;t work for me, so I&amp;rsquo;ve altered it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;So it seems that we&amp;rsquo;re missing the projection plane.
Let&amp;rsquo;s create one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt; 2) (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/atan&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/radian&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is better to compute this once, but since we can change the ray count, we have to recompute this.&lt;/p&gt;
&lt;p&gt;With this distance we can add computation in our &lt;code&gt;wall-height&lt;/code&gt; computation process:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-3d-stage-example9&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#333&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#999&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;sort &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l1&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt;} {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt;}] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:n&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; 4))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; 10)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rgb(&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; 1) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; extra pixel for border&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This looks much better in both examples:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example9-1&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
  &lt;canvas id=&#34;example9-2&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;Although walls now appear further.
I&amp;rsquo;ve tried to make up constants that will play nice to make the wall occupy the whole height when we near the wall, so I&amp;rsquo;ll keep it this way.
I&amp;rsquo;m sure I have some misunderstanding of the algorithm, but it works, so I&amp;rsquo;m ok with that.&lt;/p&gt;
&lt;h2 id=&#34;handling-input-and-focus&#34;&gt;Handling input and focus&lt;/h2&gt;
&lt;p&gt;Now, when we have our camera working, we can make it move by pressing arrow keys.
We already have needed procedures for handling camera position and rotation, so the only thing we really need is input handlers, and a way to focus our canvas, so pressing arrows would not scroll the page.&lt;/p&gt;
&lt;p&gt;There are some libraries for handling keyboard input, but I&amp;rsquo;m a purist, so we&amp;rsquo;ll implement this without dependencies.
All we need is two procedures, that check if a key is pressed, and that it is released.
Let&amp;rsquo;s create &lt;code&gt;raycasting/input.cljs&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;raycasting.input&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;atom&lt;/span&gt; {}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defonce &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;focus&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We start by defining another atom for our key states.
It will hold a map of keys and their states, like this &lt;code&gt;{&amp;quot;Up&amp;quot; false, &amp;quot;Down&amp;quot; true}&lt;/code&gt;, which means that currently the &lt;kbd&gt;Down&lt;/kbd&gt; key is pressed down.
Another one is &lt;code&gt;focus&lt;/code&gt; which we will use to determine whether should we handle input or not.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s add these three procedures:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;valid-key?&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Escape&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Shift&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowLeft&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowUp&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowRight&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;= key &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowDown&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-key-press&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;focus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-event&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;key &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-key&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;valid-key?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;preventDefault&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc key &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-key-release&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;focus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-event&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;key &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-key&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;valid-key?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;assoc key &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;preventDefault&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ll get our keys as strings, and check if this is one of the keys we need.
If it is, and we&amp;rsquo;re focused, we &lt;code&gt;swap!&lt;/code&gt; our &lt;code&gt;key&lt;/code&gt; state with either &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, so our &lt;code&gt;key-states&lt;/code&gt; atom always holds most recent state.
Now we need to assign these procedures to events:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-onkeyup&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-key-release&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-onkeydown&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-key-press&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also have these procedures to handle focus:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;on-click&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;focus&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;true&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;release-focus&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;focus&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;false&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But we set these in the initialization code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;^&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:export&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;raycaster&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;mousedown&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;input/on-click&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/set-position&lt;/span&gt; 10 10 45)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-getContext&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getContext&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The final step would be to poll our keys on each frame in our &lt;code&gt;render&lt;/code&gt; procedure.
For this, we create another procedure, but in &lt;code&gt;raycasting.core&lt;/code&gt; this time:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-camera&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;} @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Escape&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;input/release-focus&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;reset!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;input/key-states&lt;/span&gt; {}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowRight&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Shift&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/strafe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; -1.5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;detect-collision&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/strafe&lt;/span&gt; -1)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; -1.5)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowLeft&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;Shift&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/strafe&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 1.5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;detect-collision&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/strafe&lt;/span&gt; 1)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; 1.5)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowUp&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; 1.5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;detect-collision&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-forward&lt;/span&gt; 1.5))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;key-states&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;ArrowDown&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-forward&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; -1.5)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;not &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;detect-collision&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-forward&lt;/span&gt; -1.5))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We then, call this procedure each frame as early as possible.
You can notice that we&amp;rsquo;re calling another procedure &lt;code&gt;detect-collision&lt;/code&gt;, it is much like our intersection finding stuff, but it calculates the end position of our camera, and checks if the path intersects with any of our walls.
Not very optimal, but works well.&lt;/p&gt;
&lt;p&gt;The last thing I want to add is a way to control the amount of rays, and field of view, as well as a fisheye compensation toggle.
For that we&amp;rsquo;ll need these &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tags:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;input type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;range&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountSlider&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         min=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;10&amp;#34;&lt;/span&gt; max=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;256&amp;#34;&lt;/span&gt; step=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/input&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;label for=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountSlider&amp;#34;&lt;/span&gt;&amp;gt;Ray Count: &amp;lt;/label&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;output name=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountValue&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountOutput&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/output&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;input type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;range&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSlider&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         min=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;10&amp;#34;&lt;/span&gt; max=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;360&amp;#34;&lt;/span&gt; step=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/input&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;label for=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSlider&amp;#34;&lt;/span&gt;&amp;gt;Field of View: &amp;lt;/label&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;output name=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSliderValue&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSliderOutput&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/output&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;input type=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;checkbox&amp;#34;&lt;/span&gt; id=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fishEyeCompensation&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/input&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;label for=&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fishEyeCompensation&amp;#34;&lt;/span&gt;&amp;gt; FishEye compensation&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And we need a way to control those.
For this, let&amp;rsquo;s add these procedures:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-fov&lt;/span&gt; 360)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt; 180)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-ray-count&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/parseInt&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;output&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountOutput&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;output&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-innerHTML&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-fov&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/parseInt&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;output&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSliderOutput&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;output&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-innerHTML&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-fish-eye-compensation&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;.. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;event&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-target&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-checked&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSlider&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-max&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-fov&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;and &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-output&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSliderOutput&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-output&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-innerHTML&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;init-inputs&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-slider&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountSlider&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;input&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-ray-count&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-output&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rayCountOutput&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-output&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-innerHTML&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSlider&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;input&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-fov&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-max&lt;/span&gt;) (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-compensated-fov&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;max-fov&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fov-slider&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-output&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fovSliderOutput&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-count-output&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-innerHTML&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;compensate&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/document&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;getElementById&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;fishEyeCompensation&amp;#34;&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;compensate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;addEventListener&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;update-fish-eye-compensation&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;compensate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-value&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In short, these are event handlers, which are called when we&amp;rsquo;re interacting with these inputs.
We&amp;rsquo;re setting initial values as well, as the handlers in &lt;code&gt;init-input&lt;/code&gt; procedure.&lt;/p&gt;
&lt;h2 id=&#34;coloring-walls&#34;&gt;Coloring walls&lt;/h2&gt;
&lt;p&gt;Up until now, we were creating gray walls, which are fine, but boring.
And you could notice that we&amp;rsquo;re drawing our lines in color, so walls have color information.
Let&amp;rsquo;s update our &lt;code&gt;find-intersections&lt;/code&gt; procedure to include color information, and use it to color our walls:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersect?&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;font-weight:bold&#34;&gt;new &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;intersection &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  [(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;new&lt;/span&gt;) {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:end&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;new &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;or &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#eeeeee&amp;#34;&lt;/span&gt;)}])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                [10000000 {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;}])))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;into &lt;/span&gt;{})))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we return a map that has length as its key, and another map, which holds endpoint and wall color as a value.
We need to update our &lt;code&gt;cast-rays&lt;/code&gt; procedure to use this information:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; [(&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;) 100)]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/rotate&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; 2.0))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; ()]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;do &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-point&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; 5000)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;find-intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;apply min &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;keys &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;&#34;&gt;➊&lt;/span&gt; {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersections&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-between&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-start&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt;] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;central-ray&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                              0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;dec &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;step&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;conj &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:end&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-end&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;shortest-ray&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;}))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We destructure our map ➊, and then use its values when we &lt;code&gt;conj&lt;/code&gt; rays.
If we use this color in our &lt;code&gt;draw-3d-stage&lt;/code&gt; procedure, we&amp;rsquo;ll finally get results similar to what I showed in the very beginning:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;example10&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;But it would be nice if we keep the effect that more distant walls appear darker.
To do that we&amp;rsquo;ll have to parse color, and dim it by some factor:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim-factor&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/pow&lt;/span&gt; 1.1 (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;inc &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;amount&lt;/span&gt;) 7))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;int &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim-factor&lt;/span&gt;))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;lt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; 25)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      25
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim-color&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;red&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/parseInt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0x&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;subs &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; 1 3)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;green&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/parseInt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0x&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;subs &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; 3 5)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;blue&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/parseInt&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;0x&amp;#34;&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;subs &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; 5)))]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;rgb(&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;red&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;green&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;blue&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These two procedures will dim colors encoded as six-digit hex colors, or &lt;code&gt;#ffffff&lt;/code&gt;.
We use our distance as the dim factor with some computations to make it look nice.
Now we can use it in our &lt;code&gt;draw-3d-stage&lt;/code&gt; procedure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-3d-stage&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;) 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gradient&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;createLinearGradient&lt;/span&gt; 0 0 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;doto &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gradient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addColorStop&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#424242&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addColorStop&lt;/span&gt; 0.5 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#111111&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;.addColorStop&lt;/span&gt; 1 &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;&amp;#34;#e2e2e2&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;gradient&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;loop &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;sort &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l1&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt;} {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt;}] (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l1&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;l2&lt;/span&gt;)) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when-let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[{&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:length&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:angle&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:color&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;angle-step&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*compensate-fisheye*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;m/three-decimal&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;Math/cos&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-degree&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ray-count*&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;projection-distance&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*fov*&lt;/span&gt; 4))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dim-color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;distance&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;set!&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-fillStyle&lt;/span&gt;) &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;color&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;fillRect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;canvas-width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;* &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;n&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;- &lt;/span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; 2) (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;/ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt; 2))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;+ &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ray-width&lt;/span&gt; 1) &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;;; extra pixel for border&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall-height&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;recur&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;rest &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve also added a bit more nice gradient for our background color there.
This will be our final version of this procedure.&lt;/p&gt;
&lt;h2 id=&#34;labyrinth-game&#34;&gt;Labyrinth game&lt;/h2&gt;
&lt;p&gt;Now we can create a small labyrinth game, but we need a way to determine if the goal was reached.
But first, we need a stage to play on, as our current one isn&amp;rsquo;t really a good one.
I&amp;rsquo;ve come up with this:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/labyrinth.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Our goal is to reach that colored corridor.
To check if we succeeded we&amp;rsquo;ll simply check if our camera is inside the square.
To check that we&amp;rsquo;ll use our raycasting facilities.
The algorithm is pretty easy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We cast rays from our point to the right,&lt;/li&gt;
&lt;li&gt;We count with how many walls of a given square we intersect with,&lt;/li&gt;
&lt;li&gt;If the amount of intersections is odd then we&amp;rsquo;re inside.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can see that this works for us:&lt;/p&gt;
&lt;figure class=&#34;invertable&#34;&gt;&lt;img src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/inside.svg&#34;/&gt;
&lt;/figure&gt;

&lt;p&gt;Of course, there are special cases, like when a point lies on either of the rectangle sides, but we can&amp;rsquo;t intersect with walls, because we detect collisions, so we&amp;rsquo;ll be fine.
Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;inside-rectangle&lt;/span&gt; [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dy&lt;/span&gt;]]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;walls&lt;/span&gt; [[[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;bx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;by&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cy&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dy&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dx&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;dy&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ax&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;ay&lt;/span&gt;]]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt;} (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/move-forward&lt;/span&gt; {&lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:y&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#666;font-style:italic&#34;&gt;:degree&lt;/span&gt; 90} 1000)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;walls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;font-weight:bold&#34;&gt;fn &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;intersect?&lt;/span&gt; [[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;] [&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;x&lt;/span&gt;&amp;#39; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;y&lt;/span&gt;&amp;#39;]] &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;wall&lt;/span&gt;) 1 0)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;reduce + &lt;/span&gt;0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;odd?&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We receive four points that define our goal and move the camera 90 degrees right to some amount.
Then we map &lt;code&gt;intersect?&lt;/code&gt; procedure across our walls, returning either &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt; depending on collision detection, and &lt;code&gt;reduce&lt;/code&gt; results with &lt;code&gt;+&lt;/code&gt;, to finally check if the result is &lt;code&gt;odd?&lt;/code&gt; or not.&lt;/p&gt;
&lt;p&gt;Though we need some way to extract goals from our stage, I&amp;rsquo;ll just define it as a constant because I don&amp;rsquo;t want to make stage code even more complex than it is now, and we&amp;rsquo;re not going to change stages.
So when we&amp;rsquo;ve reached our goal, we&amp;rsquo;ll just teleport the camera back to starting point:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;move-camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;input/key-states&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;inside-rectangle&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage/goal&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;swap!&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/set-position&lt;/span&gt; 12 195 180))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;font-weight:bold&#34;&gt;let &lt;/span&gt;[&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*canvas*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;-width&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; @&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cam/camera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt; (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;cast-rays&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;*ctx*&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;clearRect&lt;/span&gt; 0 0 &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;height&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-rays&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-camera&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;camera&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;stage&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;draw-3d-stage&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;rays&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;font-weight:bold&#34;&gt;. &lt;/span&gt;&lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;js/window&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;requestAnimationFrame&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;render&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Combining all this stuff should give us this small game:&lt;/p&gt;
&lt;div style=&#34;text-align: center&#34;&gt;
  &lt;canvas id=&#34;raycaster&#34; width=&#34;512&#34; height=&#34;224&#34;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;input type=&#34;range&#34; id=&#34;rayCountSlider&#34;
         min=&#34;10&#34; max=&#34;256&#34; step=&#34;1&#34;&gt;&lt;/input&gt;
  &lt;label for=&#34;rayCountSlider&#34;&gt;Ray Count: &lt;/label&gt;
  &lt;output name=&#34;rayCountValue&#34; id=&#34;rayCountOutput&#34;&gt;&lt;/output&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;input type=&#34;range&#34; id=&#34;fovSlider&#34;
         min=&#34;10&#34; max=&#34;360&#34; step=&#34;1&#34;&gt;&lt;/input&gt;
  &lt;label for=&#34;fovSlider&#34;&gt;Field of View: &lt;/label&gt;
  &lt;output name=&#34;fovSliderValue&#34; id=&#34;fovSliderOutput&#34;&gt;&lt;/output&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;input type=&#34;checkbox&#34; id=&#34;fishEyeCompensation&#34;&gt;&lt;/input&gt;
  &lt;label for=&#34;fishEyeCompensation&#34;&gt; FishEye compensation&lt;/label&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;You can click on this canvas, and use &lt;kbd&gt;Up&lt;/kbd&gt;, &lt;kbd&gt;Down&lt;/kbd&gt;, &lt;kbd&gt;Left&lt;/kbd&gt;, &lt;kbd&gt;Right&lt;/kbd&gt; to move, you also can strafe to the side while holding &lt;kbd&gt;Shift&lt;/kbd&gt;, and pressing &lt;kbd&gt;Esc&lt;/kbd&gt; will return focus to the page so you could scroll it with arrow keys as usual.&lt;/p&gt;
&lt;h2 id=&#34;what-i-ve-learned&#34;&gt;What I&amp;rsquo;ve learned&lt;/h2&gt;
&lt;p&gt;This project was extremely fun to do in ClojureScript, and Clojure itself is quite an awesome language, although those have some differences.
If you&amp;rsquo;re learning Clojure, I highly recommend &lt;a href=&#34;https://www.braveclojure.com/&#34; target=&#34;_blank&#34;&gt;Clojure for the Brave and True&lt;/a&gt; book, and although I didn&amp;rsquo;t finish it yet, I&amp;rsquo;ve borrowed a lot of ideas from there, like using these little Unicode circles (➊) to mark stuff for further explanations.
This book has a &lt;a href=&#34;https://www.braveclojure.com/functional-programming/#Peg_Thing&#34; target=&#34;_blank&#34;&gt;&amp;ldquo;Peg Thing&amp;rdquo; game example&lt;/a&gt;, which got me thinking about trying something a bit more complex and real-time with Clojure, but I wasn&amp;rsquo;t sure how to draw graphics with Java stuff, so I&amp;rsquo;ve chosen ClojureScript because the canvas was very easy to reach.&lt;/p&gt;
&lt;p&gt;After implementing this, I think that while you don&amp;rsquo;t really need all these class objects like &lt;code&gt;point&lt;/code&gt;, &lt;code&gt;line&lt;/code&gt;, e.t.c.
as long as you&amp;rsquo;re passing those in meaningful contexts, which I didn&amp;rsquo;t really do through this post, and I expect that this code will be really hard to read after some point in time.
But certainly, maps provide most of what you need from a class or object and are more generic than objects.&lt;/p&gt;
&lt;p&gt;The cleaned-up source code for this project can be found &lt;a href=&#34;https://gitlab.com/andreyorst/raycasting-with-clojurescript&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; if you&amp;rsquo;re interested in looking more closely.
I hope you&amp;rsquo;ve enjoyed the read, and got interested in Clojure or Lisp in particular if you&amp;rsquo;re not a Lisp hacker already.&lt;/p&gt;
&lt;script type=&#34;text/javascript&#34; src=&#34;https://andreyor.st/2020-06-04-simple-ray-casting-with-clojurescript/js/main.js&#34;&gt;&lt;/script&gt;
&lt;script&gt;
  window.onload = function() {
    raycasting.core.init();
  }
&lt;/script&gt;
&lt;div class=&#34;comment-link&#34;&gt; &lt;a href=&#34;mailto:%61%6e%64%72%65%79%6f%72%73%74%2b%62%6c%6f%67%40%67%6d%61%69%6c%2e%63%6f%6d?subject=Comment: Simple Ray Casting with ClojureScript&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Comment via email&lt;/a&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 04 Jun 2020 13:49:00 +0300</pubDate>
    </item>
  </channel>
</rss>
