<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Harrison Goldstein</title>
    <subtitle>Harrison Goldstein is an Assistant Professor of Computer Science and Engineering at the University at Buffalo, working on property-based testing, formal methods, and usable software validation tools.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://harrisongoldste.in/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://harrisongoldste.in"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-09-16T00:00:00+00:00</updated>
    <id>https://harrisongoldste.in/atom.xml</id>
    <entry xml:lang="en">
        <title>My New Favorite Mocktail</title>
        <published>2024-09-16T00:00:00+00:00</published>
        <updated>2024-09-16T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/mocktail/"/>
        <id>https://harrisongoldste.in/blog/mocktail/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/mocktail/">&lt;p&gt;Here&#39;s a quick post, just sharing a mocktail that I&#39;m workshopping.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;recipe&quot;&gt;Recipe&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2 oz. Lapsang souchong, brewed strong (around 1/2 as much water as normal)&lt;/li&gt;
&lt;li&gt;3 oz. Ginger beer (I like Fever Tree)&lt;/li&gt;
&lt;li&gt;1/2 oz. Rose vinegar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add the ingredients to a high-ball glass with ice and stir. Garnish with candied ginger if you have
it.&lt;/p&gt;
&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;/h2&gt;
&lt;p&gt;My favorite cocktail is the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Penicillin_(cocktail)&quot;&gt;Penicillin&lt;/a&gt;, and
while this mocktail ends up pretty far away from that starting point, it does hit some of the same
ginger-and-whiskey notes.&lt;/p&gt;
&lt;p&gt;Lapsang souchong has become popular as a non-alcoholic replacement for Scotch for good reason---it&#39;s
smokiness really does scratch the same itch, especially in a cocktail with other interesting things
going on.&lt;/p&gt;
&lt;p&gt;Ginger beer adds sweetness and... ginger. I could have done a more &quot;spirit forward&quot; mocktail with a
ginger syrup (as one would in a Pennicilin), but I think mocktails like that go by too quickly. The
ginger beer lets me make a longer drink that I don&#39;t finish in 5 minutes.&lt;/p&gt;
&lt;p&gt;The rose vinegar is, admittedly, where things get a bit weird. I like it because it has a bit more
bite than another acid like lemon juice would, which is helpful in a mocktail. Plus, the rose
flavor adds an extra little bit of excitement. Of course, I don&#39;t expect you have rose vinegar
around (and I won&#39;t for long either, I got mine at &lt;a rel=&quot;external&quot; href=&quot;https://noma.dk/&quot;&gt;Noma&lt;/a&gt; and I don&#39;t think I&#39;ll
be able to get more).  I think lemon juice would be a perfectly reasonable option instead, but
personally when I finish my rose vinegar I&#39;m going to experiment a bit with other vinegars first.
I&#39;ll update this post if I find anything interesting.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;/sup&gt;
&lt;p&gt;I don&#39;t claim that this is particularly original, I&#39;ve had drinks like it at restaurants. I&#39;m
just documenting my experiments making it myself.&lt;/p&gt;
&lt;/div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Appearance on Disseminate</title>
        <published>2024-07-08T00:00:00+00:00</published>
        <updated>2024-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/disseminate/"/>
        <id>https://harrisongoldste.in/blog/disseminate/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/disseminate/">&lt;p&gt;I had a lovely conversation with Dr. Jack Waudby on the &lt;i&gt;Disseminate&lt;/i&gt; podcast. We talked about
&lt;i&gt;Property-Based Testing in Practice&lt;/i&gt; and PBT in general. You can find the episode
&lt;a rel=&quot;external&quot; href=&quot;https://shows.acast.com/disseminate/episodes/harry-goldstein-property-based-testing-55&quot;&gt;here&lt;/a&gt;
or wherever you listen to podcasts.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Don&#39;t Give a No-Op Talk</title>
        <published>2024-04-22T00:00:00+00:00</published>
        <updated>2024-04-22T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/dont-give-a-no-op-talk/"/>
        <id>https://harrisongoldste.in/blog/dont-give-a-no-op-talk/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/dont-give-a-no-op-talk/">&lt;p&gt;I&#39;ve noticed a common failure mode among academic conference keynotes and other large audience talks
that I&#39;ve started calling a &quot;no-op&quot; talk.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; These talks are often delivered well and have
reasonably good structure, but they misunderstand their audience in an important way.
&lt;strong&gt;A no-op talk is unconvincing for your skeptics and boring for your allies.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So how do you know if you&#39;re giving a no-op talk? The classic form goes something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Center your talk around a controversial opinion.&lt;/li&gt;
&lt;li&gt;Recognize that you have allies in the audience, and spend most of your talk trying to &lt;em&gt;inform&lt;/em&gt;
them rather than &lt;em&gt;persuade&lt;/em&gt; skeptics.&lt;/li&gt;
&lt;li&gt;Recognize that you have skeptics in the audience, and &lt;em&gt;simplify&lt;/em&gt; your informative points so that
the skeptics can understand them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Did you see what happened? In point (2) you decided to alienate your skeptics, but then in point (3)
you decided to bore your allies. The resulting talk doesn&#39;t really work for anyone.&lt;/p&gt;
&lt;p&gt;By way of example, consider a talk arguing that dogs are better than cats. If the speaker starts &quot;we
all know that playing fetch is the greatest joy in the world&quot; — alienating many cat lovers — but
then continues with shallow discussion of well-known dog breeds — boring the dog lovers — that&#39;s a
no-op talk.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;When writing an opinionated talk, you need to carefully consider your goals. Are you trying to sway
the skeptics? In that case, start from first principles and speak to their values. When taking this
approach, don&#39;t forget to be humble and to honestly engage with the arguments against your stance;
this will make the audience more likely to trust you. You can do this in a way that is useful for
your allies as well — presenting a really clear and convincing argument for your point gives your
allies ammunition to argue that point in the future.&lt;/p&gt;
&lt;p&gt;On the other hand, you may say f*** the skeptics, I want to make my point without concessions. In
that case, just write the talk for your allies. Make points that they&#39;ll find interesting and
surprising, and make them in enough detail to show real depth. This may be confusing for those who
disagree with you, but, if you do it right, the skeptics in the room may find that your opinion has
more technical merit than they had expected. They&#39;ll be confused, but they may be compelled to
clarify that confusion later, rather than simply dismissing your opinion as shallow and unfounded
(as they would with a no-op talk).&lt;/p&gt;
&lt;p&gt;I know that giving talks is really difficult, and giving good talks is even harder. Academic
researchers are not trained orators, and it&#39;s totally understandable that not all large talks will
land. But I think that being a bit more mindful about our audiences and how our talks might impact
them is a great first step towards better academic communication.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;/sup&gt;
&lt;p&gt;Named after &quot;no-op&quot; computer instructions, which have no effect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;/sup&gt;
&lt;p&gt;For a programming languages audience, a more specialized version: consider a talk arguing that all software should be proved correct. If the speaker starts &quot;we all know that correctness is the most important thing in software engineering&quot; — alienating many — but then continues with shallow discussion of the available tools for proving code correct — boring the true believers — that&#39;s a no-op talk.&lt;/p&gt;
&lt;/div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Victor Basili Postdoctoral Fellowship</title>
        <published>2024-02-18T00:00:00+00:00</published>
        <updated>2024-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/victor-basili/"/>
        <id>https://harrisongoldste.in/blog/victor-basili/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/victor-basili/">&lt;p&gt;I&#39;m excited to announce that starting in Fall 2024 I will be working with Leonidas Lampropoulos at
the University of Maryland as a Victor Basili Postdoctoral Fellow.  With Leo&#39;s guidance I will
continue to explore themes from my PhD work on property-based testing, leveraging tools from
programming languages and human-computer interaction to improve the state of software testing.&lt;/p&gt;
&lt;p&gt;I can&#39;t wait to see what great opportunities for collaboration pop up over the next two years, and I
am honored to have been awarded this fellowship.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I was on TheForkJoin!</title>
        <published>2023-07-29T00:00:00+00:00</published>
        <updated>2023-07-29T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/theforkjoin/"/>
        <id>https://harrisongoldste.in/blog/theforkjoin/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/theforkjoin/">&lt;p&gt;Last week I had the pleasure of being a guest on &lt;a rel=&quot;external&quot; href=&quot;https://twitch.tv/theforkjoin&quot;&gt;TheForkJoin&lt;/a&gt;. I
chatted with Rachit Nigam and Oliver Flatt about my computer science journey, my research,
property-based testing in general.&lt;/p&gt;
&lt;p&gt;You can watch the video here:&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/tEXq-eSiFwk&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;I&#39;m also uploading a few YouTube Shorts with short clips and follow-ups from the conversation, on
&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/channel/UCcc1UtCXkMfmkKnjjFIC7Zg&quot;&gt;my YouTube channel&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing Tourist</title>
        <published>2019-04-14T00:00:00+00:00</published>
        <updated>2019-04-14T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/tourist-intro/"/>
        <id>https://harrisongoldste.in/blog/tourist-intro/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/tourist-intro/">&lt;p&gt;I&#39;ve been spending a lot of time lately working on a project that I&#39;m really
excited about. With the help of my roommate Jason, I&#39;ve been working on an
application Tourist. It&#39;s goal is to empower developers with an interesting
new way of writing documentation.&lt;/p&gt;
&lt;p&gt;The project page says,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tourist is a new approach to documentation that allows programmers to explain
low-level technical details of a system while simultaneously providing the
context of how those details fit into the broader architecture. It lets
programmers document code in the same way that they would explain it in
person: by walking the consumer step-by-step through the important parts of a
codebase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&#39;s really all Tourist is -- a tool (currently an extension for Visual
Studio Code) that allows programmers to guide virtual &quot;tours&quot; of their code.
Rather than writing technical documentation in a wiki or other format that is
totally external to the code, Tourist lets you associate documentation with
specific locations in the code, and then makes it easy to view that
documentation in the appropriate context.&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-tour&quot;&gt;What is a tour?&lt;/h2&gt;
&lt;p&gt;A tour is a series of code locations (a particular line in a particular file)
along with a markdown description of why that location is significant. The
locations (or &quot;stops&quot;) can be in different files and even in different git
repositories.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Tourist provides a simple interface for building and viewing tours. The GIF
below shows what it&#39;s like to view a tour in Visual Studio Code.&lt;/p&gt;
&lt;img src=&quot;/img/tourist-demo.gif&quot; alt=&quot;An animated screen recording of Visual Studio Code: clicking a tour stop jumps the editor to the right file and line, and the stop&#39;s markdown is rendered in a side panel.&quot; /&gt;
&lt;p&gt;When you click on a tour stop, your editor jumps to the appropriate file and
line, and the stop&#39;s markdown content is rendered in a &quot;web-view&quot;.&lt;/p&gt;
&lt;p&gt;Adding tour stops is as easy as viewing them. Once you have a tour file
created, you can simply right click in a file and ask tourist to add a stop
at that location. From there you can edit the stop content, move the stop
around, and reorder stops as needed.&lt;/p&gt;
&lt;p&gt;(This demo is fairly simple, and the first version of the extension is
planned to stay that way. That being said, we have lots of cool ideas for how
the extension can be made more powerful in the future, and we welcome
suggestions.)&lt;/p&gt;
&lt;h2 id=&quot;why-is-this-exciting&quot;&gt;Why is this exciting?&lt;/h2&gt;
&lt;p&gt;As I mentioned before, long-form external documentation like wiki pages is
disconnected from the code that it documents. A technical report can explain
a lot about class X or function Y, but you have to do your own legwork to
actually connect that information to the logic involved. In addition, it is
really easy to forget to maintain the documentation as the code changes. If
class X becomes class Z you need to change that in your documentation too,
and that documentation generally fairly far-removed from the place that you
made the change.&lt;/p&gt;
&lt;p&gt;Inline comments have a different issue: context. When you read inline
comments, you&#39;re generally only reading to understand a particular line or
set of lines. Maybe a docstring on a module or function gives you
&lt;em&gt;sligtly&lt;/em&gt; more context, but the main goal is still to explain the code that&#39;s
written &lt;em&gt;right here&lt;/em&gt;. When inline comments to try to explain broader context,
it can start to get hard to read the actual code. Tourist&#39;s idea of
documentation that is connected to a code location but not written inline is
an attractive solution to this problem.&lt;/p&gt;
&lt;p&gt;Of course, both inline comments and long-form documentation are important,
and Tourist doesn&#39;t necessarily intend to replace either. Long-form
documentation is still crucial for less technical documentation like user
manuals, as well as for more external techncial things like release notes.
Inline comments provide important insight into the nitty-gritty details of an
algorithm. Code tours bridge the gap between these worlds, rounding out a
project&#39;s documentation by addressing the interaction between high-level
architectural concerns and low-level information about the code itself.&lt;/p&gt;
&lt;h2 id=&quot;what-can-i-use-it-for&quot;&gt;What can I use it for?&lt;/h2&gt;
&lt;p&gt;This technology is still really new, and we expect that people will come up
with all sorts of interesting ways to use it. That being said, here are a few
things that I think tours are really good for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Onboarding.&lt;/strong&gt; Getting started with a new codebase is always a challenge, and
it&#39;s often really helpful to have someone who already knows the code walk
you through the important parts. Tourist provides a low-cost, repeatable
method of knowledge transfer. This is especially powerful when someone is
leaving a company or project and needs a quick way to write down as much
knowledge as possible. Someone can come along later and pick up the
project as if the old maintainer was still there.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Low-level demos.&lt;/strong&gt; When demoing a new feature or code-path to other
programmers, it is often helpful to show how data flows through the new
code. A code tour that hits each important branch point in turn makes it
really easy to see the impact of the change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Library overviews.&lt;/strong&gt; Automatically generated documentation isn&#39;t always
enough information for someone to use a library effectively. Library
writers can use Tourist to put use-case code snippets alongside the actual
code that is being called in the snippets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have other ideas, reach out and let me know! I&#39;m really excited to see
what we can do with this framework.&lt;/p&gt;
&lt;h2 id=&quot;how-can-i-get-it&quot;&gt;How can I get it?&lt;/h2&gt;
&lt;p&gt;Tourist is in extremely early alpha, so you&#39;ll need to build everything
yourself. First and foremost, you&#39;ll need &lt;code&gt;tourist&lt;/code&gt; from
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/hgoldstein95/tourist&quot;&gt;hgoldstein95/tourist&lt;/a&gt;, and unless
you&#39;re going to write your own editor extension, you&#39;ll want &lt;code&gt;tourist-vscode&lt;/code&gt;
at
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/hgoldstein95/tourist-vscode&quot;&gt;hgoldstein95/tourist-vscode&lt;/a&gt;.
Getting &lt;code&gt;tourist&lt;/code&gt; set up should be fairly straightforward -- the README
should have enough information. Once that&#39;s built, you can run&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;npm&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;from &lt;code&gt;tourist-vscode&lt;/code&gt; and start the extension with the debugger.&lt;/p&gt;
&lt;p&gt;If you&#39;re trying to get tourist up and running on your machine, feel free to
send me an email or create an issue on either of the above repositories. I&#39;m
happy to help anyone who wants to help us keep moving tourist forward.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Watch this blog for more about tourist! As we move towards a feature-complete
launch, I&#39;ll keep this page updated, and I&#39;ll probably post again with news
and information.&lt;/p&gt;
&lt;br/&gt;
&lt;hr /&gt;
&lt;br/&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;/sup&gt;
&lt;p&gt;As of now, Tourist requires that all of the code you reference is
versioned using git. In the future we hope to add support for subversion and
mercurial, but git is universal enough that we think this is the right place
to start.&lt;/p&gt;
&lt;/div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brown Butter Chocolate Chip Cookies</title>
        <published>2019-02-24T00:00:00+00:00</published>
        <updated>2019-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/chocolate-chip-cookies/"/>
        <id>https://harrisongoldste.in/blog/chocolate-chip-cookies/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/chocolate-chip-cookies/">&lt;p&gt;I know all two of you who read this blog are here for my computer science
content, but who doesn&#39;t like chocolate chip cookies??&lt;/p&gt;
&lt;p&gt;TL;DR: &lt;a href=&quot;https://harrisongoldste.in/blog/chocolate-chip-cookies/#recipe&quot;&gt;Jump to the recipe&lt;/a&gt; or &lt;a href=&quot;https://harrisongoldste.in/blog/chocolate-chip-cookies/#condensed&quot;&gt;jump to the super short, condensed recipe.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-setup&quot;&gt;The Setup&lt;/h3&gt;
&lt;p&gt;I&#39;ve been cooking and baking since I was little. My parents are both great
cooks with adventurous tastes, so I grew up eating tons of good food and
learning how to make it. One of the earliest things I remember baking are the
classic, back-of-the-chocolate-chip-bag recipe Toll House cookies. They&#39;d
always come out a little differently; sometimes they were soft and chewy,
sometimes crispy and crunchy. We used butter or margerine, just depending on
what we had around. We didn&#39;t know how or why the recipe worked, and we
didn&#39;t really care -- the cookies were perfect anyway.&lt;/p&gt;
&lt;p&gt;... well, the cookies were really good. The problem is, some batches were a
little better than others. I always liked them chewy, but sometimes they&#39;d
come out crispy. Eventually we figured out that cookies made with butter
were softer than the ones made with margerine; that helped, but there was
still so much variability in the finished product that I began to get
frustrated. By the time I was baking these cookies in college, I started to
feel like they had lost some of their charm.&lt;/p&gt;
&lt;h3 id=&quot;a-new-approach&quot;&gt;A New Approach&lt;/h3&gt;
&lt;p&gt;One evening, a trail of YouTube recommendations led me to no fewer than four
high-quality videos chocolate chip cookie recipes. Call it a stroke of luck
or just the algorithm at work, but all of a sudden I had all of the resources
I needed to fix my cookie problem. Here&#39;s what I watched (and I highly
recommend you do too):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=ylxzfecackM&quot;&gt;Binging with Babish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=oCt3xhKCX1k&quot;&gt;America&#39;s Test Kitchen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=rEdl2Uetpvo&quot;&gt;Tasty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=wCYBOOvCY5Y&quot;&gt;Serious Eats&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The recipes in these videos were similar to the one from my childhood, but
there were two important differences. First, these recipes were a little more
advanced. Each one added some interesting new flavors and/or procedures that
aimed to elevate the otherwise simple cookies. Second, many of these videos
talked through the food science behind their choices of ingredients and
processes. This was a huge improvement from the recipe on the chocolate chip
bag -- the extra context made it much easier to diagnose problems, explain
differences in batches, and experiement with modifications.&lt;/p&gt;
&lt;p&gt;I got to work on my own recipe. I took my favorite ideas from each, and ended
up with something that I&#39;m pretty excited about. Full disclosure, this recipe
is pretty darn close to the &lt;em&gt;Cook&#39;s Illustrated&lt;/em&gt; recipe from the America&#39;s
Test Kitchen video, but I worked in a few ingredient recommendations from the
Tasty one. The other two videos provided fewer direct ideas, but Babish and
Stella were awesome inspiration anyway.&lt;/p&gt;
&lt;p&gt;At this point you probably just want the recipe, so here you go.&lt;/p&gt;
&lt;div id=&quot;recipe&quot;&gt;&lt;/div&gt;
&lt;h3 id=&quot;the-recipe&quot;&gt;The Recipe&lt;/h3&gt;
&lt;h4 id=&quot;dry-ingredients&quot;&gt;Dry Ingredients&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;5 oz          All Purpose Flour&lt;/li&gt;
&lt;li&gt;3.8 oz        Bread Flour&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The Tasty recipe recommended bread flour for added chewiness. The ratio I
tried was just a guess, and in the end the cookies might have been a little
bit too chewy. I&#39;d consider shifting a little more towards the AP flour next
time, but I definitely like the idea of at least some bread flour.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;0.5 tsp       Baking Soda&lt;/li&gt;
&lt;li&gt;1.25 c        Chocolate Chips&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;I used normal semi-sweet chips this time, and I think it turned out really
well. Next time I&#39;ll see what difference chopped up baking chocolate makes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;wet-ingredients&quot;&gt;Wet Ingredients&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;1.75 stick    Butter&lt;/li&gt;
&lt;li&gt;3.5 oz        Granulated Sugar&lt;/li&gt;
&lt;li&gt;5.3 oz        Light Brown Sugar&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Most of the recipes called for dark brown sugar, but I don&#39;t tend to keep
it around. If I remember to buy some I might try the dark brown sugar, or I
might just try adding a teaspoon of molasses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;1 XL          Egg&lt;/li&gt;
&lt;li&gt;1 XL          Egg Yolk&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The standard Toll House recipe uses two eggs, but the America&#39;s Test
Kitchen video said that removing the second egg white actually makes the
cookies &lt;strong&gt;more&lt;/strong&gt; moist. I believe it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;1 tsp         Instant Espresso Powder&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This is another addition from the Tasty recipe. Coffee is great with
chocolate, and I&#39;m a caffeine addict, so why not?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;2 tsp         Vanilla Extract&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prepare dough:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brown 1 stick of butter in a stainless steel saucepan. Heat and stir/swirl
pan until the foaming stops and the milk solids begin to brown. Remove from
heat.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Browned butter is magic. Three out of the four videos recommend it, and
there&#39;s a good reason why. You can tell the difference instantly. The batter
smells and tastes like toffee. I&#39;ll never make this recipe with normal
butter again. Keep an eye on the butter while you&#39;re browning it, it burns
pretty easily.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Add the remaining 0.75 stick of butter to the pan and allow the butter to
melt together. Cool slighly.&lt;/li&gt;
&lt;li&gt;Combine wet ingredients in a bowl and stir for 30 seconds or so, until
everything is combined and no lumps of brown sugar remain.&lt;/li&gt;
&lt;li&gt;Wait 3 minutes, then stir for another 30 seconds. Repeat three times,
until mixture is smooth and glossy.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;This process comes from the Cook&#39;s Illustrated recipe, and the idea is to
dissolve the sugar without adding too much air. I definitely think it made a
difference in the consistency of the dough.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Combine dry ingredients in a bowl and stir to combine.&lt;/li&gt;
&lt;li&gt;Add the dry ingredients into the wet. This can be done fairly easily in
one installment, folding with a spatula. Do not over-mix.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Adding the chocolate to the flour and folding by hand ensures that you
won&#39;t overwork the dough. It also makes the dough super easy to make without
a stand mixer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;Chill the dough for 15-30 minutes.&lt;/li&gt;
&lt;li&gt;Turn the dough out onto a piece of wax or parchment paper, shape into a
rough rectangle, and cut into 16 equal pieces. Shape the pieces into balls.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;This is really the only innovation that I came up with myself. Chocolate chip
cookie recipes &lt;strong&gt;always&lt;/strong&gt; give instructions for scooping the cookies, but
I&#39;ve found that scooping can lead to poor chocolate chip distribution. No one
wants the sad cookie that you scooped at the end with only two chocolate
chips left. Cutting the dough into pieces makes it easier to get consistent
cookies with consistent chocolate. If you hit a chocolate chip with the kife,
just cut right through.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;9&quot;&gt;
&lt;li&gt;Refrigerate for up to 3 days (potentially longer?).&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;I need to see how long these keep before they&#39;re baked. Babish claims that the
batter actually keeps getting better for a few days, but I haven&#39;t done the
tests myself. I also want to know if you can freeze the dough balls -- I bet
you can.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When ready to bake:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Preheat oven to 375F.&lt;/li&gt;
&lt;li&gt;While the oven is preheating, let cookie dough come to room temperature.&lt;/li&gt;
&lt;li&gt;Place dough balls onto parchment paper and flatten slightly. Top with
coarse sea salt if desired.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;You should desire. The salt makes a huge difference. Don&#39;t flatten the
cookies too much, but they do need a little help spreading out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Bake for 12 minutes, or until the cookies are browned on the edges and not
completely set in the middle.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;They&#39;ll finish cooking on the tray. Or maybe they won&#39;t. Cookie dough is
amazing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Let cool on the sheet for 5 minutes, and then move to a wire rack to cool
completely.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;You&#39;re not going to let them cool completely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;the-results&quot;&gt;The Results&lt;/h3&gt;
&lt;p&gt;The cookies are pretty amazing, if I do say so myself. They&#39;re moist, chewy,
crispy at the edges, not too sweet, and basically everything else positive
that people have said about a chocolate chip cookie. I claim very little
credit for the recipe, but I am fairly excited about my idea to ditch the
scoop or spoon and just cut the cookies into the right size. Overall I&#39;m
mostly just happy because I&#39;m going to be able to make these cookies for any
and all cookie-appropriate occasions.&lt;/p&gt;
&lt;p&gt;Here&#39;s the recipe one more time without my interruptions...&lt;/p&gt;
&lt;br/&gt;
&lt;hr /&gt;
&lt;br/&gt;
&lt;div id=&quot;condensed&quot;&gt;&lt;/div&gt;
&lt;h2 id=&quot;brown-butter-chocolate-chip-cookies&quot;&gt;Brown Butter Chocolate Chip Cookies&lt;/h2&gt;
&lt;h4 id=&quot;dry-ingredients-1&quot;&gt;Dry Ingredients&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;5 oz          All Purpose Flour&lt;/li&gt;
&lt;li&gt;3.8 oz        Bread Flour&lt;/li&gt;
&lt;li&gt;0.5 tsp       Baking Soda&lt;/li&gt;
&lt;li&gt;1.25 c        Chocolate Chips / Chunks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;wet-ingredients-1&quot;&gt;Wet Ingredients&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;1.75 stick    Butter&lt;/li&gt;
&lt;li&gt;3.5 oz        Granulated Sugar&lt;/li&gt;
&lt;li&gt;5.3 oz        Light Brown Sugar&lt;/li&gt;
&lt;li&gt;1 XL          Egg&lt;/li&gt;
&lt;li&gt;1 XL          Egg Yolk&lt;/li&gt;
&lt;li&gt;1 tsp         Instant Espresso Powder&lt;/li&gt;
&lt;li&gt;2 tsp         Vanilla Extract&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prepare dough:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brown 1 stick of butter in a stainless steel saucepan. Heat and stir/swirl
pan until the foaming stops and the milk solids begin to brown. Remove from
heat.&lt;/li&gt;
&lt;li&gt;Add the remaining 0.75 stick of butter to the pan and allow the butter to
melt together. Cool slighly.&lt;/li&gt;
&lt;li&gt;Combine wet ingredients in a bowl and stir for 30 seconds or so, until
everything is combined and no lumps of brown sugar remain.&lt;/li&gt;
&lt;li&gt;Wait 3 minutes, then stir for another 30 seconds. Repeat three times,
until mixture is smooth and glossy.&lt;/li&gt;
&lt;li&gt;Combine dry ingredients in a bowl and stir to combine.&lt;/li&gt;
&lt;li&gt;Add the dry ingredients into the wet. This can be done fairly easily in
one installment, folding with a spatula. Do not over-mix.&lt;/li&gt;
&lt;li&gt;Chill the dough for 30 minutes.&lt;/li&gt;
&lt;li&gt;Turn the dough out onto a piece of wax or parchment paper, shape into a
rough rectangle, and cut into 16 equal pieces. Shape the pieces into balls.&lt;/li&gt;
&lt;li&gt;Refrigerate for up to 3 days (potentially longer?).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When ready to bake:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Preheat oven to 375F.&lt;/li&gt;
&lt;li&gt;While the oven is preheating, let cookie dough come to room temperature.&lt;/li&gt;
&lt;li&gt;Place dough balls onto parchment paper and flatten slightly. Top with
coarse sea salt if desired.&lt;/li&gt;
&lt;li&gt;Bake for 12 minutes, or until the cookies are browned on the edges and not
completely set in the middle.&lt;/li&gt;
&lt;li&gt;Let cool on the sheet for 5 minutes, and then move to a wire rack to cool.&lt;/li&gt;
&lt;/ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The (Regular) Language of Dance</title>
        <published>2018-04-02T00:00:00+00:00</published>
        <updated>2018-04-02T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/language-of-dance/"/>
        <id>https://harrisongoldste.in/blog/language-of-dance/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/language-of-dance/">&lt;p&gt;Over the last month or so, I&#39;ve gotten really into swing dancing. It&#39;s a new and
exciting challenge for me---I&#39;m not the most coordinated person, and dancing is
a unique kind of social interaction. For the most part, this has taken me well
out of my comfort zone. Luckily, as is often the case with learning new things,
I&#39;ve found ways to relate these new ideas to things I already know. In
particular, I realized that if you reeeally squint, swing dancing looks kind of
like a regular language.&lt;/p&gt;
&lt;h3 id=&quot;crash-course-in-swing-dancing&quot;&gt;Crash Course in Swing Dancing&lt;/h3&gt;
&lt;div style=&quot;text-align: center; margin: 20px&quot;&gt;
  &lt;img src=&quot;/img/swingout.gif&quot; alt=&quot;An animated loop of two dancers performing a swingout.&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;The dance that I&#39;ve been learning is usually called
&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/East_Coast_Swing&quot;&gt;East Coast Swing&lt;/a&gt;. It&#39;s a
really fun social dance that is set to quick swing music.&lt;/p&gt;
&lt;p&gt;The basic East Coast Swing step is a six-count pattern---depending on the tempo
of the music, the pattern is either &quot;rock step, triple step, triple step&quot; or
&quot;rock step, step, step&quot;. Often, dancers will also incorporate elements of &lt;em&gt;Lindy
Hop&lt;/em&gt;, a very closely related dance, which uses the eight-count pattern &quot;rock
step, triple step, step, step, triple step&quot;. The latter is what&#39;s happening in
the gif above.&lt;/p&gt;
&lt;p&gt;Of course, there&#39;s a lot more to dancing than footwork. In swing, partners dance
in a number of different holds and positions, and there are also tons of
different moves that make the dance fun and interesting. I highly recommend
checking out some YouTube videos of people dancing to get an idea of what I
mean.&lt;/p&gt;
&lt;h3 id=&quot;a-dancing-machine&quot;&gt;A Dancing Machine&lt;/h3&gt;
&lt;p&gt;When I started learning different swing moves, I realized that each move was
sort of a &quot;transition&quot; from one &quot;state&quot; to another. For example, the partners
might be dancing in closed position and the lead might use a &quot;tuck-turn&quot; to
transition to open position. More subtly, a left-side pass from open position
might leave the couple back in open position, but with the leader&#39;s hand on top
of the follow&#39;s hand (normal open position has the leader&#39;s hands under the
follow&#39;s).&lt;/p&gt;
&lt;p&gt;As a computer scientist, when I hear &quot;states&quot; and &quot;transitions&quot; I immediately
think of
&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Deterministic_finite_automaton&quot;&gt;finite automata&lt;/a&gt;.
A finite automaton is a mathematical structure that is often written out as a
graph like the ones below. The nodes are states, and the edges represent
transitions. When a node &lt;em&gt;p&lt;/em&gt; has an edge labeled &lt;em&gt;a&lt;/em&gt; to another node &lt;em&gt;q&lt;/em&gt;, you&#39;re
allowed to &quot;do &lt;em&gt;a&lt;/em&gt;&quot; to transition from &lt;em&gt;p&lt;/em&gt; to &lt;em&gt;q&lt;/em&gt;. Here is an automata that I
built based on the first few moves that I learned when I started doing
swing.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin: 20px&quot;&gt;
  &lt;img width=&quot;90%&quot; src=&quot;/img/dance.svg&quot; alt=&quot;A finite automaton with two states, Closed and Open, joined by arrows labelled with six-count swing moves: basic, tuck-turn, inside turn, and a right-side pass.&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, even with just a few moves and states, the diagram gets pretty
complicated pretty quickly. Focusing in on a particular state often helps to
clear things up; for example, looking at &quot;closed&quot;, we see that a basic step
would keep the couple in closed position, and a tuck-turn would transition to
open position.&lt;/p&gt;
&lt;h3 id=&quot;keeping-count&quot;&gt;Keeping Count&lt;/h3&gt;
&lt;p&gt;As we increase the complexity of the moves that we allow, there are a number of
interesting things that we can add to the model. Here&#39;s a slightly more
complicated automaton that incorporates some 8-count &quot;Lindy Hop&quot; moves.&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin: 20px&quot;&gt;
  &lt;img width=&quot;90%&quot; src=&quot;/img/dance2.svg&quot; alt=&quot;A larger finite automaton of swing moves, with extra states added so that the eight-count Lindy Hop moves have somewhere to return to.&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;The main thing to notice is that when I added 8-count moves, I added extra
states. Strictly speaking, dancing 8-count moves doesn&#39;t correspond to a
different &lt;em&gt;physical&lt;/em&gt; position, but it does correspond to a different &lt;em&gt;mental&lt;/em&gt;
position. When leading, it is important to be able to communicate your intent.
Your partner needs to know that you want to start dancing 8-count patterns after
a while of doing 6-count, and vice versa. Since my partners and I are usually
beginners, I try to use a simple move (like a basic) to go between standard East
Coast and Lindy.&lt;/p&gt;
&lt;h3 id=&quot;speaking-my-language&quot;&gt;Speaking My Language&lt;/h3&gt;
&lt;p&gt;It should be clear that if we focus in on only the moves and positions, we can
represent the space of East Coast Swing routines using a finite automaton. At
any given point in the dance, all of the &quot;valid&quot; moves would be available as
transitions, and other ones wouldn&#39;t. It is a well known fact in computer
science that every finite automaton corresponds to a (regular)
&lt;em&gt;language&lt;/em&gt;---formally some set of sequences of symbols (strings) that satisfies
some property. In this case, the &quot;symbols&quot; are swing moves, and the property is
that the whole sequence makes sense as a dance. This means that we literally
have a &quot;language&quot; of swing dance, and it corresponds exactly to routines.&lt;/p&gt;
&lt;p&gt;Taking this a step further, we can examine exactly which kinds of strings are in
the language of East Coast Swing. According to my &quot;beginner&quot; automaton above,
the string&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;basic, basic, tuck-turn, left-side pass, right-side pass&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;is a valid dance, but&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;right-side pass, basic&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;is not (since you can&#39;t do a right-side pass from closed position) and neither
is&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;tuck-turn, left-side-pass, left-side pass&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;because the lead&#39;s hand would get all flipped around.&lt;/p&gt;
&lt;p&gt;When I lead a dance, I can keep a model like this in my head. Obviously, I&#39;m not
actually simulating the automaton in earnest, nor am I really thinking about
strings and languages, but thinking about moves this way gives me a framework
for deciding what to do next. If the &quot;strings&quot; that my partner and I dance are
in the language of swing, I can be sure that the dance will feel natural.&lt;/p&gt;
&lt;h3 id=&quot;next-steps&quot;&gt;Next Steps &lt;img height=&quot;30px&quot; src=&quot;/img/steps.jpg&quot; alt=&quot;&quot; /&gt;&lt;/h3&gt;
&lt;p&gt;I have a lot of cool ideas for ways to use this language model of dance, and
I&#39;ll probably write another post exploring one or more of those options later.
For now, I&#39;ll just mention a couple of my ideas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Non-determinism.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The automata above are both (mostly) deterministic. This means that the current
state completely determines the effect of a move. Put more simply, it means that
there are no two arrows with the same label coming from the same source state.&lt;/p&gt;
&lt;p&gt;Technically speaking, labeling both &quot;closed&quot; and &quot;closed, 8-count&quot; as start
states is a form of non-determinism, but this is resolved as soon as the dance
starts, so it isn&#39;t very interesting. A more interesting form of non-determinism
is &quot;$\varepsilon$-transitions&quot;. An $\varepsilon$-transition is a transition
that happens without a symbol being read, or, in this case, without a move being
done. It turns out that these transitions don&#39;t actually change the set of
languages that automata can represent, but they do offer a compact and intuitive
way to consider state changes that don&#39;t depend on the input/moves.&lt;/p&gt;
&lt;p&gt;If I allowed myself to use $\varepsilon$-transitions, I could encode things
like the music speeding up, or even something as silly as &lt;em&gt;getting tired&lt;/em&gt;. In
both of these cases, we might want to restrict ourselves to simpler moves that
might be less time-consuming and labor-intensive. In the model, this would
correspond to a set of $\varepsilon$-transitions into a copy of the original
machine with the same states but fewer transitions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Matching up with music.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dancing is rarely done without music, and swing is no exception. A large part of
&quot;getting good&quot; at swing is developing musicality---a sense of how the music
should effect your choice of moves. If we want to express musicality in our
automata model, one place to start might be representing the music as an
automaton as well.&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin: 20px&quot;&gt;
  &lt;img width=&quot;60%&quot; src=&quot;/img/dance3.svg&quot; alt=&quot;A four-state cycle of an automaton counting out the four beats in a measure of swing music.&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;This simple automaton counts out the four beats in a measure of swing music.
Let&#39;s say we want to enforce that an 8-count move should always start at the
beginning of a measure. This won&#39;t always happen, since a 6-count moves often
end mid-measure, but it usually feels better.&lt;/p&gt;
&lt;p&gt;One way we could do this would be to simulate both automata simultaneously. Each
time we do a 6-count move, we advance the music automaton 6 steps, and each time
we do a 8-count move, advance it 8 steps. Now, we can make sure that 8-count
moves start at the beginning of a measure by making sure that the music
automaton is in state 1 before we do an 8-count move. I haven&#39;t quite worked out
a formal way of doing this yet, but I&#39;m sure there&#39;s a clean way to work the
music into the model.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I am fully aware that I made a ton of simplifications when talking about
dancing. There&#39;s a lot more to swing than strings of moves, and even if you do
ignore all of the human and musical aspects, it is still way more complex than I
made it out to be. My point wasn&#39;t to fully capture all of swing dance in one
computer science formalism---I just wanted to explore the space and see if I
could learn something.&lt;/p&gt;
&lt;p&gt;Dancing is fun&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, and computer science is fun&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. Putting them together is a
natural way for me to explore each in a little bit more depth, and in this case,
I think I got something pretty cool out of it.&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;/sup&gt;
&lt;p&gt;If you are already familiar with automata, you&#39;ll notice that I&#39;m ignoring
accepting states. We could theoretically use accepting states to decide
which moves are &quot;fun&quot; to end a routine on and which aren&#39;t. Here, for the
sake of simplicity, I&#39;m going to assume that every state is accepting except
for the implicit &quot;trap&quot; state.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;/sup&gt;
&lt;p&gt;For sufficiently musical definitions of fun.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;/sup&gt;
&lt;p&gt;For sufficiently nerdy definitions of fun.&lt;/p&gt;
&lt;/div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Derivatives of Regular Expressions</title>
        <published>2017-09-30T00:00:00+00:00</published>
        <updated>2017-09-30T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/derivatives-of-regular-expressions/"/>
        <id>https://harrisongoldste.in/blog/derivatives-of-regular-expressions/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/derivatives-of-regular-expressions/">&lt;blockquote&gt;
&lt;p&gt;Quick disclaimer: The ideas in this blog post are not my original work. I am
paraphrasing from lectures given by both Nate Foster and Dexter Kozen at
Cornell University, and adding some of my own intuition and insights where I
think it is helpful. My intent is to increase awareness of a cool thing that I
am excited about, not to pass any of this work off as my own.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Regular expressions come up a lot in computer science. From a theory
perspective, they are a compact and intuitive way to understand regular
languages. In practice, they allow programmers to recognize phone numbers,
search for files, and even parse HTML.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Up until about a month ago, I
thought I knew everything I wanted to know about regular expressions, and then I
discovered Brzozowski derivatives.&lt;/p&gt;
&lt;p&gt;Before I start, let&#39;s take a step back and define exactly what we mean by
regular expressions. Here&#39;s a nice inductive definition:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
r ::= \varnothing \mid a \mid r_1 + r_2 \mid r_1 r_2 \mid r^* \quad\quad a
\in \Sigma
$$
&lt;/div&gt;
&lt;p&gt;Note that this definition is minimal---I don&#39;t include things like $r^+$ or
$r?$ because they can be written in terms of the other operators. One bit of
common notation that I &lt;em&gt;will&lt;/em&gt; use is $\varepsilon$ to instead of
$\varnothing^*$; both are the regular expression denoting the empty string.&lt;/p&gt;
&lt;p&gt;At this point, I&#39;ll assume you have a general understanding of how to interpret
regular expressions; so if I write $a^*b^* + c$, you should know that it
denotes any string that is either zero or more $a$&#39;s followed zero or more
$b$&#39;s, or just $c$.&lt;/p&gt;
&lt;h3 id=&quot;the-brzozowski-derivative&quot;&gt;The Brzozowski Derivative&lt;/h3&gt;
&lt;p&gt;With notation out of the way, we can start to look at what a Brzozowski
derivative is.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Intuitively, it is a way of partially interpreting a regular
expression. The derivative of $r$ with respect to a character $a$,
$D_a(r)$, is a new regular expression that matches all strings from $r$ that
started with an $a$, but without the $a$. We &quot;take $a$ off the front of
$r$&quot;. For example,&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_b(foo + bar + baz) = ar + az
$$
&lt;/div&gt;
&lt;p&gt;Since $foo$ doesn&#39;t start with a $b$, we dropped that part of the expression
altogether. For each of the other pieces, we just took a $b$ off of the front.&lt;/p&gt;
&lt;p&gt;Now that we understand what we&#39;re going for, let&#39;s actually define a way to
compute $D_a(r)$. We&#39;ll do it inductively, step by step.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_a(\varnothing) = \varnothing
$$
&lt;/div&gt;
&lt;p&gt;This one should be pretty obvious. If you take $a$ off of every string in
$\varnothing$... well there were no strings to begin with.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_a(c) = \begin{cases}
\varepsilon &amp; a = c \\
\varnothing &amp; a \neq c
\end{cases}
$$
&lt;/div&gt;
&lt;p&gt;The idea here is that if you try to take $a$ off of the string $a$, you get
an empty string back, and if you try to take $a$ off of the string $c$
(where $c$ is some character that isn&#39;t $a$), you just can&#39;t do it.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_a(r_1 + r_2) = D_a(r_1) + D_a(r_2)
$$
&lt;/div&gt;
&lt;p&gt;If you want to take an $a$ off the front of an alternation, you can either
take it off of the first expression, or off of the second.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_a(r_1r_2) = D_a(r_1)r_2 + E(r_1)D_a(r_2)
$$
&lt;/div&gt;
&lt;p&gt;Uh oh. What does $E(r)$ mean? It&#39;s actually totally straightforward, and I&#39;ll
define it in detail soon. For now, just know that $E(r) = \varepsilon$ if
$r$ can denote the empty string, and $\varnothing$ otherwise. With that in
mind, this statement says that taking $a$ off of a concatenation either means
taking $a$ off of the first expression, or &lt;strong&gt;if the first expression can be
empty&lt;/strong&gt; taking $a$ off of the second expression.&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;math&quot;&gt;
$$
D_a(r^*) = D_a(r)r^*
$$
&lt;/div&gt;
&lt;p&gt;Finally, we can say that taking an $a$ off of a sequence of $r$&#39;s means
taking $a$ off of the first $r$, and leaving a sequence of $r$&#39;s after
that. This looks a little silly, but if you play around with it for a bit, it
should make sense.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;making-observations&quot;&gt;Making Observations&lt;/h3&gt;
&lt;p&gt;Let&#39;s go back and define $E(r)$, which we&#39;ll call the observation function.
Remember that it &quot;observes&quot; whether $r$ can denote the empty string, and
returns $\varepsilon$ or $\varnothing$ accordingly. Here&#39;s the definition:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\begin{aligned}
E(\varnothing) &amp;= \varnothing \\
E(a) &amp;= \varnothing \\
E(r_1 + r_2) &amp;= E(r_1) + E(r_2) \\
E(r_1r_2) &amp;= E(r_1)E(r_2) \\
E(r^*) &amp;= \varepsilon
\end{aligned}
$$
&lt;/div&gt;
&lt;p&gt;The only tricky thing here is convincing yourself that the $+$ and $\cdot$
cases work. These facts might help:&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\begin{aligned}
\varnothing + r &amp;= r \\
r + \varnothing &amp;= r \\
\varnothing r &amp;= \varnothing \\
r \varnothing &amp;= \varnothing \\
\varepsilon r &amp;= r \\
r \varepsilon &amp;= r
\end{aligned}
$$
&lt;/div&gt;
&lt;p&gt;It turns out that $E$ will be more important than just helping us define the
derivative. We can actually use the observation function to tell us about which
strings match a given expression.&lt;/p&gt;
&lt;h3 id=&quot;matching-strings&quot;&gt;Matching Strings&lt;/h3&gt;
&lt;p&gt;We&#39;re finally ready to implement a regular expression matcher. Let&#39;s can extend
our derivative function from earlier to handle entire strings:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\begin{aligned}
\textbf{D}_{\varepsilon}(r) &amp;= r \\
\textbf{D}_{ax}(r) &amp;= \textbf{D}_x(D_a(r))
\end{aligned}
$$
&lt;/div&gt;
&lt;p&gt;You can think of this as taking a derivative with respect to each character of
the string, in order, and accumulating the result. I now claim that $r$
matches a string $x$ if and only if&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
E(\textbf{D}_x(r)) = \varepsilon
$$
&lt;/div&gt;
&lt;p&gt;So how does this work? Well, $\textbf{D}_x(r)$ goes character-by-character in
$x$, taking each character off of $r$. This means that by the end, we will
have a regular expression that matches everything left in $r$ after taking the
string $x$ off the front.&lt;/p&gt;
&lt;p&gt;If we take $x$ off of the strings in $r$ and that set contains the empty
string, then it must be the case that $x$ was in $r$ to start with!
Conversely, if we know that $r$ matched $x$ to start with, then removing
$x$ from $x$ would leave us with $\varepsilon$.&lt;/p&gt;
&lt;p&gt;Practically, this means that we can use Brzozowski derivatives to write regular
expression matchers in code! I have a
&lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/hgoldstein95/0fe2def7591b44391521d988f28abf03&quot;&gt;Haskell implementation&lt;/a&gt;
as a gist on GitHub that you can check out, and I am also currently writing a
verified version in Coq.&lt;/p&gt;
&lt;h3 id=&quot;why-i-m-excited&quot;&gt;Why I&#39;m Excited&lt;/h3&gt;
&lt;p&gt;When I first learned about regular expressions formally, we were given a process
for implementing them:
0. Transform the regular expression into an $\varepsilon$-NFA, using a
Thompson construction.
0. Turn that $\varepsilon$-NFA into a normal NFA.
0. Determinize the NFA to get a DFA.
0. Run the DFA on the input string.&lt;/p&gt;
&lt;p&gt;There are things that I love about this algorithm too. It relies on the amazing
result that regular expressions, NFAs, and DFAs are all the same, and the
Thompson construction itself is really brilliant. But there&#39;s just something
that feels so nice and PL-ey about the derivative approach. Rather than deal
with intermediate representations and stateful algorithms, we can just define
our desired result by induction, and write pure functions that capture our
intent. The Brzozowski derivatives are also totally &lt;em&gt;symbolic&lt;/em&gt;. The whole
process is just replacing symbols with other symbols, which obviates the need
for any complex reasoning.&lt;/p&gt;
&lt;p&gt;Ultimately, this algorithm captures the reason that I study programming
languages. For me, doing computer science isn&#39;t about just solving the
problem.&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; It&#39;s about seeing the structure of the problem that you are working
with, and letting that structure guide you to an answer. It&#39;s about avoiding
complex decision procedures in favor of symbolic manipulations that simplify and
transform your goal. At the end of the day, Brzozowski derivatives are just a
different way of looking at regular expressions---but I think they&#39;re a really
freaking cool way of looking at regular expressions, so I wrote a blog post.&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;hr /&gt;
&lt;br&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;/sup&gt;
&lt;p&gt;For those of you who don&#39;t get the joke, this
&lt;a rel=&quot;external&quot; href=&quot;https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454&quot;&gt;stack overflow answer&lt;/a&gt;
is a must-read.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;/sup&gt;
&lt;p&gt;Technically, this is the Brzozowski &lt;em&gt;Syntactic&lt;/em&gt; Derivative. There is also
a Semantic Derivative that deals with DFAs and their denotations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;/sup&gt;
&lt;p&gt;If you reeeeally squint at these last two definitions you might see
something familiar. The concatenation and star rules here are similar in
structure to the product and power rules for derivatives in calculus. I
doubt this is just a coincidence. If I find a satisfying reason why, I&#39;ll
probably write another post about it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;/sup&gt;
&lt;p&gt;I&#39;m being sort of sloppy with my notation around equality. What I really
mean is that $[\![\varnothing + r ]\!] = [\![ r ]\!]$, etc., so $E(r)$
might not actually be equal to $\varepsilon$ or $\varnothing$, but it
will always be denotationally equal to one or the other.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;/sup&gt;
&lt;p&gt;To be clear, there&#39;s nothing wrong with &quot;just solving the problem&quot;---in
fact, that&#39;s usually a far more effective approach.&lt;/p&gt;
&lt;/div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Encryption and Adjunctions</title>
        <published>2017-05-26T00:00:00+00:00</published>
        <updated>2017-05-26T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/encryption-and-adjunctions/"/>
        <id>https://harrisongoldste.in/blog/encryption-and-adjunctions/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/encryption-and-adjunctions/">&lt;blockquote&gt;
&lt;p&gt;This post goes pretty deep into Category Theory, fairly quickly. For
explanations of some of the concepts used in this post, I highly recommend
&lt;a rel=&quot;external&quot; href=&quot;https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/&quot;&gt;this blog&lt;/a&gt;.
The post on &lt;a rel=&quot;external&quot; href=&quot;https://bartoszmilewski.com/2016/04/18/adjunctions/&quot;&gt;adjunctions&lt;/a&gt;
is especially relevant.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Category Theory, a monad is (loosely) defined as a functor $T$ with two
natural transformations:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\begin{aligned}
\eta &amp;: Id \to T \\
\mu &amp;: T \circ T \to T
\end{aligned}
$$
&lt;/div&gt;
&lt;p&gt;I wondered what it would look like to replace the $\mu$ with a slightly
different natural transformation:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\mu&#39; : T \circ T \to Id
$$
&lt;/div&gt;
&lt;p&gt;My intuition was that this might be useful for some kind of security
application. If the functor represented some kind of encryption, then $\eta$
allows one party to encrypt some data, and $\mu&#39;$ allows the data to be used
after being properly decrypted.&lt;/p&gt;
&lt;p&gt;In practice, however, this didn&#39;t quite make sense. The biggest problem was that
encryption and decryption are inverses, but they aren&#39;t symmetric. It seemed
that if this was going to work, I&#39;d need two functors (call them $L$ and
$R$), and a natural transformation:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\epsilon : L \circ R \to Id
$$
&lt;/div&gt;
&lt;p&gt;One party can encrypt some data using $R$, and the other can apply $L$ and
use $\epsilon$ to retrieve the data.&lt;/p&gt;
&lt;p&gt;If you know some Category Theory, you might know where this is going:
adjunctions! An adjunction is a pair of functors $L$ and $R$ with the
following natural transformations:&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
\begin{aligned}
\eta &amp;: Id \to R \circ L \\
\epsilon &amp;: L \circ R \to Id
\end{aligned}
$$
&lt;/div&gt;
&lt;p&gt;We write $L \dashv R$ to express this condition. Note that $\epsilon$ is
exactly what we wrote before! If we want to represent encryption as a pair of
functors, it would be smart to choose two &lt;em&gt;adjoined&lt;/em&gt; functors. (If you&#39;re
curious, the $\eta$ can actually be understood as the same $\eta$ from the
monad definition. For any adjunction, $R \circ L$ is a monad.)&lt;/p&gt;
&lt;p&gt;Since we&#39;d like this construct to be useful, we want candidates for $L$ and
$R$ that are endofunctors (functors from a category to itself) in the category
where objects are &lt;strong&gt;types&lt;/strong&gt;, and morphisms are &lt;strong&gt;pure functions&lt;/strong&gt;. (This
category is often called $Hask$, named after the Haskell programming
language.) One such adjunction is&lt;/p&gt;
&lt;div class=&quot;math&quot;&gt;
$$
(X, -) \dashv (X \to -)
$$
&lt;/div&gt;
&lt;p&gt;where $L$ is the product (or &lt;code&gt;Tuple&lt;/code&gt;) functor, and $R$ is the exponential
(or &lt;code&gt;Reader&lt;/code&gt;) functor. Using actual code (I&#39;m
using &lt;a rel=&quot;external&quot; href=&quot;https://www.idris-lang.org/&quot;&gt;Idris&lt;/a&gt; here), the functors are just data
types, and are written as follows:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;data L&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkL&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;data R&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkR&lt;/span&gt;&lt;span&gt; (k&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; a)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can convince ourselves that these functors are adjoined by implementing
$\eta$ and $\epsilon$, which are polymorphic functions that are
conventionally called &lt;code&gt;unit&lt;/code&gt; and &lt;code&gt;counit&lt;/code&gt; respectively:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;unit &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; R&lt;/span&gt;&lt;span&gt; k (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;L&lt;/span&gt;&lt;span&gt; k a)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;unit x &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkR&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;\&lt;/span&gt;&lt;span&gt;y &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkL&lt;/span&gt;&lt;span&gt; y x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;counit &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; L&lt;/span&gt;&lt;span&gt; k (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;R&lt;/span&gt;&lt;span&gt; k a)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;counit (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MkL&lt;/span&gt;&lt;span&gt; y (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MkR&lt;/span&gt;&lt;span&gt; f))&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; f y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what does any of this have to do with encryption? To answer that question,
we really need to figure out better names for &lt;code&gt;L&lt;/code&gt; and &lt;code&gt;R&lt;/code&gt;. Let&#39;s start with &lt;code&gt;R&lt;/code&gt;.
The key insight here is that &lt;code&gt;R&lt;/code&gt; sort of &lt;em&gt;hides&lt;/em&gt; data behind a function call. It
takes a value of type &lt;code&gt;a&lt;/code&gt;, and requires that we have a value of type &lt;code&gt;k&lt;/code&gt; if we
want our value back. Let&#39;s rename &lt;code&gt;R&lt;/code&gt; to &lt;code&gt;Encrypted&lt;/code&gt;, and write a function
&lt;code&gt;encrypt&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;data Encrypted&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkEncrypted&lt;/span&gt;&lt;span&gt; (k&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; a)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;encrypt &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; (k &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Type&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Encrypted&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;encrypt _ x &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkEncrypted&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; $ \&lt;/span&gt;&lt;span&gt;_ &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function is the reason that I opted to use a dependently typed language
like Idris over a more standard language. In order to get any use out of this
function, we need to be able to specify what type &lt;code&gt;k&lt;/code&gt; actually is; that requires
passing a type to encrypt as if it were data.&lt;/p&gt;
&lt;p&gt;Now that we have the &lt;code&gt;Encrypted&lt;/code&gt; functor, we can make a guess at what &lt;code&gt;L&lt;/code&gt; is
supposed to be. The name I settled on (somewhat unsurprisingly) was &lt;code&gt;Decrypter&lt;/code&gt;;
this is because the key contained within the tuple can be used to decrypt some
encrypted value.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;data Decrypter&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MkDecrypter&lt;/span&gt;&lt;span&gt; k a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we rewrite &lt;code&gt;counit&lt;/code&gt; from before, we can finally get:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;decrypt &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Decrypter&lt;/span&gt;&lt;span&gt; k (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;Encrypted&lt;/span&gt;&lt;span&gt; k a)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;decrypt (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MkDecrypter&lt;/span&gt;&lt;span&gt; x (&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MkEncrypted&lt;/span&gt;&lt;span&gt; f))&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; f x&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all of this machinery, we can:
0. Pick a type &lt;code&gt;k&lt;/code&gt;; in a dependently typed language, this type can be a proof of
some sort.
0. Call &lt;code&gt;encrypt k&lt;/code&gt; on some value of type &lt;code&gt;a&lt;/code&gt; to get an &lt;code&gt;Encrypted k a&lt;/code&gt;.
0. Use the &lt;code&gt;MkDecrypter&lt;/code&gt; constructor, along with a valid value of type &lt;code&gt;k&lt;/code&gt; to
make a &lt;code&gt;Decrypter k (Encrypted k a)&lt;/code&gt;.
0. Call &lt;code&gt;decrypt&lt;/code&gt; to get the original value out.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My main purpose with this exploration was to gain a deeper understanding of how
Category Theory interacts with real-world programming problems. While the end
result is not particularly useful, it does give some interesting insight into
what a &lt;em&gt;proof-relevant&lt;/em&gt; encryption system would look like.&lt;/p&gt;
&lt;p&gt;In addition, I found it extremely interesting how two inverse concepts like
encryption and decryption map nicely onto adjoined functors. While it is easy to
see that adjoined functors are inverses conceptually, it is exciting to see how
they model those behaviors in practice.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Elm, First Impressions</title>
        <published>2017-05-25T00:00:00+00:00</published>
        <updated>2017-05-25T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/elm-first-impressions/"/>
        <id>https://harrisongoldste.in/blog/elm-first-impressions/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/elm-first-impressions/">&lt;p&gt;I like exploring new programming languages and paradigms in my spare time. Here
are some of my thoughts on Elm.&lt;/p&gt;
&lt;p&gt;Elm is a purely functional, strongly typed language for web development. It&#39;s a
very opinionated language, with a very powerful run-time that is designed to make
writing web applications easy. There are some things that I really like about
Elm, and some things that I find frustrating. Your mileage may vary.&lt;/p&gt;
&lt;h2 id=&quot;pros&quot;&gt;Pros&lt;/h2&gt;
&lt;h3 id=&quot;the-elm-architecture&quot;&gt;The Elm Architecture&lt;/h3&gt;
&lt;p&gt;All Elm applications are written with the same general design pattern. The
general structure is similar to things like Redux and Flux (which is actually
based on Elm):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;model&lt;/code&gt;: A single object, encapsulating the entire state of the application.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update&lt;/code&gt;: A pure function that takes a message and a model and produces a new
model.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;view&lt;/code&gt;: A pure function that takes a model and produces instructions on how to
render the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This pattern is called &quot;The Elm Architecture&quot;, and the run-time supports it
directly. Once you specify these three components, the run-time sets up a model
and renders a view. Then, it listens for messages from the view, passes each
one to the &lt;code&gt;update&lt;/code&gt; function, changes the model accordingly, and re-renders only
the parts of the view that changed.&lt;/p&gt;
&lt;p&gt;I really like this approach because it manages abstraction in a really
intelligent way. On one hand, I have access to (and am expected to deal with)
all of the application-specific parts of my project. As a programmer, I need to
specify the application state, how that state changes, and what that state
&quot;looks like&quot;. On the other hand, machinery that is especially general (the
wiring) is taken out of the programmer&#39;s control completely. (There isn&#39;t a lot
of configuration in Elm; in general, if the run-time want&#39;s to handle something,
you&#39;re expected to let it.)&lt;/p&gt;
&lt;p&gt;A nice side effect of this is that Elm is actually really fast. In some sense,
the Architecture encompasses all of the slowest parts of the application---this
makes it free to heavily optimize those pieces.&lt;/p&gt;
&lt;h3 id=&quot;static-typing&quot;&gt;Static Typing&lt;/h3&gt;
&lt;p&gt;The other &lt;strong&gt;major&lt;/strong&gt; benefit of Elm is that it is statically typed. This means
that the compiler (and not the Chrome developer console) catches your mistakes.
I could go on for a long time about the benefits of a good type system, but I&#39;ll
leave that for another blog post.&lt;/p&gt;
&lt;h2 id=&quot;cons&quot;&gt;Cons&lt;/h2&gt;
&lt;h3 id=&quot;no-type-classes&quot;&gt;No Type Classes&lt;/h3&gt;
&lt;p&gt;Since Elm looks so much like Haskell, I often expect it to behave like Haskell.
While it does most of the time, sometimes it falls short. One large place this
happens is with type classes; since Elm does not support type classes it
misses out on some of the really nice features that come along with them.&lt;/p&gt;
&lt;p&gt;For example, rather than use &lt;code&gt;do&lt;/code&gt; notation to deal with monads, we need to
explicitly bind arguments into monadic functions (in Elm, most types define a
function called &lt;code&gt;andThen&lt;/code&gt; for this purpose). Keep in mind that this problem
is related to type classes because Haskell&#39;s &lt;code&gt;do&lt;/code&gt; is tied to the &lt;code&gt;Monad&lt;/code&gt; type
class; anything that implements &lt;code&gt;Monad&lt;/code&gt; supports &lt;code&gt;do&lt;/code&gt; notation.&lt;/p&gt;
&lt;p&gt;Things like &lt;code&gt;do&lt;/code&gt; notation would be a nice to have, but in the end, it isn&#39;t such
a big deal. One thing that is a big deal is how Elm deals with comparisons. In
Haskell, we have &lt;code&gt;Ord a&lt;/code&gt; which allows a user to define comparisons for their own
types. Elm uses something called &lt;code&gt;comparable&lt;/code&gt;, does the same job as &lt;code&gt;Ord&lt;/code&gt;,
without being a proper type class. Basically, a function&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can take any argument at all, but a function&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; comparable &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;can only take an argument that permits comparisons. Unfortunately, the only
types that are &lt;code&gt;comparable&lt;/code&gt; are &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Float&lt;/code&gt;, &lt;code&gt;Time&lt;/code&gt;, &lt;code&gt;Char&lt;/code&gt;, and &lt;code&gt;String&lt;/code&gt;---
that&#39;s it. There&#39;s no way to make a user defined type comparable, since
&lt;code&gt;comparable&lt;/code&gt; is just a built-in language construct and not a formal type class.
This is especially frustrating since the built in type &lt;code&gt;Dict&lt;/code&gt; (a dictionary
based on a balanced binary tree) has the following interface:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;get &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;:&lt;/span&gt;&lt;span&gt; comparable &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Dict&lt;/span&gt;&lt;span&gt; comparable v &lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; Maybe&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is that no user defined types can ever be the key of a dictionary,
even if there is a perfectly reasonable way to compare them.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Overall, I really like Elm. It&#39;s been fun to work with, and it&#39;s definitely
mature enough to be usable for some projects. It has some drawbacks, and I&#39;d
hesitate to put it into production just yet, but it&#39;s certainly heading in the
right direction.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why not try Spacemacs?</title>
        <published>2017-05-24T00:00:00+00:00</published>
        <updated>2017-05-24T00:00:00+00:00</updated>
        
        <author>
          <name>Harrison Goldstein</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://harrisongoldste.in/blog/why-not-try-spacemacs/"/>
        <id>https://harrisongoldste.in/blog/why-not-try-spacemacs/</id>
        
        <content type="html" xml:base="https://harrisongoldste.in/blog/why-not-try-spacemacs/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: I hope this post does not offend anyone. I do mention both
&lt;strong&gt;vim&lt;/strong&gt; and &lt;strong&gt;emacs&lt;/strong&gt;, so reader disgression is advised.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I first started programming, my teacher forced us to write our code in
Windows notepad. Not even &lt;em&gt;notepad++&lt;/em&gt;. Notepad.&lt;/p&gt;
&lt;p&gt;Looking back, I suppose I understand his rationale; if we learned to write code
with all of the assistance that an IDE provides, we wouldn&#39;t understand what is
actually going on. (Clicking &quot;Run&quot; is very different from typing &lt;code&gt;javac&lt;/code&gt; at the
command line, and I&#39;m glad that I started off with that deeper understanding.)
By the time that I was headed to college, I understood that I could write code
even without the bells and whistles of IDEs and code editors.&lt;/p&gt;
&lt;p&gt;But that didn&#39;t mean I could write &lt;em&gt;good&lt;/em&gt; code.&lt;/p&gt;
&lt;p&gt;Since those days, I have learned to rely on and appreciate the tools that are
available to help me do my work. Writing code is constant multitasking: a
programmer is simultaneously solving high level problems and dealing with the
nuance of implementing the solutions. Any experienced programmer will tell you
that it takes a lot of focus to write good code, so I am glad that there is such
a rich ecosystem of tools to make the process easier. I have used a number of
code editors and IDEs, from Eclipse to Sublime Text to, most recently, Vim. For
the last year or so, I learned to love Vim and it&#39;s amazingly efficient editing
style. It&#39;s how I write most of my code, as well as most things that aren&#39;t
code. It&#39;s completely changed the way that I think about programming.&lt;/p&gt;
&lt;p&gt;Lately, though, I have gotten a little bit frustrated with Vim. While I
appreciate its philosophy of configurability, it has become increasingly
frustrating to actually configure all of the behaviors that I want. I&#39;ve also
had more and more need for advanced code editing features like debugging and
linting, which are difficult or impossible to actually get set up in Vim.&lt;/p&gt;
&lt;p&gt;Enter Emacs.&lt;/p&gt;
&lt;p&gt;A few weeks ago, some lucky YouTube video recommendations led me to watch a few
talks on Emacs. From what I could see, it had all of the powerful features that
I was looking for, along with the same level of &quot;hackability&quot; that I had gotten
used to in Vim. Even more importantly, Emacs has &lt;code&gt;evil-mode&lt;/code&gt;. Evil stands for
&lt;strong&gt;E&lt;/strong&gt;xtensible &lt;strong&gt;vi L&lt;/strong&gt;ayer, and is basically a full implementation of Vim in
Emacs Lisp. (((Emacs uses a dialect of lisp to configure behavior instead of a
custom language like vimscript.))) That meant that I could have my cake and eat
it too; the editing style of Vim with the power of Emacs.&lt;/p&gt;
&lt;p&gt;There was just one problem left to tackle: Emacs pinky. I&#39;ll be honest, I don&#39;t
have the largest hands in the world, and the thought of reaching for control or
alt any time I wanted to do something was not particularly appealing.&lt;/p&gt;
&lt;p&gt;Enter spacemacs.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http://spacemacs.org&quot;&gt;Spacemacs&lt;/a&gt; is a custom Emacs distribution that is built
on &lt;code&gt;evil-mode&lt;/code&gt; and configured with Vim users in mind. Basically, Spacemacs
changes almost all of the Emacs key-bindings to the spacebar (the &quot;space&quot;, in
spacemacs) followed by a short string of characters. For example, &lt;code&gt;SPC f s&lt;/code&gt;
saves the current buffer, and &lt;code&gt;SPC g s&lt;/code&gt; displays an interactive window with Git
status information. In keeping with Vim&#39;s philosophy, these bindings all all
mnemonic; &quot;f s&quot; corresponds to &quot;file, save&quot;, &quot;g s&quot; for &quot;git, status&quot;, etc. It
was shocking how quick it was to get used to, and before I knew it I had written
a couple thousand lines of code (and this blog post) in spacemacs.&lt;/p&gt;
&lt;p&gt;So, if you happen to be like me (comfortable with Vim, but looking for a more
powerful code editor), give spacemacs a try. I can say for sure that it is the
first editor in a while that I&#39;ve felt actually has what I need.&lt;/p&gt;
</content>
        
    </entry>
</feed>
