diff options
Diffstat (limited to 'reversible.html')
| -rw-r--r-- | reversible.html | 36 |
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><<ty>A</ty>> { <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><<ty>A</ty>>(<id>amount</id>: <ty>A</ty>) -> <ty>Addition</ty><<ty>A</ty>> { @@ -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<(A, B)>)</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><(<ty>A</ty>, <ty>B</ty>)>)</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><<ty>X</ty>, <ty>Y</ty>>(<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><<ty>X</ty>>(<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> |
