<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Statebox - Medium]]></title>
        <description><![CDATA[Formally verified process language. Find out more at https://statebox.org - Medium]]></description>
        <link>https://medium.com/statebox?source=rss----63b470e13211---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Statebox - Medium</title>
            <link>https://medium.com/statebox?source=rss----63b470e13211---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 16:50:23 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/statebox" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[FSM-Oracle Release]]></title>
            <link>https://medium.com/statebox/fsm-oracle-release-235e04a156ae?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/235e04a156ae</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[petri-nets]]></category>
            <category><![CDATA[finite-state-machine]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[category-theory]]></category>
            <dc:creator><![CDATA[Fabrizio Romano Genovese]]></dc:creator>
            <pubDate>Wed, 29 Apr 2020 12:07:36 GMT</pubDate>
            <atom:updated>2020-04-29T12:07:36.610Z</atom:updated>
            <content:encoded><![CDATA[<p>Hoping this blogpost finds you all well and without any further ado, we’d like to announce a very important release for Statebox: <a href="https://github.com/statebox/fsm-oracle">the finite state machine oracle</a>.</p><p>A considerable amount of time has been spent on both research (more amazing stuff about this will follow in the coming months) and on formalizing a formally verified version of our <a href="https://github.com/statebox/idris-fsm-oracle">core</a> in Idris, which in turn has been implemented by many people from our team (mainly Sjoerd, Alex and Andre, which I thank for the incredible work!).</p><h4>What does it do?</h4><p>Now that we have a version of the core released, I’d like to explain what it does. The idea is simple:<em> You pass it a specification for a finite state machine/Petri net, an initial state and a sequence of actions, and the core will tell you if that sequence of actions is valid.</em></p><p>I know what you are thinking: “Wait what? You spent more than a year to get this?!” The short answer is “Yes, we have.” The long answer is “We decided to make an investment, and spent a lot of time developing our basic infrastructure so that building incrementally on it would be much easier later on”. An even better answer is: “Try it out yourself!”. In any case, with this post, I hope to convince you this choice is not as abysmally dumb as it sounds, but quite the opposite.</p><h4>Typedefs and Typed Core</h4><p>Several years ago we started two big projects at Statebox, namely <a href="https://github.com/typedefs">Typedefs</a> and Typed Core. <em>Typedefs is a formally verified programming language for types and terms. </em>Essentially, it allows to specify a universal format for types that can be recursively built out of type variables, products, coproducts and fixed point operators, and for their terms. Given Typedefs and their terms, one is able to automatically serialize and deserialize them to various formats, such as binary, S-expressions and JSON. This allows for a formally well-defined way of exchanging data between different programming languages.</p><p>On the other hand, <em>typed core is a formally verified implementation of the main engine that tells us if a given sequence of transitions fired in a Petri net is valid or not.</em> This is done in Idris, and relies on <a href="http://github.com/statebox/idris-ct/">idris-ct</a>, our formally verified category theory library.</p><p>Getting these two projects up to a point where they could be useful has been a lot of work, but it pays off! <em>Now, we can just define our categories effortlessly using idris-ct, and import/export their signatures and morphisms using Typedefs.</em></p><p>This is exactly what we did in our first version of the core, which we completed roughly a month ago. In it, the user is able to feed the core with a specification for a finite state machine, an initial state and a sequence of actions, specified as a path in the underlying FSM graph. This specification is exchanged using JSON, as in the following example:</p><pre>{<br>  &quot;_0&quot;: {<br>    &quot;_0&quot;: 5,<br>    &quot;_1&quot;: [<br>      {<br>       &quot;input&quot;: 1,<br>       &quot;output&quot;: 1<br>      },<br>      {<br>       &quot;input&quot;: 3,<br>       &quot;output&quot;: 4<br>      },<br>      {<br>       &quot;input&quot;: 2,<br>       &quot;output&quot;: 1<br>      },<br>      {<br>       &quot;input&quot;: 3,<br>       &quot;output&quot;: 2<br>      }]<br>  },<br>  &quot;_1&quot;: 3,<br>  &quot;_2&quot;: [3, 2, 0]<br>}</pre><p>Here, the first field specifies the “shape” of the FSM:</p><pre>&quot;_0&quot;: 5,<br>    &quot;_1&quot;: [<br>      {<br>       &quot;input&quot;: 1,<br>       &quot;output&quot;: 1<br>      },<br>      {<br>       &quot;input&quot;: 3,<br>       &quot;output&quot;: 4<br>      },<br>      {<br>       &quot;input&quot;: 2,<br>       &quot;output&quot;: 1<br>      },<br>      {<br>       &quot;input&quot;: 3,<br>       &quot;output&quot;: 2<br>      }]</pre><p>The first field tells us that the FSM has five vertexes, indexed 0, 1, 2, 3, 4 . The second field specifies the edges, indexed 0,1,2,3: The first edge goes from 1 to 1 , the second from 3 to 4 , the third from 2 to 1, the fourth from 3 to 2. All in all, the FSM looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/312/1*Wk_s2aYRuuNwQmyFtKHOVw.png" /></figure><p>Then we have:</p><pre>  &quot;_1&quot;: 3,<br>  &quot;_2&quot;: [3, 2, 0]</pre><p>Here the first field specifies the initial state (start from vertex 3), while the second one specifies a path, in this case (go through edge 3, then through edge 2, then through 0 ). The path is the one displayed below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/372/1*9EN7viUl-HmU43BO2ssYsg.png" /></figure><p>The point is that this JSON format is not arbitrary; it is the encoding of a Typedefs term. So if the term is malformed for whatever reason, Typedefs will throw an error automatically. We do not have to worry anymore about our parser being correct, because it is generated automatically from our definition!</p><p>Internally, a correct FSM specification is used as the signature to build the free category associated to it. Then, the path is evaluated: Either it forms a valid morphism or it doesn’t. If it doesn’t then we throw an error, if it does we check that the domain of such morphism is indeed the initial state specified. If this is the case we return a positive answer. In any case, the answer is again returned as a Typedefs term, and as such can be easily exchanged around.</p><blockquote>All in all, our software works like an oracle. The cool thing is that we can be very flexible about the types we use to exchange computational objects around since TDefs will take care of serialization and parsing for us. Moreover, we are using categorical constructions as typecheckers, and not some ad-hoc thing.</blockquote><p>The advantages of this approach are considerable. Less than two weeks ago we started working on the Petri net version of this, which amounts to taking symmetric strict monoidal categories as our typecheckers. We had already implemented those in idris-ct, and hence we were able to finish our work almost instantly. <strong>With an amount of minimal tweaking, we were able to recast our infrastructure completely to deal with Petri nets</strong>. Indeed, we are now in the process of documenting the new version of the core, which we will likely release in the coming months.</p><p>I hope that the advantages of employing categorical methods are now clear. It’s a lot of hassle in the beginning, but then things become way easier since in category theory everything is defined “canonically”, meaning that there is often just one way to do things, which is also the right one if you worked on the foundations of your project well enough.</p><p>Feel free to <a href="https://github.com/statebox/fsm-oracle/">play with the oracle we released</a>, and stay tuned for the new version that we’ll release soon!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=235e04a156ae" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/fsm-oracle-release-235e04a156ae">FSM-Oracle Release</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction is the New Gold]]></title>
            <link>https://medium.com/statebox/abstraction-is-the-new-gold-40cb343f156e?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/40cb343f156e</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Fabrizio Romano Genovese]]></dc:creator>
            <pubDate>Mon, 13 Jan 2020 12:00:39 GMT</pubDate>
            <atom:updated>2020-01-13T12:00:39.664Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/834/1*xCmHSDsAh8-7Xccc05IPKQ.png" /><figcaption><a href="https://ykode.id/making-sense-of-category-theory-6f901e39fa3c">https://ykode.id/making-sense-of-category-theory-6f901e39fa3c</a></figcaption></figure><p>As our dear readers widely know, Statebox is a company that heavily relies on category theory for the development of its products. Attention towards category theory by academia is not at all surprising. Applied category theory has become a fertile research field, as reflected by the several conferences and events which emerged in the past few years, such as <a href="https://www.appliedcategorytheory.org/">the yearly applied category theory conference (ACT)</a> or <a href="https://summit.statebox.org/">our own yearly summit</a>.</p><p>On the other hand, the enterprise sector seems to get increasingly aware of how categorical reasoning could impact their own future. In many niches of the tech space, there is a pervasive feeling that we finally possess the right formal tools to apply compositional techniques (that is, ACT) in a widespread fashion. Some companies are understanding this at a naïve level, and are reacting by, say, increasingly adopting functional programming languages for the development of their product stack. Other companies are instead fully aware of this, and are actively setting up research efforts in applied category theory.</p><h3>How category theory can help your company</h3><p>In <a href="https://www.cambridge.org/core/books/an-invitation-to-applied-category-theory/D4C5E5C2B019B2F9B8CE9A4E9E84D6BC">An Invitation to Applied Category Theory</a>, Fong and Spivak introduce their topic as follows:</p><blockquote>It is unmatched in its ability to organize and layer abstractions, to find commonalities between structures of all sorts.</blockquote><p>To give you an intuitive feeling of how category theory can impact company life, think about the following:</p><ul><li>at a high and abstract level, business is about connecting different ideas and crunching numbers to see how these ideas perform and become profitable;</li><li>programming is about connecting different pieces of software in a manner that will minimise generative effects, or as we like to call it, emergent behavior;</li><li>production and planning is about connecting different facts (e.g. travelling time and price from A to B) while keeping an eye on optimization.</li></ul><p>In all these examples, the idea of “connecting things to other things” is preeminent. <strong>Category theory provides a universal language to reason about these relationships.</strong> Now business planning and programming become just two different incarnations of the same underlying idea. Moreover, the use of functors (which are ways to map things to other things while preserving their connections) makes the unthinkable possible, e.g. <em>by mapping business workflows directly into code</em>. This is precisely what we are working on at <a href="https://statebox.org/">Statebox</a>, and you can see a minimal application of this in our video series about <a href="https://www.youtube.com/watch?v=hxEwmBQTQuI">designing smart contracts with Petri nets</a>.</p><h3>Do you need to be a mathematician to learn category theory?</h3><p>This is the most popular myth surrounding category theory adoption and we are here to bust it. Unfortunately, as all things when seen from the outside world, the ideas behind category theory can feel obscure and complicated. In addition to this, people seem to believe that you have to already know a lot of mathematics to get category theory right. This is clearly false, but such prejudice is reinforced by the fact that nearly all of the free learning material on the internet is directed at mathematicians, physicists and computer scientists.</p><h3>Too hard, won’t bother</h3><p>But how hard is it to learn category theory? In my experience as a category theory teacher, I’ve noticed that people tend to naturally think in compositional terms, but somehow they forget about it when they are taught other things. For this reason, learning category theory requires a shift in point of view that, once started, feels more as a re-discovery than as something new. This is confirmed by my own experience as a category theory student. When I myself had to learn category theory, I found out that the cause of my struggle was trying to understand category theory with the tools I had already acquired, instead of just starting from scratch. When things started clicking, I realized that category theory is, by definition, the most natural way to reason about and model systems. From this point of view it is evident that category theory is not difficult to learn, since its working principles are, most often than not, already well understood by its learners, who simply are not yet aware of this.</p><h3>Category Theory Course — March, Berlin</h3><p>For the above reasons and more, we decided to launch <a href="https://training.statebox.org/">a category theory course</a> aimed at programmers, system architects and businesses in general. We already have experience in teaching category theory to non mathematicians and we believe the best way to teach it is through examples tailored on the knowledge of the learners. In our course, we carefully evaluate the needs of our clients and their skillset, and figure out the most frictionless way to initiate your journey into categorical thinking.</p><p>The aim of our course is to provide a base layer of understanding of the main topics in ACT and show how they can be used to model systems. Then, you will be able to either deepen your knowledge by yourself by accessing previously unmanageable learning material on the internet or to interact with expert category theorists in the ACT community. You will be able to understand the category theory jargon, and <em>this will endow you with a universal language that facilitates the understanding of current research in the field as well as form abstractions and find similarities in seemingly unfamiliar spheres</em>. We truly believe that this opens the door to offering unique solutions to problem solving, regardless of the domain you find yourself in.</p><p>Join our category theory course on 24–27 March in Berlin. The course will be taught by yours truly with the support of at least one other guest category theorist from the ACT community. <a href="https://training.statebox.org/berlin.html">Sign up here</a>!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40cb343f156e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/abstraction-is-the-new-gold-40cb343f156e">Abstraction is the New Gold</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[More (Categorical) Thoughts on Lawful Lenses]]></title>
            <link>https://medium.com/statebox/more-categorical-thoughts-on-lawful-lenses-9dba9fb269fd?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/9dba9fb269fd</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[Marco Perone]]></dc:creator>
            <pubDate>Wed, 16 Oct 2019 05:22:38 GMT</pubDate>
            <atom:updated>2020-04-26T15:22:19.037Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://blog.statebox.org/on-lawful-lenses-6e18a1e17bdf">In the previous post</a> we discussed how we could state a definition for generic lawful optics and we proved that lawful lenses are exactly constant complement lenses.</p><p>In this post we will revisit the ideas presented there in a more categorical fashion, but focusing on lenses in particular.</p><p>What we will present in this post is a series of results which were obtained at the third <a href="https://summit.statebox.org/">Statebox Summit</a> with the collaboration of the participants, out of which I ought to mention <a href="https://twitter.com/_julesh_">Jules Hedges</a>, <a href="https://math.mit.edu/~dspivak/">David Spivak</a>, <a href="http://brendanfong.com/">Brendan Fong</a>, <a href="https://mathdept.ucr.edu/faculty/cvasil.html">Christina Vasilakopoulou</a>, <a href="https://twitter.com/elianalorch">Eliana Lorch</a><a href="https://whatisrt.github.io/">, Andre Knispel</a> and <a href="https://www.cs.ox.ac.uk/people/stefano.gogioso/">Stefano Gogioso</a> for taking active part in this discussion.</p><h3><strong>The Category of Lenses</strong></h3><p>Let’s start by defining the category of lenses. The objects of our category will be pairs of sets (S, T), morphisms between (S, T) and (A, B) will be lenses of type Lens S T A B, which are described by pairs of functions</p><pre>g : S → A</pre><pre>p : S → B → T</pre><p>The composition of two morphisms, i.e. two lenses, (g, p) : (S, T) → (A, B) and (h, q) : (A, B) → (C, D) is a new lens (g&#39;, p&#39;) : Lens S T C D defined by functions</p><pre>g&#39; : S → C<br>g&#39; = g ; h</pre><pre>p&#39; : S → D → T<br>p&#39; s d = p s (q (g s) d)</pre><p>where p&#39; can be represented by the following diagram</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g2SsZR9eI38Fj4abQFYwCA.png" /></figure><p>where ∙ : S → S × S is the copy operation.</p><p>Given any object of our category, which is a pair (S, T), the identity morphism on it is the lens (gᵢ, pᵢ) : (S, T) → (S, T) defined by</p><pre>gᵢ : S → S<br>gᵢ s = s</pre><pre>pᵢ : S → T → T<br>pᵢ s t = t</pre><p>It can be checked that the above definitions satisfy the axioms for a category.</p><h3><strong>Associated Lenses</strong></h3><p>Given a generic lens L := (g, p) : (S, T) → (A, B), we saw <a href="https://blog.statebox.org/on-lawful-lenses-6e18a1e17bdf">in this post</a> that we can define a set</p><pre>M = { m ∈ B → T | ∃ s : S . m = p s }</pre><p>which turns out to be really helpful in proving that lawful lenses are exactly the constant complement ones. In fact, this set allows us to define two new lenses associated to the lens L.</p><p>First off, we can define L* : (S, T) → (A × M, B × M) by</p><pre>g*: S → A × M<br>g* s = (g s, p s)</pre><pre>p* : S → B × M → T<br>p* s (b, m) = m b</pre><p>Moreover, we can also define L^ : (B × M, A × M) → (T, S) by</p><pre>g^ : B × M → T<br>g^ (b, m) = m b</pre><pre>p^ : B × M → S → A × M<br>p^ (b, m) s = (g s, p s)</pre><p>Notice how ^ (pronounced “hat”) produces a swap between A and B and between S and T. In their generic form, L* and L^ are not composable. However, if we restrict them to simple lenses, they are!</p><p>So, with these two new lenses at hand, some questions arise naturally</p><ul><li>In the simple lens case, when are L* and L^ inverse of one another?</li><li>In the simple lens case, when are L* and L^ lawful?</li><li>In the generic case, if we consider π : (A × M, B × M) → (A, B) to be the lens defined by</li></ul><pre>gπ : A × M → A<br>gπ (a, m) = a</pre><pre>pπ : A × M → B → B × M <br>pπ (a, m) b = (b, m)</pre><p>is it always true that L = L* ; π?</p><h3><strong>Are </strong><strong>L* and </strong><strong>L^ Inverses?</strong></h3><p>Let us first consider the composition L* ; L^. In this case we have</p><pre>g*^ : S → S<br>g*^ s = p s (g s) = s -- by getput</pre><pre>p*^ : S → S → S<br>p*^ s₁ s₂ = p s₂ (g s₂) = s₂ -- by getput</pre><p>Therefore L^ ; L^ = id on (S, S) if and only if getput holds for L.</p><p>On the other hand, consider L^ ; L*. We obtain</p><pre>g^* : A × M → A × M<br>g^* (a, m) = (g (m a), p (m a))</pre><pre>p^* : A × M → A × M → A × M<br>p^* (a₁, m₁) (a₂, m₂) = (g (m₂ a₂), p (m₂ a₂))</pre><p>Remember that by definition of M we have that any m ∈ M is of the form p s for some s ∈ S. Hence we get</p><pre>g^* : A × M → A × M<br>g^* (a, p s) = (g (p s a), p (p s a))<br>             = (a, p s) -- by putget and putput</pre><pre>p^* : A × M → A × M → A × M<br>p^* (a₁, p s₁) (a₂, p s₂) = (g (p s₂ a₂), p (p s₂ a₂))<br>                          = (a₂, p s₂) -- by putget and putput</pre><p>We then obtain that L^ ; L* = id on (M × A) whenever L satisfies putget and putput.</p><p>We conclude by saying that L* and L^ are each other’s inverses if and only if L is a lawful lens.</p><h3><strong>Are L* and L^ Lawful?</strong></h3><p>In this section we will check whether L* and L^ are lawful lenses in the simple case, and which conditions we do need to assume on L for them to satisfy the lens laws.</p><p>Let’s start with L*</p><h4><strong>getput</strong></h4><pre>p* s (g* s) = p s (g s) = s -- by getput</pre><h4><strong>putget</strong></h4><pre>g* (p* s₁ (a, p s₂)) = g* (p s₂ a)<br>                     = (g (p s₂ a), p (p s₂ a))<br>                     = (a, p s₂) -- by putget and putput</pre><h4><strong>putput</strong></h4><pre>p* (p* s (a₁, m₁)) (a₂, m₂) = p* (m₁ a₁) (a₂, m₂)<br>                            = m₂ a₂<br>                            = p* s (a₂, m₂) -- always holds</pre><p>Hence L* always satisfies putput, satisfies getput if L satisfies getput and satisfies putget if L satisfies putget and putput. Therefore L* is lawful if and only if L is.</p><p>Let’s now have a look at L^.</p><h4><strong>getput</strong></h4><pre>p^ (a, p s) (g^ (a, p s)) = p^ (a, p s) (p s a)<br>                          = (g (p s a), p (p s a))<br>                          = (a, p s) -- by putget and putput</pre><h4>putget</h4><pre>g^ (p^ (a, m) s) = g^ (g s, p s)<br>                 = p s (g s)<br>                 = s -- by getput</pre><h4><strong>putput</strong></h4><pre>p^ (p^ (a, m) s₁) s₂ = p^ (g s₁, p s₁) s₂<br>                     = (g s₂, p s₂)<br>                     = p^ (a, m) s₂ -- always</pre><p>Therefore also L^ always satisfies putput, and it satisfies getput if L satisfies putget and putput and satisfies putget if L satisfies getput. So also L^ is lawful if and only if L is.</p><h3><strong>Decomposing L</strong></h3><p>One question remains: whether L = L* ; π holds. It is not hard to check that it actually always does; in fact if we compute the components g° and p° for the composed lens, we get</p><pre>g° : S → A<br>g° s = gπ (g* s) = gπ (g s, p s) = g s</pre><pre>p° : S → B → T<br>p° s b = p* (s, pπ (g* s, b))<br>       = p* (s, pπ ((g s, p s), b))<br>       = p* (s, (b, p s)) = p s b</pre><p>In conclusion, we can always decompose L into L* ; π, where π is always lawful.</p><h3><strong>Conclusion</strong></h3><p>In this post we investigated the role of M more closely, as well as the lenses L* and L^ which are generated from it. We saw that L* and L^ are strictly related to L, and that they satisfy the lens laws only if L satisfies other lens laws.</p><p>Putting together the three results presented above, we can also recover a more formal proof that a simple lens is lawful if and only if it is isomorphic to a constant complement lens.</p><p>Some further questions we might consider</p><ul><li>What is M for L* and L^ ?</li><li>How are L**, L*^, L^* and L^^ related to L, L* and L^?</li><li>Is there a relation between M being a singleton set and isomorphisms in the category of lenses (it is easy to prove that M = {*} implies that L satisfies putput)?</li><li>Are the properties stated for the simple case generalizable to the general case?</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9dba9fb269fd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/more-categorical-thoughts-on-lawful-lenses-9dba9fb269fd">More (Categorical) Thoughts on Lawful Lenses</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[On Lawful Lenses]]></title>
            <link>https://medium.com/statebox/on-lawful-lenses-6e18a1e17bdf?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/6e18a1e17bdf</guid>
            <category><![CDATA[lenses]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[mathematics]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[category-theory]]></category>
            <dc:creator><![CDATA[Marco Perone]]></dc:creator>
            <pubDate>Wed, 16 Oct 2019 05:13:09 GMT</pubDate>
            <atom:updated>2020-04-26T15:21:45.106Z</atom:updated>
            <content:encoded><![CDATA[<h4>Some thoughts following the <a href="https://summit.statebox.org/">3rd Statebox Summit</a></h4><p>Lenses and optics in general seem to be popping up both in the functional programming and category theory community. This suggest they have an important role that is yet to be completely understood.</p><p>One thing that struck me while reading about lenses is the fact that functional programmers tend to consider only lawful lenses, while academics are interested more broadly in generic lenses. Moreover, optics laws, although very meaningful in practice, appear as something God-given and it is hard to understand where they come from. Additionally, laws are usually defined only for simple lenses, while it seems reasonable to expect that generic lenses also obey some coherence conditions.</p><p>This is why at the <a href="https://summit.statebox.org/">Statebox summit</a> I was very curious to talk to other people more skilled than me about lawful generic lenses. It turned out this was a really interesting thing to do, since it seems we now have a good idea on how to solve the above issues. I really need to thank <a href="https://twitter.com/_julesh_">Jules Hedges</a>, <a href="https://math.mit.edu/~dspivak/">David Spivak</a>, <a href="http://brendanfong.com/">Brendan Fong</a>, <a href="https://mathdept.ucr.edu/faculty/cvasil.html">Christina Vasilakopoulou</a>, <a href="https://twitter.com/elianalorch">Eliana Lorch</a>, <a href="https://whatisrt.github.io/">Andre Knispel,</a> <a href="https://www.cs.ox.ac.uk/people/stefano.gogioso/">Stefano Gogioso</a> and everyone else who was there for contributing to what follows.</p><h3><strong>Lens Recap</strong></h3><p>Let’s review briefly what a Lens is. It can be seen as a way to access and update a part of an immutable data structure S, through two functions</p><pre>data Lens S T A B = Lens<br>  { g : S -&gt; A<br>  , p : S -&gt; B -&gt; T<br>  }</pre><p>For example, we could define a lens cc : Lens (A x M) (B x M) A B defined by</p><pre>cc : Lens (A x M) (B x M) A B<br>cc = lens get put<br>  where<br>    get : A x M -&gt; A<br>    get (a, m) = a</pre><pre>    put : (A x M) -&gt; B -&gt; (B x M)<br>    put (a, m) b = (b, m)</pre><p>We will call every lens of this form a constant complement lens.</p><p>We will call a lens Simple if T = Sand B = A, that is if put does not have the ability to change types, but only to update the value of type A inside S.</p><h3><strong>Lens Laws</strong></h3><p>Traditionally the lens laws are stated for simple lenses as follows:</p><h4>getput</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dpXMkIlDS9jrw3QelkWgPw.png" /></figure><p>Here • is the function S -&gt; (S, S) that duplicates the input, and i : S -&gt; S is the identity on S.</p><p>Alternatively, we could rewrite this as p s (g s) = s .</p><h4>putget</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UwqGyjUIci7flZZ0XAApuQ.png" /></figure><p>Here, ◦ means that we are not using its argument S and i : a -&gt; a is the identity on a.</p><p>This could be rewritten as g (p s a) = a .</p><h4>putput</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*we6Oh1F8OdfS3ha7MpOvkw.png" /></figure><p>Here ◦ means that we are not using its argument a.</p><p>This could be rewritten as p (p s a) = p s .</p><p>We say that a simple lens is lawful or very well-behaved if it satisfies the three laws above.</p><h3><strong>On Lens Laws</strong></h3><p>I’ve always felt a bit bothered by the three lens laws because, though they make a lot of sense, they still feel a lot like God-given rules without a clear mathematical explanation.</p><p>Moreover, as presented above, we are able to state them only for simple lenses, and it feels pretty weird that general lenses do not need to satisfy any rule at all!</p><p>Also, lawful lenses seem to be of interest only for programmers, while in academic papers (with some exceptions such as <a href="https://arxiv.org/abs/1809.00738">this one</a>) lawful lenses don’t seem to be considered to be very interesting, and generic lenses are usually investigated instead.</p><p>Before trying to understand something more about generic lawful lenses, let’s have a look at an easier example of optics, namely adapters.</p><h3><strong>Generic Lawful Adapters</strong></h3><p>An adapter is the simplest of all optics and it encodes the fact that we can adapt data between two different formats. It is defined as</p><pre>data Adapter S T A B = Adapter<br>  { f : S -&gt; A<br>  , t : B -&gt; T<br>  }</pre><p>An adapter is said to be simple if T = S and B = A. A simple adapter is lawful if f and t are each other’s inverses, i.e. f (t a) = a and t (f s) = s for any a : A and s : S .</p><p>From this point of view, it is clear that we cannot generalise this definition for generic adapters, because we have no way of composing f and t in the generic case.</p><p>On the other hand we can easily interpret a simple adapter as follows: it enables us to adapt functions A -&gt; A to functions S -&gt; S, and vice versa, using the isomorphism provided by f and t.</p><p>But now we can try to generalize this new point of view to generic adapters: we want a generic adapter to be lawful if it gives us a way to translate functions A -&gt; B to functions S -&gt; T in an isomorphic way, meaning that we can use it to adapt functions A -&gt; B to functions S -&gt; T and vice versa. Hence, we could give the following definition:</p><blockquote>A generic adapter is lawful when both f and t are isomorphisms</blockquote><p>It is now easy to observe that this definition is equivalent to the previous one when we restrict to the simple case, so this new definition is a generalization of the traditional one.</p><h3><strong>Generalizing to Lenses</strong></h3><p>Now that we were able to state a definition for a generic lawful adapter, let’s see if we can apply this insight to other optics.</p><p>If we look at the paper <a href="https://arxiv.org/abs/1809.00738">Categories of Optics</a> by Mitchell Riley, we see that a generic optic is defined as</p><pre>data Optic S T A B = exists M . Optic<br>  { g : S -&gt; M ⊗ A<br>  , p : M ⊗ B -&gt; T<br>  }</pre><p>where ⊗ is a tensor in a symmetric monoidal category. If you don’t know what that is, don’t worry and interpret it as follows in our relevant examples.</p><ul><li>For lenses ⊗ is the product, so think to M ⊗ A as (M, A).</li><li>For prisms ⊗ is the coproduct, or sum. In this case we think to M ⊗ A as Either M A.</li><li>For adapters ⊗ is just the constant functor, so M ⊗ A is just A.</li></ul><p>We can observe that for adapters this definition coincides exactly with the one we gave above. So, we restate our new interpretation of generic lawful adapters in this new more generic setting: an adapter is lawful if both g and p are isomorphisms.</p><p>However, with this new interpretation our definition can now be expressed for any possible Optic, not only for adapters! To state it again in its full generality, we say that</p><blockquote>An optic o : Optic S T A B is lawful if g and p are isomorphisms</blockquote><p>If we now interpret this definition for lenses, where ⊗ is the product, we see that we obtain that lawful lenses are all lenses Lens S T A B where S is isomorphic to M x A and T is isomorphic to M x B. But, up to isomorphism, this is exactly the definition of constant complement lenses we introduced above!</p><p>So, to check if our interpretation makes sense, we want to prove that a simple lens is lawful (in the traditional sense, i.e. it respects the three lens laws) if and only if it is constant complement.</p><h3><strong>Lawful Lenses are a Constant Complement</strong></h3><p>It is quite easy to check that a simple constant complement lens respects the three lens laws, so we are just going to prove that a lawful lens is constant complement.</p><p>The idea of this proof came to us thanks to this hint from <a href="https://twitter.com/kmett">Edward Kmett</a>:</p><h3>Edward Kmett on Twitter</h3><p>@marcoshuttle @mstk @BartoszMilewski It is easiest to see (in tweet form) by looking at s -&amp;gt; (a -&amp;gt; s, a) as extracting the complement as an s with an a-sized hole, and the a. The fact that the former is injective (or s is uninhabited) is key to realizing this is actually just a proxy for the unnamed complement.</p><p>Let’s consider a Lens S S A A, defined by functions g : S -&gt; A and p : S -&gt; A -&gt; S, which satisfies getput, putget and putput.</p><p>To prove our claim we need to define an M such that S is isomorphic to A x M.</p><p>First off, we observe that we can collapse our functions g and p into a single function</p><pre>g&amp;p : S -&gt; (A, A -&gt; S)<br>g&amp;p s = (g s, p s)</pre><p>This is really interesting because it is already sending S into the product of A with something else, where every element of this something else is of the form p s. Hence, we could try to define</p><pre>M = { m : A -&gt; S | ∃ s : S . m = p s }</pre><p>At this point let’s try to see if we can prove that S is isomorphic to A x M. Let’s start by defining functions</p><pre>f : S -&gt; A x M<br>f s = (g s, p s)</pre><p>and</p><pre>h : A x M -&gt; S<br>h (a, m) = m a</pre><p>Next, we would like to prove that these two functions f and h are each other’s inverses.</p><p>Let’s check first that f ; h is the identity on S. We have</p><pre>(f ; h) s = p s g(s)</pre><p>which is equal to s by getput.</p><p>Finally, let’s check that h ; f is the identity on A x M.</p><pre>(h ; f) (a, m) = (g(m a), p(m a))</pre><p>By the definition of the set M, we know that m = p s for some s : S and hence</p><pre>(g(m a), p(m a)) = (g(p s a), p(p s a))</pre><p>which is actually equal to (a, p s) = (a, m) by putget and putput, respectively.</p><p>QED!</p><h3><strong>Conclusion</strong></h3><p>The fact that simple lawful lenses are constant complement lenses is folklore in the functional programming community (e.g. <a href="https://blog.jle.im/entry/lenses-products-prisms-sums.html">Lenses embody Products, Prisms embody Sums</a>), but a proof of the fact was not easy to find, so I think that writing it down could be useful for future reference.</p><p>On the other hand, a definition for a generic lawful optic seems to not be present in the literature, and I think the approach proposed above works really nicely and can help us understand the origin of lens laws.</p><p>One interesting question to tackle now would be to understand how this generic notion of lawfulness translates to the profunctor optics encoding.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6e18a1e17bdf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/on-lawful-lenses-6e18a1e17bdf">On Lawful Lenses</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Elliptic Curve Pairings]]></title>
            <link>https://medium.com/statebox/elliptic-curve-pairings-213131769fac?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/213131769fac</guid>
            <category><![CDATA[mathematics]]></category>
            <category><![CDATA[ethereum]]></category>
            <category><![CDATA[cryptocurrency]]></category>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[zksnark]]></category>
            <dc:creator><![CDATA[Joshua Fitzgerald]]></dc:creator>
            <pubDate>Sat, 31 Aug 2019 08:56:00 GMT</pubDate>
            <atom:updated>2019-08-31T08:56:00.259Z</atom:updated>
            <content:encoded><![CDATA[<p>At <a href="https://blog.statebox.org/">Statebox</a> we are exploring using boolean circuits to model computation. One thing we’d like to do is verify correct computation on a blockchain in a scalable way. A zero-knowledge proof system, like a zkSNARK, can do this. In <a href="https://blog.statebox.org/boolean-circuits-in-libsnark-facf7c23400b">my last post</a> I explained how to create a zkSNARK that verifies a boolean circuit in Libsnark.</p><p>In this post, I’d like to take a closer look at the core bit of mathematics that makes a zkSNARK work: the elliptic curve pairing.</p><h3>Introduction</h3><p>Usually in cryptography we want our encryption functions to destroy as much information as possible. The inputs to these functions should appear to be completely unrelated to their outputs — unless, of course, you know the key.</p><p>However there are situations where we might want a little bit of information about the inputs to be recoverable, but not all of it.</p><p>For instance, suppose you had an online store and you wanted to check that your customer’s password was sufficiently complex without asking the user to actually reveal their password to you. First they would encrypt their password using some encryption function. Then you would need to be able to tell from only the encrypted output that the <em>input </em>to the function satisfied some condition.</p><p>This is possible. It requires a form of encryption that doesn’t destroy <em>all</em> information about its inputs. One mathematical object used to accomplish this is an<em> elliptic curve pairing</em>.</p><h3>Elliptic Curve 101</h3><p>A lot of this information can be found elsewhere, so I’ll just give the bare necessities. An elliptic curve is a polynomial that looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/275/1*qthXPl_c7wBZ2sNl9QbSnw.png" /></figure><p>The set of points <em>(x,y) </em>that are solutions to this equation plus a “point at infinity” form a group under a special addition rule.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/703/1*nL3BMNfz4--8HENke6-hHA.png" /><figcaption>Addition on an elliptic curve</figcaption></figure><p>Two points are added on elliptic curves by drawing a line through the two points. Because the curve is degree three this line will intercept the curve in a third place. That point of intersection is then reflected over the <em>x</em>-axis. Because of the <em>y</em>-squared term on the left side the curve is symmetric over the <em>x-</em>axis and this reflected point is also on the curve. The reflected point is the sum.</p><p>The geometric method of adding points is beautiful, but not so practical. There is a function that computes the sum of two points using on a curve by using their coordinates. Thankfully, this function is a rational function which is not too hard to compute. A point can also be doubled using a similar rational function. A double-and-add algorithm makes it practical to compute arbitrary multiples of an elliptic curve point, which I will write as n*g for integer n and some elliptic curve point g.</p><p>The point at infinity serves as the identity of the group. Two elliptic curve points that lie on the same vertical line are inverses.</p><p>Since addition and doubling are computed by rational functions on the coordinates, an elliptic curve group can be created using coordinates from any field. In a cryptographic setting we would use a finite field for the coordinates. Using a finite field destroys the nice geometric method of adding points by drawing lines between points, but the rational functions that compute adding and doubling are the same.</p><h3>The Elliptic Curve Discrete Logarithm Problem</h3><p>Something that is believed to be very hard to do with elliptic curve points is to compute the elliptic curve discrete logarithm (ECDLP). Given a point g on an elliptic curve and some multiple of that point n*g, what is n?</p><p>One of the most efficient algorithms for solving ECDLP, the baby-step giant-step method, runs in time exponential on the number of digits in the order of the elliptic curve group. For large groups this problem is highly impractical to solve.</p><p>Since this is problem is difficult, we can choose a secret n and be sure that it will remain secret even if we reveal g and n*g.</p><p>Why is it called discrete logarithm? Usually this problem is expressed in multiplicative notation, where the problem becomes computing n from g and g^n, essentially computing the base-<em>g</em> logarithm of g^n.</p><h3>The Torsion Subgroup</h3><p>An <em>r-</em>torsion subgroup is a subgroup formed of all elements g for which r*g = 0. The torsion subgroups of elliptic curve groups have a predictable structure. If we say E[r]<em> </em>is the the <em>r-</em>torsion subgroup of elliptic curve group E<em>, </em>then<em> </em>E[r]<em> </em>has this structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/245/1*kOWyyXtj01juMRYsPPST6w.png" /></figure><p>The caveats are that r must be relatively prime to the degree of the field E is defined on, and we may have to pass up to an extension of that field in order to get “all” of the points in E[r].</p><h3>The Embedding Degree</h3><p>The embedding degree k is the smallest degree field extension needed to get the entire torsion subgroup E[r].</p><p>The embedding degree k, as well as r<em>, </em>have an enormous effect on the security and efficiency of an elliptic curve and its pairing.</p><h3>Elliptic Curve Pairings</h3><p>An elliptic curve pairing is a function that takes a pair of points on an elliptic curve and returns an element of some other group, called the target group. Elliptic curve pairings have this nice essential property:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/298/1*Isv9taz0JM1ku311A1N_rw.png" /></figure><p>For some g1, g2, and g3 on the curve and integers a and b.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*NGWyOOq6x2tdNdMoIPnYUQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*k--K49nrc5XUJYVZK4tePQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/527/1*3-ViHNTLrSyHgBJPaQUgfw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/527/1*OifA9T9x_FXfyJKimZQLZQ.png" /></figure><p>This is called <em>bilinearity</em> since the pairing is linear in both coordinates.</p><p>A pairing needs to have a further property, called <em>non-degeneracy. </em>For generators g1, g2:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/199/1*vtLdv59h0Q82-UKCuterJQ.png" /><figcaption>1 is the identity of the target group.</figcaption></figure><p>The groups G1 and G2 are often different subgroups of a torsion group E[r]<em>, </em>and the target group is either the <em>r</em>th roots of unity or a cyclic group isomorphic to it.</p><h3>An Attack on Elliptic Curve Cryptography</h3><p>Elliptic curve pairings were introduced by French mathematician André Weil in 1940 as a tool for solving an analogue of the Riemann Hypothesis for finite fields.</p><p>Pairings were later used as an attack on elliptic curve cryptography. A desirable property of a secure cryptosystem is that the Decisional Diffie-Hellman problem (DDH) is difficult in the underlying group. The DDH problem is this: given g, x*g, y*g, can you tell the difference between xy*g and a randomly chosen z*g? If that is difficult, the group has DDH. A group that where DDH holds can be used to hide the fact that the coefficients x, y and xy are related by multiplication.</p><p>The bilinearity property of pairings can be used to break DDH. (How? Compute e(x*g, y*g) and e(g, z*g). If they are equal, then xy = z with high probability.)</p><p>Since pairings can break DDH, a pairing can reveal that secret values are related by multiplication even though the values themselves remain secret.</p><p>Pairings are only able to show a relationship with one single multiplication. One would need a three-coordinate, <em>tri</em>linear function to reveal a relationship with two multiplications.</p><h3>How are Pairings used in zk-SNARKs?</h3><p>Pairings can reveal that secret values are related by addition and up to one multiplication.</p><p>If a statement can be transformed into a relationship with a single multiplication than it can easily be checked using a pairing. For example, suppose I want to convince you that I have an integer solution to a quadratic equation but I don’t want to reveal it. Here is an example equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/1*LHWMUn1atyf8htO7lM0tWw.png" /></figure><p>I take my root a and a pair of elliptic curve points g1 and g2. I compute a*g1 and a*g2 give you the results, along with the points g1 and g2. Because of the ECDLP I can be sure you won’t be able to compute a and my root will remain a secret.</p><p>You use a pairing and compute:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*CRXFwUJubYG-qNMWsPoY9w.png" /></figure><p>By the bilinearity property, this is equal to:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/357/1*GE2jGrCD8XuxdPTiqVzEjA.png" /></figure><p>If this is equal to 1, then a^2-2027a+16152 is equal to 0 with high probability. (The non-degeneracy condition, along with a large target group ensures this.) I have convinced you that my secret a really is a solution to the quadratic equation without ever revealing it.</p><p>In a zk-SNARK, elliptic curve pairings are used to check a system of quadratic constraints like the one above. The system of constraints is converted into a single large polynomial that has particular roots only if each of the quadratic constraints is satisfied.</p><h3>Computing a Pairing</h3><p>The best known algorithm for computing pairings is Miller’s algorithm. The algorithm is computationally expensive, as its complexity is polynomial on the order of the particular subgroup used in the pairing. For security, the order of this subgroup is very large, so the algorithm can take some time.</p><p>For this reason, efficient zero-knowledge protocols using elliptic curve pairings minimize the amount of pairing values that must be computed. The Pinocchio Protocol in <a href="https://eprint.iacr.org/2013/279.pdf">PGHR13</a> needs 11 pairing values, while <a href="https://eprint.iacr.org/2016/260.pdf">Groth16</a> needs only 3.</p><h3>Want to know more about pairings?</h3><p>The introductory sources on elliptic curve pairings on the internet are slim, but I found these helpful and illuminating:</p><p><a href="https://medium.com/u/587a00dbce51">Vitalik Buterin</a>’s blog post:<br><a href="https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627">https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627</a></p><p>Craig Costello’s<em> Pairings for Beginners:</em><br><a href="http://www.craigcostello.com.au/pairings/PairingsForBeginners.pdf">http://www.craigcostello.com.au/pairings/PairingsForBeginners.pdf</a></p><p>This talk by Dan Boneh:<br><a href="https://www.youtube.com/watch?v=8WDOpzxpnTE">https://www.youtube.com/watch?v=8WDOpzxpnTE</a></p><h3>Want to know more about Statebox?</h3><p>Check out our <a href="https://blog.statebox.org/">blog</a> or watch some of our <a href="https://statebox.org/talks/">talks</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=213131769fac" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/elliptic-curve-pairings-213131769fac">Elliptic Curve Pairings</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Boolean Circuits in Libsnark]]></title>
            <link>https://medium.com/statebox/boolean-circuits-in-libsnark-facf7c23400b?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/facf7c23400b</guid>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[cryptocurrency]]></category>
            <category><![CDATA[zero-knowledge-proofs]]></category>
            <category><![CDATA[cryptography]]></category>
            <dc:creator><![CDATA[Joshua Fitzgerald]]></dc:creator>
            <pubDate>Mon, 12 Aug 2019 10:24:21 GMT</pubDate>
            <atom:updated>2019-08-12T10:24:21.321Z</atom:updated>
            <content:encoded><![CDATA[<p>At Statebox we use category theory to model computation, where the objects of a category represent the possible states of a system and morphisms between states represent a computation taking some state to another. One natural way to express these kinds of morphisms is to use boolean circuits.</p><p>A <em>boolean circuit</em> is a function that transforms a bitstring of m bits into a bitstring of n bits. It is called a <em>circuit</em> because it can be imagined as a diagram of wires and gates, where a 1 is a wire carrying a charge and a 0 is a wire with no charge. The gates can be logical operators like OR or NAND.</p><p>Boolean circuit satisfiability is NP-complete, so any problem in NP can be expressed as a boolean circuit. Due to the PCP Theorem, any decision problem in NP has probabilistically checkable proofs that can be verified in a reasonable amount of time.</p><p>Connecting everything together, we ought to be able to construct a non-interactive zero-knowledge proof that a morphism exists between two states of a system.</p><p>Libsnark is a library for creating zkSNARKs, and it has an efficient method for constructing SNARKs from two-input boolean circuits. (Two-input boolean circuits consist of gates where each gate has exactly two inputs.) Let’s look at how we can use libsnark to create a zkSNARK for a tiny example circuit.</p><h4>An Example Circuit</h4><p>Suppose we want a boolean circuit that can test whether a three-bit number is divisible by three. The input to our circuit is a bitstring of length three while the output is a single bit. Out of eight total three-bit numbers there are only two that are divisible by three: 011 and 110. Our circuit must be able to test any three-bit number and return 1 only on 011 or 110.</p><h4>Designing the Circuit</h4><p>Both correct bitstrings have a middle bit of 1 and each has exactly two set bits. These statements completely characterize the two bitstrings we are trying to select.</p><p>If the middle bit must be 1, then there is only one set bit left for the outer bits. So one of the outer bits must be 1 and the other must be 0. We can use an XOR gate to test that the outer bits are opposites. Then all we need to do is test that the middle bit is 1. Here is a diagram of a two-input boolean circuit with two gates and five wires that accomplishes the task.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*2wDmiPrPGLdZDBa5F_Cozw.png" /><figcaption>The boolean circuit diagram, to be read top-bottom</figcaption></figure><h4>How a Boolean Circuit becomes a SNARK</h4><p>Most SNARKs are based on a Quadratic Arithmetic Program which is constructed from an arithmetic circuit. The arithmetic circuit is first written as a rank-1 constraint system (R1CS), then a special polynomial is constructed from the R1CS that has roots corresponding to each gate of the arithmetic circuit. Then it is possible to check that each gate of the arithmetic circuit is satisfied by checking that the polynomial has the expected roots.</p><p>While it is possible to convert boolean circuits into arithmetic circuits and use a quadratic arithmetic program, it is not very efficient to do so. Instead, we can use what is called a Square Span Program.</p><h4>Square Span Programs</h4><p>A Square Span Program is another system for building a SNARK that is designed to be efficient for boolean circuits. Each boolean gate is written as a linear combination of the input and output bits. For example, if a and b are bits, then 2a + 2b + 4c - 5 will be either 1 or -1 if NAND(a,b) = c. Each type of boolean gate gets one of these linear combinations that equal -1 or 1 if the gate is satisfied. Then all that needs to be checked is that(2a + 2b + 4c — 5)² = 1. This is called a Unitary Square Constraint System (USCS). It is similar to a R1CS but is much more simple for boolean circuits and produces smaller SNARKs. Libsnark can express a boolean circuit as a USCS.</p><h3>Writing Our Circuit in Libsnark</h3><p>Writing our boolean circuit in libsnark is quite simple. For each gate, we specify its left and right input wires, its output wire, its gate type, and whether or not the gate is an output of the entire circuit.</p><h4>Gate Types</h4><p>A two-input boolean gate can be represented as a truth table for its inputs and output. Here is the truth table for NAND:</p><pre>| a | b | c |<br>|---|---|---|<br>| 0 | 0 | 1 |<br>| 0 | 1 | 1 |<br>| 1 | 0 | 1 |<br>| 1 | 1 | 0 |</pre><p>The last column specifies exactly how NAND functions for each input. Since the last column is 1110, NAND is given an op code of 14. There are sixteen possible two-input boolean gates and libsnark recognizes each one.</p><h4>Circuit Output Gates</h4><p>The proof generated for a boolean circuit is a proof that each gate behaves according to its type and that <em>the outwire of any circuit output gate is 0</em>. This is the opposite of the usual intuition for circuits and will cause the circuit we designed earlier to fail verification in libsnark. We can easily fix this by changing the output gate of our circuit to its negation, so that AND becomes NAND.</p><p>Our corrected circuit:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*HxMt2GVAfBkIz4lJm7lSkA.png" /></figure><h4>Specifying our Circuit in Libsnark</h4><p>Our circuit is specified in libsnark like this:</p><pre>int main()<br>{   <br>    // Choose the field<br>    typedef libff::Fr&lt;default_tbcs_ppzksnark_pp&gt; FieldT;</pre><pre>    // Initialize public parameters<br>    default_tbcs_ppzksnark_pp::init_public_params();</pre><pre>    // Initialize the circuit<br>    tbcs_circuit div_by_3;</pre><pre>    // Set the circuit size<br>    div_by_3.primary_input_size = 0;     // number of PUBLIC inputs<br>    div_by_3.auxiliary_input_size = 3;   // number of PRIVATE inputs</pre><pre>    tbcs_gate g1;<br>    tbcs_gate g2;</pre><pre>    g1.left_wire = 1;<br>    g1.right_wire = 3;<br>    g1.type = tbcs_gate_type(6);      // XOR<br>    g1.output = 4;<br>    g1.is_circuit_output = false;</pre><pre>    g2.left_wire = 4;<br>    g2.right_wire = 2;<br>    g2.type = tbcs_gate_type(14);     // NAND<br>    g2.output = 5;<br>    g2.is_circuit_output = true;</pre><pre>    div_by_3.add_gate(g1);                   <br>    div_by_3.add_gate(g2);</pre><h4>Valid Circuits</h4><p>For a circuit to be considered valid by libsnark, the output wire of each gate must be exactly one more than the number of previous wires already specified. Also, the left and right input wires must each be less than the output wire.</p><p>Libsnark provides a constant wire (wire 0), so the first input wire is wire 1.</p><h4>Specifying an Assignment</h4><p>An assignment to our circuit is a vector of bits, with one bit for each wire (including the internal wires). Here is a correct assignment showing 110 (six) is divisible by three:</p><pre>vector&lt;bool&gt; assgn_six = {1,1,0,1,0};</pre><p>Note that the last wire needs to be 0 because we marked the last gate as a circuit output.</p><h4>Create the Proving and Verifying Keys (Trusted Setup)</h4><pre>const tbcs_ppzksnark_keypair&lt;default_tbcs_ppzksnark_pp&gt; keypair =<br>   tbcs_ppzksnark_generator&lt;default_tbcs_ppzksnark_pp&gt;(div_by_3);</pre><h4>Make an Assignment to the Circuit</h4><pre>// public input is empty                               tbcs_primary_input pi = {};</pre><pre>// private input<br>tbcs_auxiliary_input ai = assgn_six;</pre><h4>Generate a Proof</h4><pre>tbcs_ppzksnark_proof&lt;default_tbcs_ppzksnark_pp&gt; proof = tbcs_ppzksnark_prover&lt;default_tbcs_ppzksnark_pp&gt;(keypair.pk, pi, ai);</pre><h4>Verify the Proof</h4><pre>bool verified = tbcs_ppzksnark_verifier_strong_IC&lt;default_tbcs_ppzksnark_pp&gt;<br>(keypair.vk, pi, proof);</pre><p>Thank you to <a href="https://medium.com/u/eae2a5f8f8b2">Christian Lundkvist</a> and <a href="https://medium.com/u/3ab5f29d1ec">Howard Wu</a> for their helpful libsnark tutorials on which this code is based.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=facf7c23400b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/boolean-circuits-in-libsnark-facf7c23400b">Boolean Circuits in Libsnark</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Note on Mechanised Governance]]></title>
            <link>https://medium.com/statebox/note-on-mechanised-governance-4a96708514e7?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/4a96708514e7</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[ethereum]]></category>
            <dc:creator><![CDATA[wires]]></dc:creator>
            <pubDate>Thu, 08 Aug 2019 12:26:49 GMT</pubDate>
            <atom:updated>2019-08-08T12:28:53.751Z</atom:updated>
            <content:encoded><![CDATA[<h4>Some thoughts regarding governance, simulations, semantics and complexity</h4><blockquote>Disclaimer: Before you roast me, this post is not meant to judge any person or organisation and what they did or did not do. In particular, I have nothing against ETH, ETC, the DAO team or the hacker. All of them did and are doing incredibly useful things.</blockquote><p>There are ongoing online discussions regarding “blockchain governance”. I want to add a few cents to this, from the point of view of someone understanding a thing or two about foundations of mathematics and security engineering.</p><p>For some context regarding the governance discussion, check:</p><p>- The blogpost “<a href="https://medium.com/cryptolawreview/against-szabos-law-for-a-new-crypto-legal-system-d00d0f3d3827">Against Szabo’s law</a>”<br>- A response “<a href="https://medium.com/coinmonks/in-defense-of-szabos-law-for-a-mostly-non-legal-crypto-system-8f1ce2b364a6">In Defense of Szabo’s Law</a>”<br>- This <a href="https://twitter.com/hudsonjameson/status/1158130400717410305">recent twitter thread</a> which made me write this</p><p>What is the point of Szabo’s law / ethos?</p><p>&gt; Zamfir: “Do not implement changes to the blockchain protocol unless the changes are required for the purpose of technical maintenance.”</p><p>&gt; Shapiro: Szabo’s ethos: a “social trust minimisation approach”</p><h3>Code is Law</h3><p>Before we dive into that, let’s talk about <em>“code is law”</em><strong>. </strong>This notion refers to smart contracts and suggests that “the law” is not coming from what is written down in a natural language contract and the lawyers and court’s interpretation of it, but instead a “smart contract” blindly and mechanically executes its code and nobody can do anything about it. Because the code is public and because the execution is deterministic*, you know exactly what kind of contract you are interacting with. (*same input, same behaviour)</p><p>So the most important aspect of *code is law* is that -but hold on- it makes it unambiguous how the contract should be interpreted, unlike the natural language version of a contract.</p><p><em>At this stage, we need to understand the code that creates the ‘simulation’, namely the runtime, the smart contract host, (for example the Bitcoin or Ethereum daemons).</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*z-RmY5zaFdCwQ7jbwJYyHg.png" /></figure><p>The runtime in principle does not distinguish between smart contracts, they are all on equal footing. So you could write a very simple, safe contract, or you could have a very complicated, buggy contract. The runtime does not care and just executes the code as is.</p><p><strong>In order to understand unambiguously what a SC does, you need to understand exactly what the machine does AND what the smart contract tells the machine to do. </strong>The instructions in the smart contract are a form of “machine code” running on a virtualised process, called a virtual machine. (EVM, Ethereum virtual machine in ETH case).</p><blockquote>Roughly, we call the machine code in smart contracts ‘syntax’ and the behaviour or meaning that we expect the “semantics”.</blockquote><p>There are two ways to describe the semantics of this virtual machine precisely:</p><p>- <strong>operationally</strong>, or a step-by-step description. If you see instruction A and you are in state X, then go to state Y and change the memory at location…</p><p>The nice part of operational semantics is that it is very close to how the machine actually operates. For example, here you see this in action; it’s how a Turing machine works / is described:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FE3keLeMwfHY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DE3keLeMwfHY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FE3keLeMwfHY%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f54acd1407ebc97fa8758107f4ab37e/href">https://medium.com/media/8f54acd1407ebc97fa8758107f4ab37e/href</a></iframe><p>The not so nice part is that it is very difficult to understand what it’s happening if you zoom out from the local view, to the effect of the entire calculation. For instance, in the video it is not exactly clear right away that all the erasing and writing ones and zeros is actually adding or counting, etc.</p><p>- the other way of describing semantics is <strong>denotational</strong>.</p><p>Here, instead of giving the step by step instructions, you show that your syntax is just another way of speaking about a specific mathematical structure. Without going into too much detail (could be a whole blog series), the point here is that <strong>you can use existing theories about this structure to reason about the “global” behaviour</strong>.</p><blockquote>I am mentioning this to show you that even though it is exactly known for each input what the contract does, depending on the complexity of the virtual machine it may still be impossible for a human, or even a computer to reason about all possible things that can happen with the contract.</blockquote><p>Mathematics may look complicated, but it is really mainly formed to be easy to reason about. You just look at the transition table of a Turing machine, and you see each step. Easy to understand what this does! But you cannot create a conjecture about all possible ways it can run, let alone proof that conjecture easily, except for some very special situations.</p><p>In fact, a famous theorem states that a universal Turning machine (a TM that can simulate any other Turing machine, having this property in a VM or programming language is called Turing completeness) is that there are programs for which there does not exist an algorithm that can decide if the program will terminate or not.</p><blockquote>Very concretely, this means that you could construct a transaction for a blockchain and all the nodes in the network would never finish processing the transaction and there is no way to detect this before you start working.</blockquote><p>This is one of the reasons Ethereum has Gas (which I am going to call fuel). If you are out of fuel, the computation stops. So trivially the EVM is not Turing complete.</p><p>But this still does not help with making reasoning about SC behaviour any easier. You can also read this as more generally: **if you have Turing completeness, it becomes impossible to exclude unwanted behaviour automatically in all cases.**</p><p>This is why I have always argued against Turing completeness in the EVM and why I argue for formal semantics. It is an easy way out to take a TM and restrict it with fuel. But I want to be able to reason in the large about the behaviour of smart contracts.</p><h3>Back to Governance</h3><p>There is another very (in)famous example of governance in action, <em>“the DAO fork”</em>, probably better called the “DAO bailout”.</p><p>Let’s quickly summarise what happened there.</p><p>A particular smart contract running on the Ethereum blockchain (the DAO contract) was implemented in a rather complicated way and it turned out that there was some <em>‘emergent behaviour’</em> that was not exactly clear from the code immediately. In fact, it was even pointed out to the smart contract developers that their code was very complicated and might have bugs, but they brushed it off with “we don’t see any bugs with it, so it’s probably fine”. But it was not and had a critical security flaw which was eventually exploited by someone.</p><p>This is where the friction starts.</p><p>If “code was law”, then the DAO contract (which anyone was free to “sign into”) said in a not-immediately-obvious way that anyone could take all the money if they followed a very specific protocol.</p><blockquote>Anyone with some security training (either offensive or defensive) knows that large complicated codebases are a Bad Thing(tm).</blockquote><p>Would you sign a huge contract written in legalspeak where all pages refer back and forth to conditions in other pages etc, and on top of that you barely understand the legalspeak in the first place (machine code/solidity), let alone the implications of the laws holding particular jurisdiction this ‘legal code’ applies to? (the EVM semantics) **You probably won’t, because you don’t want to get into deep trouble signing something you don’t understand.**</p><p>Furthermore, if you are the organisation that is handing out the contracts (DAO), and you decide to write the legalese yourself instead of hiring expensive/experienced lawyers (~ someone that formalizes your contract first using paper math and then on a computer, ie. <a href="https://statebox.org/">us</a>) and then it turns out your amateur contract has some very bad unintended side effects and the signing party uses those to their benefit, well, … who’s at fault here?</p><p>Now, clearly with a paper contract, you can say: “Hey wait, you are interpreting this text wrong, I didn’t mean that”. And this is what expensive lawyers and courts are for, to figure out who is wrong.</p><p>Even so, in the DAO case, are you really sure the SC behaviour used by the “attacker” was unintentional? Crazy suggestion, you say? Consider this:</p><p>- structural issues about the security process and code base were pointed out to the team before attack was engaged, the team brushed this off<br>- imagine you are the only person in a team trying to point out there is a security issue or the approach is wrong and they laugh you repeatedly; you could turn around and exploit it at some point, so you silence yourself and instead say: “yeah let’s keep hacking on this reentrant code, looks good to me”<br>- at that time not many people would have the background to understand reentrancy bugs in EVM, likely the attacker had some stash ETH (if he/she didn’t, you’d probably attack straight away)<br>- so maybe the DAO was the ETH biggest scam so far?</p><p>FWIW, I really don’t think this happened, but I just want to point out the possibility and how non-obvious the intended behaviour was.</p><p>You might also say that clearly everyone that was investing into the DAO wanted it not to get hacked, the terms &amp; conditions of the investment contract clearly gave a different impression about the behaviour of the code.</p><p>But this is the point, you DO-NOT-WANT to have a piece of natural language text that says what the code _should_ do and if later it turns out there are discrepancies, you just resolve that in court instead (as a form of governance).</p><p>Firstly, this problem already exists in the non-decentralised software world.<br><em>It is very inefficient and expensive to go from imprecise specification to precise code.</em> As the programmers have to turn the spec into code, usually they discover incomplete specifications, inconsistencies or plain impossibilities. So they need to give feedback to the spec author, which then updates specs, etc. very time consuming and waterfall vs agile is exactly about making this iteration loop as fast as possible.</p><h4>So how was this DAO situation resolved?</h4><p>Let’s call the runtime ‘the simulation’, because as far as a smart contract is concerned this is all it sees and all interactions come from this environment. Zooming out, we see it’s simulations (formalised “virtual” worlds) all the way down:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZIwmkybc7wndO1lJ888r8g.png" /></figure><p>If we then look at the user-defined ones, we can distinguish different levels of ambiguity in those contracts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e08M0fvEbhwX-73LKgjejg.png" /></figure><p>The green box represents the simplest contracts that have very limited functionality and for which you can (and have) proof that there is no other behaviour *at all* possible than what is in the contract. I call this closed, because it assumes a “closed universe”, every possible thing that can happen in *The Simulation* is considered in the security proof, interaction with other contracts, but also all things in ‘The Real World’, etc.</p><p>You can also have (yellow) very simple contracts that are fully understood, but because they interact in a more complicated way with the rest of the simulation, we cannot include everything in the security proof, so it is maybe possible that some undescribed and unconsidered outside mechanism breaks the contract. But you are still following the rules of the simulation.</p><p>Then there is the Turing complete contract, where nobody bothers really to proof anything; and a fancy website, flimsy white-paper and pseudo rigorous arguing should be enough to convince some people to sign the contract. IMHO* all hope is lost.</p><p>What the Ethereum Foundation did was what I’d call *governance at the simulation level*. Some “hand of a (pretending) God” decided to change the rules of the simulation, to take a very specific smart contract and bail them out.</p><p>*This violated Szabo’s law directly**. What is now called Ethereum classic is the chain that kept running the unmodified simulation code, the ETH chain is the one that runs exceptional code that gives the funds back to the DAO contract, ie. the one where governance changes the rules of the universe.</p><h3>Conclusion</h3><p>A different reading of Szabo’s law could be something like this.</p><p>In general, less code = fewer opportunities for bugs or emergent behaviour.</p><p>But that is not all, as in algebraic methods, we seek to have well behaved, very restricted systems that have nice properties and are “reasonable” (= able to reason mathematically about it).</p><p>A small amount of code does not imply that, per se. For instance, in a few lines of code one can write a Turing complete virtual machine, the extreme case where we have a proof that there are unreasonable programs (halting problem).</p><p>Or in the other direction, **at Statebox we spend a nearly-insane amount of effort on avoiding Turing completeness, exactly for this reason**, but with a tiny addition (`AND NOT IS ZERO`) to a single if statement, we would gain the ability to simulate a Turing machine.</p><p>If you are a programmer and you don’t have an understanding of these subtle issues, you’d think, what’s the problem, a single line change and it does not make the semantics really any more complicated. Well, <strong>operationally speaking it doesn’t, but denotationally we are looking at a very different beast suddenly.</strong></p><h4>Some examples</h4><p>Many great examples of hacks or exploits that use this fact are around. For instance, people playing Super Mario in Starcraft.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bEcY-u4yA8UqjCuCCiV2zw.png" /></figure><p>(screenshots from RECON-BRX2018 talk “<a href="https://recon.cx/2018/brussels/resources/slides/RECON-BRX-2018-Starcraft-Emulating-a-buffer-overflow-for-fun-and-profit.pdf">Starcraft, emulating a buffer overflow for fun and profit</a>”)</p><p>This is not supposed to be possible, Starcraft maps are Starcraft maps and the game should reject illegal maps. but the Super Mario map is legal, it just exploits the fact that it can simulate ANY kind of program. once the Turing machine is found, you can build tools on top to work in the *new simulation*:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZAZvoCgqYTf2VmtQ7-S3_g.png" /></figure><p>This is more or less how such “privilege escalation” exploits usually work.</p><p>Furthermore, legal governance is something that *itself* is a contract, namely the ‘real world laws’.</p><p>So you want to move this up into the smart contract world, and not apply it to the simulation. Doing this at the simulation level is similar to backdoor-ing crypto.</p><blockquote>If we cannot rely on the precise behaviour of the simulation and the smart contracts, then we cannot rely on our proofs anymore and we can NEVER build a fully secure system.</blockquote><p>If *instead* we say code is the law, there is no bailout/undo unless you build it in, then we have something to rely on. This also immediately implies that you only want to have _the utmost max A-grade level security_ for smart contracts, similar to when you launch a satellite. Because you cannot easily go up into space and press the reset button, the effort is put upfront because the software MUST NEVER fail, precisely because there is no undo button or big brother that you can go to to bail you out of your own mistake.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a96708514e7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/note-on-mechanised-governance-4a96708514e7">Note on Mechanised Governance</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Programming Languages as Categories]]></title>
            <link>https://medium.com/statebox/programming-is-just-an-example-6bc6bacb7b72?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/6bc6bacb7b72</guid>
            <category><![CDATA[dependent-types]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[idris]]></category>
            <category><![CDATA[type-theory]]></category>
            <category><![CDATA[category-theory]]></category>
            <dc:creator><![CDATA[Marco Perone]]></dc:creator>
            <pubDate>Mon, 29 Apr 2019 09:38:23 GMT</pubDate>
            <atom:updated>2019-04-30T17:42:21.711Z</atom:updated>
            <content:encoded><![CDATA[<p>In <a href="https://blog.statebox.org/fun-with-categories-70c64649b8e0">our</a> <a href="https://blog.statebox.org/concrete-categories-af444d5f055e">previous</a> <a href="https://blog.statebox.org/fun-with-functors-95e4e8d60d87">posts</a> we explored how to work with categories and functors in Idris, providing definitions that encode all the required properties and laws.</p><p>You actually hear a lot of talking about functors in the context of functional programming. Together with other derived concepts such as applicatives and monads, functors are one of the basic abstractions used to structure the flow of programs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/436/1*LVFITr_4cfi59iT6SOHTwQ.png" /><figcaption>Functors are one of the main abstractions to structure applications in functional programming.</figcaption></figure><p>In this post we will explore in detail <em>the link between general category theory and functional programming</em>, showing that the latter is just one example of the former.</p><p>Make sure to read it all until the end, where a little surprise is waiting for you.</p><blockquote>Simply put, the main reason why category theory is so relevant for programming is that, in a certain sense, any programming language can be seen as a category.</blockquote><p>This is quite a bold statement and in fact it is not one hundred percent true, but there is a lot of truth behind it, so let’s try to make it more precise.</p><p>To obtain a category from a given programming language we need to choose carefully which are the objects and which are the morphisms.</p><p>The objects will always be the types available in the type system of the language. They could be native types, like int or string, or more abstract types like (list int, string -&gt; int). It’s important to note that in a dynamic language, where changing the type of values is allowed, there is only one big type which contains every possible value. On the other hand, in a statically typed language with a very expressive type system we can have a lot of objects in our category. This is why the categorical approach makes much more sense in strongly typed languages.</p><p>So, types are objects in our programming language category, but what are morphisms, then? Well, morphisms are the so-called pure functions, that is, functions which are <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a> as expressions. This excludes from being a morphism all the (so-called) functions which have side effects (e.g. throw exceptions, make network calls, generate random numbers, …) or which rely on some external state. Therefore in procedural languages many functions which we are used to write can not be taken into account as morphisms of our category.</p><p>Luckily enough, there are programming languages where we don’t have the possibility of writing impure functions, and in such a case every possible function corresponds to a morphism in the category.</p><h3><strong>Idris as a category</strong></h3><p>In Idris, thanks to dependent types, we have the possibility of encoding the above described category, specialized for the Idris programming language, in Idris itself! Let’s see how we can do it in practice, defining a Category made with Idris types and functions.</p><p>We said that objects of our category are types, so the type of our objects will just be Type.</p><p>If you recall, the signature of the record field mor which describes morphisms of a category is obj -&gt; obj -&gt; Type, where obj is the type of objects. So in our case we have Type -&gt; Type -&gt; Type; as we said above this needs to encode all the functions between two types, so it will be practically defined as</p><pre>TypeMorphism : Type -&gt; Type -&gt; Type<br>TypeMorphism a b = a -&gt; b</pre><p>Our category is slowly shaping itself, now we need to define identities and composition, but that’s almost trivial, since we are talking about functions</p><pre>identity : (a : Type) -&gt; TypeMorphism a a<br>identity a = id</pre><pre>compose :<br>     (a, b, c : Type)<br>  -&gt; (f : TypeMorphism a b)<br>  -&gt; (g : TypeMorphism b c)<br>  -&gt; TypeMorphism a c<br>compose a b c f g = g . f</pre><p>As one could expect, identities and composition of the category are just identity functions and function composition.</p><p>The axioms for being a category, left and right identity and associativity, are at this point trivial and they can all be implemented as Refl.</p><p>Summing up, we can formally define our category as follows</p><pre>typesAsCategory : Category<br>typesAsCategory = MkCategory<br>  Type<br>  TypeMorphism<br>  identity<br>  compose<br>  (\a, b, f =&gt; Refl)<br>  (\a, b, f =&gt; Refl)<br>  (\a, b, c, d, f, g, h =&gt; Refl)</pre><h3><strong>Functors are functors (part 1)</strong></h3><p>As soon as we have a category, our instinct should be that of immediately looking for what functors are in that category. For the above category the answer is that functors are, well, functors.</p><p>In Idris we already have a concept of functor, which looks as follows</p><pre>interface Functor (f : Type -&gt; Type) where<br>  map : (func : a -&gt; b) -&gt; f a -&gt; f b</pre><pre>interface Functor f =&gt; VerifiedFunctor (f : Type -&gt; Type) where<br>  functorIdentity : {a : Type}<br>                 -&gt; (g : a -&gt; a)<br>                 -&gt; ((v : a) -&gt; g v = v)<br>                 -&gt; (x : f a)<br>                 -&gt; map g x = x<br>  functorComposition : {a : Type}<br>                    -&gt; {b : Type}<br>                    -&gt; (x : f a)<br>                    -&gt; (g1 : a -&gt; b)<br>                    -&gt; (g2 : b -&gt; c)<br>                    -&gt; map (g2 . g1) x = (map g2 . map g1) x</pre><p>We would like to prove that an Idris VerifiedFunctor can be seen as a CFunctor as we defined it, so we would like to implement a function with the following signature</p><pre>functorToCFunctor :<br>     VerifiedFunctor f<br>  -&gt; CFunctor typesAsCategory typesAsCategory<br>functorToCFunctor {f} func = ?cFunc</pre><p>The first bits of the implementation are pretty straightforward</p><pre>functorOnMorphisms :<br>     VerifiedFunctor f<br>  -&gt; (a, b : Type)<br>  -&gt; TypeMorphism a b<br>  -&gt; TypeMorphism (f a) (f b)<br>functorOnMorphisms _ _ _ (MkTypeMorphism g) =<br>  MkTypeMorphism (map g)</pre><pre>functorToCFunctor {f} func = MkCFunctor<br>  f<br>  (functorOnMorphisms func)<br>  ?funcPreserveId<br>  ?funcPreserveComp</pre><p>As you could probably guess, we use f itself to map objects and the map function provided to us by the Functor instance, to map the morphisms.</p><p>Now we are left to show that our definition of functor is lawful, that is, it respects identities and composition. But, as a matter of fact, with our current definitions this is actually not possible; in the next paragraph we’ll explain why and we’ll adapt things to solve the issue.</p><h3><strong>Intensional and extensional equality</strong></h3><p>If you try to prove that our functor preserves identity, you’ll find yourself at the point where you need to provide evidence that id : f a -&gt; f a and (map id) : f a -&gt; f a are the same function. It turns out that equality between functions is quite a complicated subject; the main question is: <em>when do we say that two functions are equal</em>?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1goKrR3BWilVwngz9DireQ.jpeg" /><figcaption>Pure function can be thought as boxes. Are two boxes equal based on their exterior or their content?</figcaption></figure><p>From a mathematical standpoint, if we look at functions as relations, it makes sense to say that two functions f, g : a -&gt; b are equal whenever, for any element x : a, we have f x = g x. This definition of equality is called <a href="https://en.wikipedia.org/wiki/Extensionality">extensional</a> and it observes only the external behaviour of functions.</p><p>From a computational point of view, instead, it may make sense to have a more strict criterion to differentiate between functions. For example, if we consider the functions \x =&gt; 2 * x and \x =&gt; x + x defined on the natural numbers, do we want to always consider them as the same function? Or, if we consider several different sorting algorithms implementations, do we want to consider them equal as functions?</p><p>For a machine it is definitely easier to check whether the abstract syntax trees used to define two functions are equal, but it could turn out very hard to understand whether two functions are extensionally equal, because it would have to compute the functions for every possible value. Therefore <em>in programming the default form of equality between functions, called intensional, concerns the equality of internal definitions.</em></p><p>Coming back to our functor definition, we can now spot where the problem is. Our definition of equality between functions uses intensional equality, while the VerifiedFunctor interface is using extensional equality. Since intensional equality is more fine-grained that the extensional one, we can not hope to adapt the VerifiedFunctor interface to our definition. We will need to slightly change our definitions to use extensional equality.</p><p>What we need to do is change our definition of morphisms, so that we can assert that extensional equality holds</p><pre>record ExtensionalTypeMorphism (a : Type) (b : Type) where<br>  constructor MkExtensionalTypeMorphism<br>  func : a -&gt; b</pre><pre>postulate<br>funExt :<br>     {f, g : ExtensionalTypeMorphism a b}<br>  -&gt; ((x : a) -&gt; func f x = func g x)<br>  -&gt; f = g</pre><p>We wrap functions in a new type ExtensionalTypeMorphism and we postulate that two elements of this type are equal whenever we have a proof of the extensional equality of the inner functions. This corresponds to quotienting the TypeMorphism type with respect to the equivalence relation given by extensional equality. Moreover, we can use this new type for defining morphisms of a new category which we will call typesAsCategoryExtensional.</p><h3><strong>Functors are functors (part 2)</strong></h3><p>We can now come back to prove that VerifiedFunctors can be seen as CFunctors. Let’s resume from where we left off, adjusting things with our newly introduced ExtensionalTypeMorphism and typesAsCategoryExtensional.</p><pre>functorToCFunctor :<br>     VerifiedFunctor f<br>  -&gt; CFunctor typesAsCategoryExtensional    <br>              typesAsCategoryExtensional<br>functorToCFunctor {f} func = MkCFunctor<br>  f<br>  (functorOnMorphisms func)<br>  ?funcPreserveId<br>  ?funcPreserveComp</pre><p>We can now use our postulate funExt to complete the missing pieces</p><pre>functorPreserveId :<br>     (func : VerifiedFunctor f)<br>  -&gt; (a : Type)<br>  -&gt; functorOnMorphisms func a a (extIdentity a)<br>   = extIdentity (f a)<br>functorPreserveId _ a =<br>  funExt (\x =&gt; functorIdentity {a} id (\v =&gt; Refl) x)</pre><p>Here we use the functorIdentity field of the VerifiedFunctor interface, which gives us the extensional equality between id : f a -&gt; f a and (map id) : f a -&gt; f a. Using funExt we can transform the extensional equality into a concrete equality and complete the proof.</p><p>Similarly, we can prove that an Idris functor respects function composition according to our definition.</p><pre>functorPreserveCompose :<br>     (func : VerifiedFunctor f)<br>  -&gt; (a, b, c : Type)<br>  -&gt; (g : ExtensionalTypeMorphism a b)<br>  -&gt; (h : ExtensionalTypeMorphism b c)<br>  -&gt; functorOnMorphisms func a c (extCompose a b c g h)<br>   = extCompose (f a) (f b) (f c) (functorOnMorphisms func a b g)  <br>                                  (functorOnMorphisms func b c h)<br>functorPreserveCompose<br>  func _ _ _<br>  (MkExtensionalTypeMorphism g’)<br>  (MkExtensionalTypeMorphism h’)<br>  = funExt (\x =&gt; functorComposition x g’ h’)</pre><h3><strong>Conclusion</strong></h3><p>Today we saw how types and functions of a programming language, Idris in our case, can be interpreted as a category. Moreover, we proved that the concept of functor commonly used in functional programming correspond exactly to functors from a categorical point of view. This implies that we can use concepts from category theory, reason with them in their very abstract setting, and then apply what we found out to our software. Or, from another point of view, we can try to write our software thinking just in terms of categories, so that we know that our code can be used not only to talk about programming languages, but has a broader scope and application.</p><p>I promised a little surprise at the beginning, so here it is: we released open source <a href="https://github.com/statebox/idris-ct">our category theory library</a>! You can have a look at the parts of the code which I didn’t have the time and space to investigate in this series of blog posts. It would be really awesome if you could provide us with some feedback on it and, if you will, maybe contribute with a new category or some other concept we haven’t defined yet.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6bc6bacb7b72" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/programming-is-just-an-example-6bc6bacb7b72">Programming Languages as Categories</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s the Deal with Statebox, Anyway?]]></title>
            <link>https://medium.com/statebox/whats-the-deal-with-statebox-anyway-517e3df727fd?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/517e3df727fd</guid>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[emi]]></dc:creator>
            <pubDate>Tue, 16 Apr 2019 14:43:04 GMT</pubDate>
            <atom:updated>2022-11-01T10:56:44.570Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*2guPIT6D0M_95G9I1724Bw.jpeg" /></figure><p>Trying to solve the same problems using the same tools over and over again and expecting to repeatedly get different and successful results is indeed pure insanity.</p><p>It is by no means an exaggeration to think that we are entrenched in and debilitated by the same patterns of action that formed our personal and professional selves. Whether we like it or not, we, as social animals, belong to certain cultures, (whether it is the Google culture or the Rust community or whichever nation state you’re from) and it’s only human that we appropriate thoughts and behaviours from those groups. I invite you to take a step back and try to analyze things from a different perspective.</p><p>In dealing with complex systems, (and we are dealing with complex systems on a daily basis; we are, as a matter of fact, immersed in one) it is imperative that we explore novel approaches. I understand that you feel very strongly about your <em>insert imperative programming language here</em>, because it gets things done and it’s good enough for what it is that you are doing, even though you spend x amount of hours trying to fix bugs, making your fellow devs understand what you were trying to do or even to understand yourself what you wrote a week ago. I also understand that you dismiss visual languages because that one time 2 years ago you played with a version of <em>insert visual language name here </em>and it sucked because of the UI, etc. But in order to understand what Statebox is about you need to get out of your comfort zone and be willing to embrace a change of perspective.</p><p><strong>For Statebox to come into existence, that change of perspective needed to happen</strong>. The idea of using Petri nets and category theory in an intertwined manner does not come naturally, to say the least. It is, in a sense, an unprecedented way of thinking and solving problems — which turns out to be more efficient than anything else out there. And it helps immensely with the increasing complexity of systems. Statebox is actually built for that!</p><h3>Moving fast and breaking things simply doesn’t cut it anymore</h3><p>Nowadays, companies tend to pitch their business models of siloed and quasi innovative problem-solving technology. The whole idea of specialization and offering solutions to particular problems has been haunting us since the time of Adam Smith. Somehow, people seem to forget that<strong> no problem arises in isolation</strong>. Do we even consider anymore that for a particular problem to come into existence, a complex web of context dependent actions need to happen? And what is the point, may I ask, of solving those problems if they will keep happening, since the source that is causing them has not been addressed? The same way we feed pesticide infested food to millions of people who end up developing health problems from it (not to mention the ecological disaster caused by growing monocrops), then develop and capitalize on medicine that treats those same health problems, <em>the approach to writing code seems to be just as flawed</em>. Badly written code can have deep societal consequences, as well. If someone can change the course of this, it is the developers themselves.</p><h3>A case for bottom-up formal verification</h3><p>To illustrate, let’s take the over-referenced example of the DAO hack. We know what went wrong with it, but somehow, after all these years, typed languages are still not used to write smart contracts. Devs are still hammering away using the usual untyped tools, while other companies come into existence promising quick fixes to patch up what goes wrong with said method. And while operational semantics and model checking serve their purpose in the current ecosystem, there is a better way. We believe using formal tools to begin with is the way to go.</p><p><strong>Bottom-up formal verification uses category theory and type theory</strong>. It creates a solid, verified foundation on which other layers can be built. This approach is very general and reusable. And while in the beginning it is abstract and limited in functionality, it proves extremely advantageous in the long run.</p><p>This is in contrast with the usual approach to formal verification, which consists in taking a piece of software, formalizing its operational semantics using an environment like Coq, and making sure that everything is correct. The top-down approach is particularly weak to scaling, since it allows the codebase to grow in any direction, often in an unprincipled way. It’s not a mystery that producing formally verified code in this way is a very slow and expensive process.</p><p>On the contrary, relying on a strong type-system — such as those with dependent types — allows to prove properties of the software bottom-up, as the developing goes. In this setting, developing is slower, but after a given “module” has been completed its behavior will be completely known, and we will be able to <em>compositionally</em> plug in into a bigger structure.</p><h3>The beauty of category theory</h3><p>This is the beauty of category theory: it allows you to build sound, verifiable code out of little pieces of code. <a href="https://blog.statebox.org/modularity-vs-compositionality-a-history-of-misunderstandings-be0150033568">Statebox has built-in compositionality</a> both within its code (which is verified bottom-up) and within its paradigm (programming with Statebox ensures a compositional bottom-up approach to verification). Moreover, since programming with Statebox is visual, it offers what is probably the easiest way to produce verified software on the market.</p><p>If you are interested in functional programming and category theory, do check out our other Medium posts and the resources on our <a href="https://statebox.org/">website</a>.</p><h4>Update</h4><p>The first business application of the Statebox language is being developed on <a href="https://process.io/">process.io</a>. Sign up for a beta trial now!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=517e3df727fd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/whats-the-deal-with-statebox-anyway-517e3df727fd">What’s the Deal with Statebox, Anyway?</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fun with functors]]></title>
            <link>https://medium.com/statebox/fun-with-functors-95e4e8d60d87?source=rss----63b470e13211---4</link>
            <guid isPermaLink="false">https://medium.com/p/95e4e8d60d87</guid>
            <category><![CDATA[idris]]></category>
            <category><![CDATA[category-theory]]></category>
            <category><![CDATA[type-theory]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[dependent-types]]></category>
            <dc:creator><![CDATA[Marco Perone]]></dc:creator>
            <pubDate>Fri, 22 Mar 2019 13:15:39 GMT</pubDate>
            <atom:updated>2019-03-22T17:17:53.085Z</atom:updated>
            <content:encoded><![CDATA[<h3>Fun with Functors</h3><p>In our <a href="https://blog.statebox.org/concrete-categories-af444d5f055e">last post</a> we provided some examples of categories which show how, with our newly defined concept of category, we can generalize a lot of already well known mathematical structures.</p><p>We understood how a category gives us a context where we can talk about <em>composition</em>, being assured that the desired properties as identity and associativity hold. But sometimes, we would like to be able to jump from one context to another, making connections between the two. But what does this mean? When is a connection between two contexts meaningful? The answer a category theorist could give is that a connection between two contexts is meaningful when the invariants present in our starting context are preserved by the connection itself.</p><p>In the world of category theory, these <em>connections</em> are represented by <strong>functors</strong>, which provide ways to go from one category to another respecting the categorical structure.</p><h3><strong>What is a functor</strong></h3><p>Simply stated, a functor is a mapping between categories which preserves their structure, but let us see what this means in all its details.</p><p>First thing, a functor goes between two categories, which we will call cat1 and cat2, and we can start defining it in Idris as</p><pre>record Functor (cat1 : Category) (cat2 : Category) where</pre><p>Now we want to define how our functor acts on cat1. Remember that a category is composed by objects and morphisms, so we will need to define how Functor acts on both. Let us start with objects:</p><pre>mapObj : obj cat1 -&gt; obj cat2</pre><p>We simply have a function, which we call mapObj, which provides a way to map objects of cat1 into objects of cat2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*5kxQKUsKZlVM-B3y1ZBuZg.png" /><figcaption><a href="http://yannesposito.com/Scratch/fr/blog/Category-Theory-Presentation/">http://yannesposito.com/Scratch/fr/blog/Category-Theory-Presentation/</a></figcaption></figure><p>For morphisms, we don’t want to have just a function that maps a morphism of cat1 to a generic morphism of cat1, but we want to impose some coherence conditions on the source and the target of the mapped morphism. This amounts to say that, if we have a morphism a -&gt; b in cat1, then we would like to map it to a morphism mapObj a -&gt; mapObj b, respecting the action of mapObj on the objects of cat1.</p><pre>mapMor : (a, b : obj cat1)<br>      -&gt; mor cat1 a b<br>      -&gt; mor cat2 (mapObj a) (mapObj b)</pre><p>To make this explicit we add to our Functor record a mapMor function which tells how, for any two objects a and b of cat1, we can map a morphism between a and b to a morphism, this time in cat2, between mapObj a and mapObj b.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*1x5h8RbPw55TYczYAUUklg.png" /><figcaption><a href="http://yannesposito.com/Scratch/fr/blog/Category-Theory-Presentation/">http://yannesposito.com/Scratch/fr/blog/Category-Theory-Presentation/</a></figcaption></figure><p>It is probably the case to stress here that in general, in category theory mapObj and mapMor are indicated with the same symbol, because it is possible to distinguish between the two usages just by checking if their argument is an object or a morphism. But, since here we are actually trying to explain category theory to the Idris compiler, we are required to be extremely pedantic and precise, so we need to use two different symbols.</p><p>Are we done now, since we can map objects and morphisms? Don’t be in such a hurry, we have mapped only the bare structure, but that’s not all there is to a category. Actually, probably the main important idea laying around in a category is the one of composition, so when defining a functor we really need to ensure that we are preserving composition too.</p><pre>preserveCompose : (a, b, c : obj cat1)<br>               -&gt; (f : mor cat1 a b)<br>               -&gt; (g : mor cat1 b c)<br>               -&gt; mapMor a c (compose cat1 a b c f g)<br>                = compose cat2<br>                          (mapObj a)<br>                          (mapObj b)<br>                          (mapObj c)<br>                          (mapMor a b f)<br>                          (mapMor b c g)</pre><p>We introduce a new field preserveCompose in our Functor record which tells us that for any objects a, a and c and morphisms f : a -&gt; b and g: b-&gt; c of cat1, we obtain the same result if we do on of the following:</p><ul><li>compose f and g in cat1 and then map the result with mapMor</li><li>map f and g into cat2 using mapMor and then compose the results in cat2</li></ul><p>In other words, we can say that we can swap the order of composition and functor application, or better yet, that <em>functor application preserves composition.</em></p><p>Composition in a category actually comes also with the concept of identity, so a functor needs to preserve that too.</p><pre>preserveId : (a : obj cat1)<br>          -&gt; mapMor a a (identity cat1 a)<br>           = identity cat2 (mapObj a)</pre><p>This condition tells us that, given any object a of cat1, the identity morphisms of a is mapped by mapMor to the identity morphism, this time in cat2, of mapObj a, as one would expect.</p><h3><strong>Examples of functors</strong></h3><p>Now that we have a complete definition of a functor, it is time to see some concrete examples, investigating what functors are in the categories we introduced in our previous post.</p><h4><strong>Discrete categories</strong></h4><p>As we discussed last time, discrete categories are categories where the only morphisms are the identities of the objects. This means that, in practice, we can’t talk about composition in discrete categories. Everything is isolated in its own world. As a consequence, when defining a functor between discrete categories, we don’t need to bother with how mapMor will work, because it will even send only identities to identities, but we can concentrate only on mapObj.</p><p>Actually, if we cave two discrete categories cat1 and cat1, which sets of objects are respectively object cat1 and object cat2, every function f : object cat1 -&gt; object cat2 defines a functor. We can actually prove it as follows:</p><pre>functionMapMor :<br>     (f : a -&gt; b)<br>  -&gt; (x, y : a)<br>  -&gt; DiscreteMorphism x y<br>  -&gt; DiscreteMorphism (f x) (f y)<br>functionMapMor f x x Refl = Refl</pre><pre>functionPreserveCompose :<br>     (f : a -&gt; b)<br>  -&gt; (x, y, z : a)<br>  -&gt; (g : DiscreteMorphism x y)<br>  -&gt; (h : DiscreteMorphism y z)<br>  -&gt; functionMapMor f x z (discreteCompose x y z g h)<br>   = discreteCompose (f x)<br>                     (f y)<br>                     (f z)<br>                     (functionMapMor f x y g)<br>                     (functionMapMor f y z h)<br>functionPreserveCompose f x x x Refl Refl = Refl</pre><pre>functionAsFunctor :<br>     (f : a -&gt; b)<br>  -&gt; CFunctor (discreteCategory a) (discreteCategory b)<br>functionAsFunctor f = MkCFunctor f<br>                                 (functionMapMor f)<br>                                 (\_ =&gt; Refl)<br>                                 (functionPreserveCompose f)</pre><h4><strong>Monoids</strong></h4><p>We know that a monoid could be seen as a degenerate category with only one object, where the composition in the category is nothing else than the binary operation of the monoid and the identity morphism is the identity element of the monoid.</p><p>What about functors between such categories? Suppose we want to define a functor between categories monoidAsCategory monoid1 and monoidAsCategory monoid2; well, we don’t have a lot of choice for mapObj, we need to map the only object of the starting category to the only object of the target category. For mapMor, we need to map morphisms of monoidAsCategory monoid1 to morphisms of monoidAsCategory monoid2; but morphisms in these categories are just elements of the respective monoids. Therefore we need a function fun from monoid1 to monoid2. Moreover, for it to be the morphism component of a functor, we need it to respect composition and the identity morphism; but this amounts exactly to say that fun must be a <a href="https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms">monoid homomorphism</a>! We can actually prove that for every monoid homomorphism between monoids monoid1 and monoid2, we can build a functor between their associated categories monoidAsCategory monoid1 and monoidAsCategory monoid2.</p><pre>record MorphismOfMonoids domain codomain where<br>  constructor MkMorphismOfMonoids<br>  func : domain -&gt; codomain<br>  funcRespOp :<br>       (VerifiedSemigroup domain, VerifiedSemigroup codomain)<br>    =&gt; (a, b : domain)<br>    -&gt; FunctionRespectsOperation a b func<br>funcRespId :<br>       (VerifiedMonoid domain, VerifiedMonoid codomain)<br>    =&gt; FunctionRespectsIdentity func<br>morphismOfMonoidsToFunctor :<br>     (monoid1, monoid2 : Monoid)<br>  -&gt; MorphismOfMonoids monoid1 monoid2<br>  -&gt; CFunctor (monoidAsCategory monoid1)<br>              (monoidAsCategory monoid2)</pre><pre>morphismOfMonoidsToFunctor<br>  monoid1<br>  monoid2<br>  (MkMorphismOfMonoids fun frOp frId) =<br>MkCFunctor<br>  id<br>  (\_, _ =&gt; fun)<br>  (\_ =&gt; frId)<br>  (\_, _, _, f, g =&gt; frOp f g)</pre><h4><strong>Preorders</strong></h4><p>Let us recall that a preorder can be seen as a category with at most one morphism between any two objects, where the order structure is reflected in the presence or absence of a morphism.</p><p>Now, how does a functor between two such categories cat1 = preorderAsCategory {t1} {po1} and cat2 = preorderAsCategory {t2} {po2}, where po1 and po2 are partial orders respectively on t1 and t2, look like? It is constituted by a function f between mapObj cat1 = t1 and mapObj cat2 = t2 and, for any objects a and b, a function between mapMor cat1 a b = po1 a b and mapMor cat2 a b = po2 a b; since in these categories there is at most one morphism between any two objects a and b, the latter function can be interpreted by saying that if there is a morphism a -&gt; b, there must exists a morphism f a -&gt; f b. Translating this in preorder terms, this amounts to saying that a &lt;= b in po1 implies f a &lt;= f b in po2. This shows that functors between preorder categories are nothing else than order preserving functions! Let’s show in Idris that any order preserving function can be seen as a functor:</p><pre>record MonotoneMap<br>  (t1 : Type)<br>  (po1 : t1 -&gt; t1 -&gt; Type)<br>  (t2 : Type)<br>  (po2 : t2 -&gt; t2 -&gt; Type)<br>where<br>  constructor MkMonotoneMap<br>  func : t1 -&gt; t2<br>  funcRespOrd : (a, b : t1) -&gt; po1 a b -&gt; po2 (func a) (func b)<br>  <br>monotoneMapToFunctor :<br>     (UniquePreorder t1 po1, UniquePreorder t2 po2)<br>  =&gt; MonotoneMap t1 po1 t2 po2<br>  &gt; CFunctor (preorderAsCategory {t = t1} {po = po1})          <br>            (preorderAsCategory {t = t2} {po = po2})<br>monotoneMapToFunctor<br>  {t1}<br>  {po1}<br>  {t2}<br>  {po2}<br>  (MkMonotoneMap fun fRespectsOrd) =<br>MkCFunctor<br>  fun<br>  fRespectsOrd<br>  (\a =&gt; unique (fun a)<br>                (fun a)<br>                (fRespectsOrd a a (reflexive a))<br>                (reflexive (fun a)))<br>  (\a, b, c, f, g =&gt;<br>    unique (fun a)<br>           (fun c)<br>           (fRespectsOrd a c (transitive a b c f g))<br>           (transitive (fun a)<br>                       (fun b)<br>                       (fun c)<br>                       (fRespectsOrd a b f)<br>                       (fRespectsOrd b c g)))</pre><p>Recall that reflexive and transitive are the functions associated with the Preorder interface, while unique comes from the UniquePreorder interface we introduced in our last post.</p><p>Notice also how the preservation of the identity morphisms and of composition follow directly from the fact that there is at most one morphism between two objects. To prove that two morphisms are equal it is then enough to observe that they have the same origin and the same target.</p><h3><strong>Conclusion</strong></h3><p>Functors are our precise way of defining a change of context where information is preserved. Whenever in your mind you make a nice connection between two different worlds, and there is some kind of preservation of structure, it is really probable that you could express your thought formally in terms of categories and functors!</p><p>In our last post we introduced three classes of categories, respectively discrete categories and categories associated to monoids and to preorders. Today we observed that functors between such categories are exactly structure preserving morphisms between those objects. In the case of monoids, the operational structure is preserved; in preorders, functors are order preserving morphisms; in discrete categories, there’s no structure to preserve, so any function is fine!</p><p>If you know a bit of functional programming and have been playing around with <strong>Haskell</strong> or <strong>Idris</strong>, you will probably know that there is already a concept of Functor defined in the language. How does it relate with what we defined today? That’s exactly the question we will tackle in our next post!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=95e4e8d60d87" width="1" height="1" alt=""><hr><p><a href="https://medium.com/statebox/fun-with-functors-95e4e8d60d87">Fun with functors</a> was originally published in <a href="https://medium.com/statebox">Statebox</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>