summaryrefslogtreecommitdiff
path: root/reversible.html
diff options
context:
space:
mode:
Diffstat (limited to 'reversible.html')
-rw-r--r--reversible.html36
1 files changed, 18 insertions, 18 deletions
diff --git a/reversible.html b/reversible.html
index 378045f..24b5b87 100644
--- a/reversible.html
+++ b/reversible.html
@@ -2,11 +2,8 @@
<html>
<head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
-
<title>Reversible Programming Blew my Mind (Reversible Part 1)</title>
<meta property="article:published_time" content="2026-07-05">
- <link rel="stylesheet" href="prose.css">
<script src="./article.js"></script>
</head>
@@ -24,18 +21,21 @@
<div id="toc"></div>
<h2 id="math">Math basis</h2>
- <p>So remember in math class when you learned to take the inverse of a function?</p>
- <p>For example, say you have <code>y = 3*x + 6</code>.</p>
- <p>You can take the inverse by solving for x. In this case, the inverse of our function is <code>x = y/3 - 2</code>.</p>
- <p>The idea behind reversible programming is that there's a specific way to write your code such that it can <strong>automatically compute the inverse</strong>.</p>
+ <p>
+ So remember in math class when you learned to take the inverse of a function?
+ For example, say you have <code>y = 3*x + 6</code>.
+ You can take the inverse by solving for <code>x</code>.
+ In this case, the inverse of our function is <code>x = y/3 - 2</code>.
+ The idea behind reversible programming is that there's a specific way to write your code such that it can <strong>automatically compute the inverse</strong>.
+ </p>
<p>This has some wild implications:</p>
<ul>
<li>Writing a parser automatically gives you a pretty-printer implementation</li>
- <li>Database migrations are only <em>half</em> as scary (writing your <code>up</code> script automatically gives you your <code>down</code> script)</li>
+ <li>Database migrations are only <em>half</em> as scary (writing your <code><fn>up</fn></code> script automatically gives you your <code><fn>down</fn></code> script)</li>
<li>Writing operations on an image (ex. Photoshop clone) gives you free undo and redo.</li>
</ul>
<p>
- These are just a few of the crazy things you could <em>theoretically</em> do with Reversible Programming.
+ These are just a few of the crazy things you could <em>theoretically</em> do with reversible programming.
But how does it actually work?
</p>
@@ -58,7 +58,7 @@
<p>
As a nice starter, let's write a block that would compute addition.
- We can model this with a struct and an impl of the <code>Rev</code> trait.
+ We can model this with a struct and an impl of the <code><ty>Rev</ty></code> trait.
</p>
<pre><code><kw>struct</kw> <ty>Addition</ty>&lt;<ty>A</ty>&gt; {
<prop>amount</prop>: <ty>A</ty>
@@ -84,7 +84,7 @@
<p>
While the generics might look scary, this is just saying "the input and output can be any type that you can add and subtract with."
- Honestly these are light work compared to what's coming up.
+ <span class="comment">Honestly these are light work compared to what's coming up.</span>
</p>
<p>Oh, and it will look nicer if we have an easy way to construct an <code>Addition</code> block:</p>
<pre><code><kw>fn</kw> <fn>plus</fn>&lt;<ty>A</ty>&gt;(<id>amount</id>: <ty>A</ty>) -&gt; <ty>Addition</ty>&lt;<ty>A</ty>&gt; {
@@ -95,7 +95,7 @@
<pre><code class="language-rust"><kw>fn</kw> <fn>main</fn>() {
<kw>let</kw> <id>operation</id> = <fn>plus</fn>(<num>5</num>);
- <mac>println!</mac>(<str>"{}"</str>, <id>operation</id>.<fn>forward</fn>(<num>6</num>)); <com>// prints 11 (6 + 5 = 11)</com>
+ <mac>println!</mac>(<str>"{}"</str>, <id>operation</id>.<fn>forward</fn>(<num>6</num>)); <com>// prints 11 (6 + 5 = 11)</com>
<mac>println!</mac>(<str>"{}"</str>, <id>operation</id>.<fn>reverse</fn>(<num>11</num>)); <com>// prints 6 (11 - 5 = 6)</com>
}</code></pre>
@@ -103,14 +103,14 @@
trait impl said.</p>
<p>I've implemented a few more in the <a href="./reversible.rs#:~:text=%2F%2F%20more%20blocks">source code</a>:</p>
<ul>
- <li><code>neg()</code> negates a number</li>
- <li><code>times(x)</code> multiplies a number by x</li>
- <li><code>discrete(x: Vec&lt;(A, B)&gt;)</code> creates a reversible block out of a set of discrete inputs and outputs.</li>
+ <li><code><fn>neg</fn>()</code> negates a number</li>
+ <li><code><fn>times</fn>(x)</code> multiplies a number by x</li>
+ <li><code><fn>discrete</fn>(x: <ty>Vec</ty>&lt;(<ty>A</ty>, <ty>B</ty>)&gt;)</code> creates a reversible block out of a set of discrete inputs and outputs.</li>
</ul>
<h2 id="first">First Combinators</h2>
<p>
- The first combinator we'll implement is <code>Pipe</code>.
+ The first combinator we'll implement is <code><ty>Pipe</ty></code>.
This takes in two <code>Rev</code>s and and makes one that applies them in sequential order.
</p>
<pre><code><kw>struct</kw> <ty>Pipe</ty>&lt;<ty>X</ty>, <ty>Y</ty>&gt;(<ty>X</ty>, <ty>Y</ty>);
@@ -132,7 +132,7 @@
}</code></pre>
<p>
- Additionally, we'll implement <code>Inverse</code> (not to be confused with <code>.reverse()</code>).
+ Additionally, we'll implement <code><ty>Inverse</ty></code> (not to be confused with <code>.<fn>reverse</fn>()</code>).
This flips the forward and reverse methods.
</p>
<pre><code><kw>struct</kw> <ty>Inverse</ty>&lt;<ty>X</ty>&gt;(<ty>X</ty>);
@@ -194,7 +194,7 @@
<h2 id="under">Under</h2>
<p>
- <code>under</code> is a higher order combinator, which means it's implemented in terms of other combinators.
+ <code><fn>under</fn></code> is a higher order combinator, which means it's implemented in terms of other combinators.
Under basically says "do a thing, do another thing, then undo the first thing.
With this foundation built up, we can implement it quite easily:
</p>