Jekyll2020-07-22T16:28:20+00:00https://blog.aehmlo.me/feed.xmlAlex’s blogPosts about computers, music, programming, and whatever else is interesting at the time.Alex HamiltonImplementing yes(1) in Racket2020-07-22T16:09:00+00:002020-07-22T16:09:00+00:00https://blog.aehmlo.me/implementing-yes-in-racket<p>As an in-retrospect-inevitable consequence of my recent <a href="/coreutils-in-haskell-part-i">post about implementing <code class="language-plaintext highlighter-rouge">yes(1)</code> in Haskell</a>, I found myself itching to try out the implementation in a whole bunch of my less-familiar languages.
A language that I’ve been slowly picking up lately is <a href="https://racket-lang.org/">Racket</a>, a Lisp (based on Scheme) designed for designing and implementing programming languages.<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>
It’s the first Lisp I’ve properly learned (after being scared away from Common Lisp), and it’s fun to play around with — the syntax makes for a pleasant break from typical C-family language syntax.
A break was just what I needed,<sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup> so let’s implement <code class="language-plaintext highlighter-rouge">yes(1)</code> in Racket!</p>
<p>I’m going to be writing this as an interpreted script rather than a compiled program, so let’s start with the hashbang line:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env racket</span>
</code></pre></div></div>
<p>One of Racket’s most interesting and unique features is its <a href="https://docs.racket-lang.org/guide/hash-languages.html"><code class="language-plaintext highlighter-rouge">#lang</code> directive</a>, which lets you write code in any number of languages (which are then translated to Racket code by interpreters behind the scenes).
There are a handful of built-in languages.
For the most part, Racketeers try to stick to something like <code class="language-plaintext highlighter-rouge">racket/base</code>, a subset of the full Racket environment, but we’re going to need some things not offered there, so let’s just go with <code class="language-plaintext highlighter-rouge">#lang racket</code>.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#</span><span class="nv">lang</span> <span class="nv">racket</span>
</code></pre></div></div>
<p>Let’s start by defining a function that retrieves the target string to be printed from a list of command line arguments.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="nv">args</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nf">empty?</span> <span class="nv">args</span><span class="p">)</span> <span class="s">"y"</span> <span class="p">(</span><span class="nf">string-join</span> <span class="nv">args</span> <span class="s">" "</span><span class="p">))</span>
</code></pre></div></div>
<p>Hopefully this is easy enough to read: if the argument list given is empty, default to the string <code class="language-plaintext highlighter-rouge">"y"</code>, else join the list with spaces and use that.
Let’s take this a step further.</p>
<p>One of the other interesting features of Racket is <a href="https://docs.racket-lang.org/guide/contracts.html">contracts</a>, which allow a way of enforcing many behaviors at runtime.
There’s a lot more to contracts that I won’t get into here, but for the purposes of this I just want to use them as a sort of type system.
To define a contract at the function boundary, we can use the convenient <a href="https://docs.racket-lang.org/guide/contract-func.html#%28part._simple-nested%29"><code class="language-plaintext highlighter-rouge">define/contract</code></a> form.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="nv">args</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="p">(</span><span class="nf">listof</span> <span class="nv">string?</span><span class="p">)</span> <span class="nv">string?</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nf">empty?</span> <span class="nv">args</span><span class="p">)</span> <span class="s">"y"</span> <span class="p">(</span><span class="nf">string-join</span> <span class="nv">args</span> <span class="s">" "</span><span class="p">)))</span>
</code></pre></div></div>
<p>The contract in the second line can be read as “this function takes a list of strings and returns a string.”
This is something like <code class="language-plaintext highlighter-rouge">&[String] -> String</code> in Rust or <code class="language-plaintext highlighter-rouge">[String] -> String</code> in Haskell, but it’s enforced at runtime here.
If the contract is violated, we get a nice error message saying what went wrong and who’s to blame.</p>
<p>Now, we want to be able to fetch a list of command-line arguments in order to determine the string to print.
Racket’s docs discuss in great detail the <a href="https://docs.racket-lang.org/reference/Command-Line_Parsing.html"><code class="language-plaintext highlighter-rouge">command-line</code></a> form, but since we don’t need anything too fancy here, let’s just use the <a href="https://docs.racket-lang.org/reference/runtime.html#%28def._%28%28quote._~23~25kernel%29._current-command-line-arguments%29%29"><code class="language-plaintext highlighter-rouge">current-command-line-arguments</code></a> form.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">println</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="p">(</span><span class="nb">current-command-line-arguments</span><span class="p">)))</span>
</code></pre></div></div>
<p>Let’s give it a shot.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">chmod</span> +x yes.rkt
<span class="nv">$ </span>./yes.rkt
fetch-repeat-string: contract violation
expected: list?
given: <span class="s1">'#()
in: the 1st argument of
(-> (listof string?) string?)
contract from:
(function fetch-repeat-string)
# ...
</span></code></pre></div></div>
<p>Huh?
It looks like we’re not getting a list from <code class="language-plaintext highlighter-rouge">current-command-line-arguments</code>.
Let’s review the docs again:</p>
<blockquote>
<p>(current-command-line-arguments)</p>
<p>→ (vectorof (and/c string? immutable?))</p>
</blockquote>
<p>Ah!
<code class="language-plaintext highlighter-rouge">current-command-line-arguments</code> gives us a <a href="https://docs.racket-lang.org/guide/vectors.html">vector</a>, not a list.
Interesting.
Well, let’s update our contract to take a vector instead as well.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="nv">args</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="p">(</span><span class="nf">vectorof</span> <span class="nv">string?</span><span class="p">)</span> <span class="nv">string?</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nf">empty?</span> <span class="nv">args</span><span class="p">)</span> <span class="s">"y"</span> <span class="p">(</span><span class="nf">string-join</span> <span class="nv">args</span> <span class="s">" "</span><span class="p">)))</span>
</code></pre></div></div>
<p>And now let’s try again.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./yes.rkt
string-join: contract violation
expected: <span class="o">(</span>listof string?<span class="o">)</span>
given: <span class="s1">'#()
# ...
</span></code></pre></div></div>
<p>Ah, so <code class="language-plaintext highlighter-rouge">string-join</code> wants a list.
Well, let’s give it a list, then.
We can readily convert a vector into a list using the <a href="https://docs.racket-lang.org/reference/vectors.html#%28def._%28%28quote._~23~25kernel%29._vector-~3elist%29%29"><code class="language-plaintext highlighter-rouge">vector->list</code></a> form.<sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup>
First, let’s change our contract back.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="nv">args</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="p">(</span><span class="nf">listof</span> <span class="nv">string?</span><span class="p">)</span> <span class="nv">string?</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nf">empty?</span> <span class="nv">args</span><span class="p">)</span> <span class="s">"y"</span> <span class="p">(</span><span class="nf">string-join</span> <span class="nv">args</span> <span class="s">" "</span><span class="p">)))</span>
</code></pre></div></div>
<p>And now let’s change the other part:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">println</span>
<span class="p">(</span><span class="nf">fetch-repeat-string</span>
<span class="p">(</span><span class="nb">vector->list</span>
<span class="p">(</span><span class="nb">current-command-line-arguments</span><span class="p">))))</span>
</code></pre></div></div>
<p>Surely this ought to work?</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$</span> <span class="o">.</span><span class="nv">/yes</span><span class="o">.</span><span class="nv">rkt</span>
<span class="s">"y"</span>
</code></pre></div></div>
<p>The first thing I notice is that the quotation marks indicating that it’s a string are still present.
We can fix that readily enough by using <a href="https://docs.racket-lang.org/reference/Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29"><code class="language-plaintext highlighter-rouge">displayln</code></a> instead of <code class="language-plaintext highlighter-rouge">println</code>:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">displayln</span>
<span class="p">(</span><span class="nf">fetch-repeat-string</span>
<span class="p">(</span><span class="nb">vector->list</span>
<span class="p">(</span><span class="nb">current-command-line-arguments</span><span class="p">))))</span>
</code></pre></div></div>
<p>Let’s check to make sure.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./yes.rkt
y
</code></pre></div></div>
<p>Cool!
Now we just need to write a function to print the string repeatedly.
To do this, we can just make a recursive function:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">print-forever</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">loop</span><span class="p">)</span>
<span class="p">(</span><span class="nb">displayln</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">))</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">)</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">print-forever</code> function defines a new function (conceptually, a closure capturing the value of <code class="language-plaintext highlighter-rouge">str</code>) which calls itself repeatedly, then calls this function once to kick off the chain of execution.
Let’s enhance it with a contract.
Since this is a divergent function, it doesn’t return anything of meaning, so let’s say it returns <a href="https://docs.racket-lang.org/reference/void.html"><code class="language-plaintext highlighter-rouge">#<void></code></a>.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">print-forever</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="nv">string?</span> <span class="nv">void?</span><span class="p">)</span>
<span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">loop</span><span class="p">)</span>
<span class="p">(</span><span class="nb">displayln</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">))</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">))</span>
</code></pre></div></div>
<p>Now let’s update the tail end of the script and try it out.</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">begin</span>
<span class="p">(</span><span class="k">define</span> <span class="nv">str</span>
<span class="p">(</span><span class="nf">fetch-repeat-string</span>
<span class="p">(</span><span class="nb">vector->list</span> <span class="p">(</span><span class="nb">current-command-line-arguments</span><span class="p">))))</span>
<span class="p">(</span><span class="nf">print-forever</span> <span class="nv">str</span><span class="p">))</span>
</code></pre></div></div>
<p>Here we go!</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./yes.rkt
y
y
y
y
<span class="c"># ^C</span>
<span class="nv">$ </span>./yes.rkt <span class="s2">"hello world"</span>
hello world
hello world
hello world
hello world
<span class="c"># ^C</span>
<span class="nv">$ </span>./yes.rkt hello world
hello world
hello world
hello world
hello world
<span class="c"># ^C</span>
</code></pre></div></div>
<p>It looks like we’ve implemented (most of) <code class="language-plaintext highlighter-rouge">yes(1)</code> in Racket!
The final source listing is below.</p>
<hr />
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">; yes.rkt</span>
<span class="c1">#!/usr/bin/env racket</span>
<span class="o">#</span><span class="nv">lang</span> <span class="nv">racket</span>
<span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">fetch-repeat-string</span> <span class="nv">args</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="p">(</span><span class="nf">listof</span> <span class="nv">string?</span><span class="p">)</span> <span class="nv">string?</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nf">empty?</span> <span class="nv">args</span><span class="p">)</span> <span class="s">"y"</span> <span class="p">(</span><span class="nf">string-join</span> <span class="nv">args</span> <span class="s">" "</span><span class="p">)))</span>
<span class="p">(</span><span class="nf">define/contract</span> <span class="p">(</span><span class="nf">print-forever</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="nf">-></span> <span class="nv">string?</span> <span class="nv">void?</span><span class="p">)</span>
<span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">loop</span><span class="p">)</span>
<span class="p">(</span><span class="nb">displayln</span> <span class="nv">str</span><span class="p">)</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">))</span>
<span class="p">(</span><span class="nf">loop</span><span class="p">))</span>
<span class="p">(</span><span class="k">begin</span>
<span class="p">(</span><span class="k">define</span> <span class="nv">str</span>
<span class="p">(</span><span class="nf">fetch-repeat-string</span>
<span class="p">(</span><span class="nb">vector->list</span> <span class="p">(</span><span class="nb">current-command-line-arguments</span><span class="p">))))</span>
<span class="p">(</span><span class="nf">print-forever</span> <span class="nv">str</span><span class="p">))</span>
</code></pre></div></div>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>To those interested in using Racket to implement programming languages, I highly recommend <a href="https://beautifulracket.com/">Matthew Butterick’s <em>Beautiful Racket</em></a>. <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p>And a good friend <a href="https://xkcd.com/356/">nerd-sniped</a> me. Again. <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:3">
<p>One of my favorite parts of Racket is the amount of extra expressivity granted by the ability to use characters like dashes and <code class="language-plaintext highlighter-rouge"><</code>/<code class="language-plaintext highlighter-rouge">></code> in identifiers. <code class="language-plaintext highlighter-rouge">vector->list</code> is so clearly a conversion and it’s nice to look at, with just a bit of added whimsy. <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Alex HamiltonAs an in-retrospect-inevitable consequence of my recent post about implementing yes(1) in Haskell, I found myself itching to try out the implementation in a whole bunch of my less-familiar languages. A language that I’ve been slowly picking up lately is Racket, a Lisp (based on Scheme) designed for designing and implementing programming languages.1 It’s the first Lisp I’ve properly learned (after being scared away from Common Lisp), and it’s fun to play around with — the syntax makes for a pleasant break from typical C-family language syntax. A break was just what I needed,2 so let’s implement yes(1) in Racket! To those interested in using Racket to implement programming languages, I highly recommend Matthew Butterick’s Beautiful Racket. ↩ And a good friend nerd-sniped me. Again. ↩coreutils in Haskell, Part I2020-07-20T22:23:00+00:002020-07-20T22:23:00+00:00https://blog.aehmlo.me/coreutils-in-haskell-part-i<p>The first programming language I ever used was HTML.
This was in the days where all-caps tag/attribute names were all the rage.
My editor of choice? Notepad.
HTML was satisfying to write because it offered immediately visible results, and it was just plain <em>fun</em>.
I soon began perusing the plethora of learning materials available for HTML online and quickly discovered a technology called <em>JavaScript</em> that I was promised would provide my simple HTML pages with exciting dynamicity.
Soon after, I discovered the marvelous technology CSS, and suddenly I could make pretty web pages with cool interactive effects.
It was a period of joyful experimentation.</p>
<p>The rest of my programming journey is long enough to warrant another post, so I’ll save it for another time.
Suffice it to say that, while there has been plenty of fun and many satisfying things produced along the way, <em>learning Haskell is the first time programming has been as joyful as it was when writing HTML</em>.
It’s a different kind of satisfaction, to be sure, something which my experiences along the way have shaped me to be able to appreciate.
This blog post, which I’m calling “Part I” in an attempt to motivate myself to make it a series, is dedicated to sharing and celebrating that joy.
Of course, it won’t all be joyous, but there’s some truth to the platitudes about needing contrast to truly appreciate joy.</p>
<hr />
<p>I would certainly call myself a Haskell newcomer.
I’ve read <a href="https://learnyouahaskell.com/"><em>Learn You a Haskell for Great Good!</em></a> a couple of times, along with the requisite dozen or so blog posts explaining what a monad is.
I’ve also made it about halfway through Bartosz Milewski’s excellent <a href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/">“Category Theory for Programmers,”</a> in recorded lecture form.
Beyond that, about all I’ve done is implement a couple of IETF RFCs and most of a sudoku solver.
I enjoy the expressivity of Haskell and the sorts of reasoning enabled by functional programming abstractions.
This series is an attempt to explore Haskell more thoroughly and document the process for Haskellers, newcomers, and outsiders alike.
Let’s get started!</p>
<p>I’ve seen Rust veterans recommend that newcomers practice the language by reimplementing parts of <code class="language-plaintext highlighter-rouge">coreutils</code> themselves.
I suspect this is partly because of Rust’s role as a systems language, but I’ve decided to try this idea out with Haskell, so there you have it: the premise of this series.
I’ve decided to save my creativity for the actual programming and call this project <code class="language-plaintext highlighter-rouge">hutils</code>.
My understanding is that <a href="https://haskellstack.org">the <code class="language-plaintext highlighter-rouge">stack</code> project</a>’s goal is reproducible builds, which sounds fine to me, so I’ll use that, I guess?</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack new hutils
</code></pre></div></div>
<p>The command output suggests I’ve forgotten to do some configuration, so I guess I’ll try again.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> hutils
<span class="nv">$ </span>vim ~/.stack/config.yaml <span class="c"># YAML, huh? Surprising.</span>
<span class="nv">$ </span>stack new hutils
</code></pre></div></div>
<p>Oh cool, <code class="language-plaintext highlighter-rouge">~/.stack/config.yaml</code> has a lot of the missing fields already listed (and commented out).
Anyway, time to start actually editing.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd </span>hutils
<span class="nv">$ </span>exa <span class="c"># https://github.com/ogham/exa</span>
</code></pre></div></div>
<p>That’s a lot of files!
I’ll take a closer look later, but I’m really itching to write some code.
I’m guessing, based on my experience with Rust, that <code class="language-plaintext highlighter-rouge">app</code> is intended for executable stuff and <code class="language-plaintext highlighter-rouge">src</code> is for library stuff.
The presence of <code class="language-plaintext highlighter-rouge">src/Lib.hs</code> seems to reinforce this.</p>
<p>Wait a second — which utility do I want to replicate?
<code class="language-plaintext highlighter-rouge">nl</code> and <code class="language-plaintext highlighter-rouge">wc</code> come to mind, as do <code class="language-plaintext highlighter-rouge">cp</code> and <code class="language-plaintext highlighter-rouge">rm</code>.
<code class="language-plaintext highlighter-rouge">cat</code> seems likely to be unexpectedly complex.
On the other hand, <code class="language-plaintext highlighter-rouge">echo</code> seems too simple.
How about <a href="https://en.wikipedia.org/wiki/Yes_(Unix)"><code class="language-plaintext highlighter-rouge">yes</code></a>?
It contains a handful of interesting things while avoiding filesystem interaction: standard output, command line argument parsing, recursion, maybe some signal handling.
Sounds like a good candidate!</p>
<p>Some poking around in <code class="language-plaintext highlighter-rouge">stack.yaml</code> suggests that I can set up the project to accomodate multiple subprojects pretty easily.
Searching online makes it seem like I should be able to just create a subdirectory; maybe I’ll run <code class="language-plaintext highlighter-rouge">stack new</code> again?</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack new yus
</code></pre></div></div>
<p>Now I’ll add <code class="language-plaintext highlighter-rouge">./yus</code> to <code class="language-plaintext highlighter-rouge">packages</code> in <code class="language-plaintext highlighter-rouge">stack.yaml</code> and try <code class="language-plaintext highlighter-rouge">stack run yus</code>.
Oh yeah, I guess I’ll wait for <code class="language-plaintext highlighter-rouge">stack</code> to install GHC. Sure.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack run yus
someFunc
</code></pre></div></div>
<p>Just to make sure, I’ll edit <code class="language-plaintext highlighter-rouge">yus/src/Lib.hs</code> to print <code class="language-plaintext highlighter-rouge">"yus"</code> instead of <code class="language-plaintext highlighter-rouge">"someFunc"</code>.
Okay, let’s try again.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack run yus
someFunc
</code></pre></div></div>
<p>Hmm.
Running <code class="language-plaintext highlighter-rouge">stack run</code> from within <code class="language-plaintext highlighter-rouge">./yus</code> executes something called <code class="language-plaintext highlighter-rouge">yus-exe</code>; I’ll try fiddling with this.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack run yus-exe
yus
</code></pre></div></div>
<p>Annoying, but understandable.
Time to actually write some code.</p>
<hr />
<p>So, what does <code class="language-plaintext highlighter-rouge">yus</code> actually need to do?
I’m going to start with the most basic version: write a single <code class="language-plaintext highlighter-rouge">y</code>, followed by a newline, to standard output until interrupted.
But this is Haskell, so I want to think in terms of types first.
This function takes no (meaningful) argument and produces a side effect.
Namely, it writes something to standard output.
That is, it performs I/O, and it returns nothing meaningful.
I’ve seen this before: <code class="language-plaintext highlighter-rouge">IO ()</code>.
Since there’s no meaningful parameter type to assign, I’ll also use the unit type for this.
Otherwise, I think GHC will just treat my “function” as a constant, which I probably don’t want?
I think that might be not good for monadic effects?
I’ll have to remember to try that out later.</p>
<p>Okay, digressions aside, I now know at least the type of the “function” (which may be multiple functions) representing my program.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">yus</span> <span class="o">::</span> <span class="nb">()</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
</code></pre></div></div>
<p>I know I can write something followed by a newline with <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Prelude.html#v:putStrLn"><code class="language-plaintext highlighter-rouge">putStrLn</code></a>; is there something specifically for writing a character followed by a newline?
Searching <a href="https://hoogle.haskell.org/">Hoogle</a> for <code class="language-plaintext highlighter-rouge">Character -> IO ()</code> doesn’t show anything particularly interesting, so I guess I’ll stick with <code class="language-plaintext highlighter-rouge">putStrLn</code>.
Now all that’s left is to write an infinite loop.
I know that monadic control flow is often simplified using <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Control-Monad.html"><code class="language-plaintext highlighter-rouge">Control.Monad</code></a>, so I’ll take a look at those docs.
<a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Control-Monad.html#v:forever"><code class="language-plaintext highlighter-rouge">forever</code></a> looks promising:</p>
<blockquote>
<p>Repeat an action indefinitely.</p>
</blockquote>
<p>However, its written as <code class="language-plaintext highlighter-rouge">forever :: Applicative f => f a -> f b</code>.
Is <code class="language-plaintext highlighter-rouge">IO</code> an applicative functor?
Oh yeah, it’s a monad, so of course it is.
(Weird to think about putting a function inside <code class="language-plaintext highlighter-rouge">IO</code>, though.
I wonder if there’s some cool serialization library that lets me read functions directly from files.
I suppose GHC is one.)</p>
<p>It doesn’t totally make sense to me that <code class="language-plaintext highlighter-rouge">forever</code> takes an <code class="language-plaintext highlighter-rouge">f a</code> and gives me an <code class="language-plaintext highlighter-rouge">f b</code>, but let’s run with it.
In <code class="language-plaintext highlighter-rouge">yus/src/Lib.hs</code> (which I totally mistyped as <a href="https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html"><code class="language-plaintext highlighter-rouge">lib.rs</code></a> several times):</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Lib</span> <span class="p">(</span><span class="nf">yus</span><span class="p">)</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Control.Monad</span> <span class="p">(</span><span class="nf">forever</span><span class="p">)</span>
<span class="n">yus</span> <span class="o">::</span> <span class="nb">()</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">yus</span> <span class="kr">_</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">$</span> <span class="n">putStrLn</span> <span class="s">"y"</span>
</code></pre></div></div>
<p>As for <code class="language-plaintext highlighter-rouge">yus/app/Main.hs</code>:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Lib</span>
<span class="n">main</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">main</span> <span class="o">=</span> <span class="n">yus</span>
</code></pre></div></div>
<p>Wait, that’s not quite right.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Lib</span>
<span class="n">main</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">main</span> <span class="o">=</span> <span class="n">yus</span> <span class="nb">()</span>
</code></pre></div></div>
<p>I fully expect this to fail, since I don’t think the signature of <code class="language-plaintext highlighter-rouge">forever</code> is quite right for this usage.
One way to find out!</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>stack run yus-exe
y
y
y
y
<span class="c"># ...</span>
</code></pre></div></div>
<p>Uh-oh.
I hope I don’t have to do signal handling myself.
Nope, it responds to <code class="language-plaintext highlighter-rouge">SIGINT</code>!
Great!</p>
<p>…but why does that type-check?
Recall the type of <code class="language-plaintext highlighter-rouge">forever</code>:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">forever</span> <span class="o">::</span> <span class="kt">Applicative</span> <span class="n">f</span> <span class="o">=></span> <span class="n">f</span> <span class="n">a</span> <span class="o">-></span> <span class="n">f</span> <span class="n">b</span>
</code></pre></div></div>
<p>What does this actually say?
To me, at my current level of understanding, it promises to take an instance of an applicative functor <code class="language-plaintext highlighter-rouge">f a</code> and return a value of a completely different, apparently unrelated type <code class="language-plaintext highlighter-rouge">f b</code>.
Oh.
Of course.
It’s a divergent function!
For all I care, it could be implemented using <code class="language-plaintext highlighter-rouge">absurd</code>: it’s not going to return, so it can promise to return whatever makes our program type-check.
I can see how this might be convenient, but I think I’d prefer if it returned something like <code class="language-plaintext highlighter-rouge">Void</code>.
Maybe this somehow breaks the type system or the optimizer or something.
For now, I guess I’ll just accept that the weirdness is due to its nature as a divergent function.
Then the type signature is much less confusing.</p>
<hr />
<p>Now it’s time to learn what <code class="language-plaintext highlighter-rouge">yes</code> actually does.
I’m not sure I’ve ever actually used it (especially since discovering <code class="language-plaintext highlighter-rouge">apt-get -y</code> exists!).
I don’t anticipate that I’ll want to implement the whole set of functionality, but I’ll take a look before I decide one way or the other.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>man <span class="nb">yes</span>
</code></pre></div></div>
<p>Well, as it turns out, the GNU <code class="language-plaintext highlighter-rouge">coreutils</code> version of <code class="language-plaintext highlighter-rouge">yes</code> doesn’t actually take any arguments other than an optional string to repeat.
Testing it reveals that multiple arguments are simply joined with spaces and treated as a single argument, which is actually quite handy and an example of good shell ergonomics.
Anyway, I suppose it’s time to figure out how to get command line arguments in Haskell.</p>
<p>A quick search brings up <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/System-Environment.html#v:getArgs"><code class="language-plaintext highlighter-rouge">System.Environment.getArgs</code></a>.
Conveniently, the documentation says that the list returned by this function <em>doesn’t</em> contain the program name, which is something I had foreseen being an annoyance.</p>
<p>It seems to me that there are two outcomes:</p>
<ul>
<li>the argument list is empty — use the default string <code class="language-plaintext highlighter-rouge">y</code>; or</li>
<li>the argument list is nonempty — join the argument list with spaces and use this as the string to repeat.</li>
</ul>
<p>It seems like an almost silly abstraction to make, but I think it at least makes logical sense to separate concerns a little bit and make a function which repeats its argument on standard output indefinitely.
This can then be called either with <code class="language-plaintext highlighter-rouge">"y"</code> or with a string derived from user input.
The type of this function is pretty apparent:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
</code></pre></div></div>
<p>The implementation’s not much harder:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">writeForever</span> <span class="n">x</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">$</span> <span class="n">putStrLn</span> <span class="n">x</span>
</code></pre></div></div>
<p>Hmm…can I write that in point-free?</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">writeForever</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">.</span> <span class="n">putStrLn</span>
</code></pre></div></div>
<p>Nice!
Now I can move on to the problem of handling arguments.
I’ll write a function to fetch the string to be used, which also seems like an almost silly level of abstraction.
I know about <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Prelude.html#v:unlines"><code class="language-plaintext highlighter-rouge">unlines</code></a> to join strings with newlines; is there a version that uses spaces?
Searching Hoogle for <code class="language-plaintext highlighter-rouge">[String] -> String</code> brings me to <a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Prelude.html#v:unwords"><code class="language-plaintext highlighter-rouge">unwords</code></a>, which seems to be exactly what I want.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">targetString</span> <span class="o">::</span> <span class="kt">String</span>
<span class="n">targetString</span>
<span class="o">|</span> <span class="n">null</span> <span class="n">args</span> <span class="o">=</span> <span class="n">return</span> <span class="s">"y"</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span> <span class="n">unwords</span> <span class="n">args</span>
<span class="kr">where</span> <span class="n">args</span> <span class="o">=</span> <span class="n">getArgs</span>
</code></pre></div></div>
<p>Oops.
I completely forgot that this performs I/O.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fetchString</span> <span class="n">args</span> <span class="o">::</span> <span class="kt">String</span>
<span class="n">fetchString</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">return</span> <span class="s">"y"</span>
<span class="n">fetchString</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">unwords</span> <span class="n">xs</span>
<span class="n">targetString</span> <span class="o">::</span> <span class="kt">IO</span> <span class="kt">String</span>
<span class="n">targetString</span> <span class="o">=</span> <span class="n">fmap</span> <span class="n">fetchString</span> <span class="n">getArgs</span>
</code></pre></div></div>
<p>Somewhat less elegant, but I guess it’s good enough.
Now to connect all of the plumbing:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Lib</span> <span class="p">(</span><span class="nf">yus</span><span class="p">)</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Control.Monad</span> <span class="p">(</span><span class="nf">forever</span><span class="p">)</span>
<span class="kr">import</span> <span class="nn">System.Environment</span> <span class="p">(</span><span class="nf">getArgs</span><span class="p">)</span>
<span class="n">yus</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">yus</span> <span class="o">=</span> <span class="n">targetString</span> <span class="o">>>=</span> <span class="n">writeForever</span>
<span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">writeForever</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">.</span> <span class="n">putStrLn</span>
<span class="n">fetchString</span> <span class="o">::</span> <span class="p">[</span><span class="kt">String</span><span class="p">]</span> <span class="o">-></span> <span class="kt">String</span>
<span class="n">fetchString</span> <span class="kt">[]</span> <span class="o">=</span> <span class="s">"y"</span>
<span class="n">fetchString</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">unwords</span> <span class="n">xs</span>
<span class="n">targetString</span> <span class="o">::</span> <span class="kt">IO</span> <span class="kt">String</span>
<span class="n">targetString</span> <span class="o">=</span> <span class="n">fmap</span> <span class="n">fetchString</span> <span class="n">getArgs</span>
</code></pre></div></div>
<p>Rewriting this helped me see things a bit more clearly: since the I/O action is the entity of interest here (rather than some function producing an I/O action), there’s no reason <code class="language-plaintext highlighter-rouge">yus</code> has to “look like” (or be) a function; rather, it can simply be a constant with a value of type <code class="language-plaintext highlighter-rouge">IO ()</code>.
If I then say <code class="language-plaintext highlighter-rouge">main = yus</code>, the IO action bound to <code class="language-plaintext highlighter-rouge">yus</code> will simply be executed; there’s no reason that it has to take any arguments.
On that note, here’s <code class="language-plaintext highlighter-rouge">yus/app/Main.hs</code>:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Lib</span>
<span class="n">main</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">main</span> <span class="o">=</span> <span class="n">yus</span>
</code></pre></div></div>
<p>Short and sweet!
Trying it out returns the desired results; it would seem I’ve successfully reimplemented <code class="language-plaintext highlighter-rouge">yes</code> in Haskell by importing two functions from <code class="language-plaintext highlighter-rouge">base</code> and writing a handful of my own.
Fewer than twenty lines of code!
The Rustacean in me wants to go dig at performance characteristics, figure out how to explicitly lock <code class="language-plaintext highlighter-rouge">stdout</code>, etc., but exactly how often does <code class="language-plaintext highlighter-rouge">yes</code> need to supply input even multiple times per second?
I think this is good enough for me, for now.</p>
<p>Or <em>almost</em> good enough, anyway.
Defining both <code class="language-plaintext highlighter-rouge">fetchString</code> and <code class="language-plaintext highlighter-rouge">targetString</code> seems like overkill; surely I can find a way to reduce this verbosity?
After a bit of digging, I recall that <code class="language-plaintext highlighter-rouge"><$></code> exists as an infix alternative to <code class="language-plaintext highlighter-rouge">fmap</code>.
I’m going to try writing this in a different way.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Lib</span> <span class="p">(</span><span class="nf">yus</span><span class="p">)</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Control.Monad</span> <span class="p">(</span><span class="nf">forever</span><span class="p">)</span>
<span class="kr">import</span> <span class="nn">System.Environment</span> <span class="p">(</span><span class="nf">getArgs</span><span class="p">)</span>
<span class="n">yus</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">yus</span> <span class="o">=</span> <span class="n">fetchString</span> <span class="o"><$></span> <span class="n">getArgs</span> <span class="o">>>=</span> <span class="n">writeForever</span>
<span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">writeForever</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">.</span> <span class="n">putStrLn</span>
<span class="n">fetchString</span> <span class="o">::</span> <span class="p">[</span><span class="kt">String</span><span class="p">]</span> <span class="o">-></span> <span class="kt">String</span>
<span class="n">fetchString</span> <span class="kt">[]</span> <span class="o">=</span> <span class="s">"y"</span>
<span class="n">fetchString</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">unwords</span> <span class="n">xs</span>
</code></pre></div></div>
<p>I like this a lot more, but there’s one last thing: I really would prefer the <code class="language-plaintext highlighter-rouge">yus</code> function to be more intuitively readable scanning from left to right.
As it is now, the first conceptual “action” performed is written second on the right side.
I <em>could</em> use <code class="language-plaintext highlighter-rouge"><<=</code> instead of <code class="language-plaintext highlighter-rouge">>>=</code>, but I want to read left-to-right and not right-to-left.</p>
<p>I’m stumped.
I actually don’t know how to pull this off more elegantly.
I’ve heard good things about the Haskell community, and I seem to recall seeing something like the Rust “easy questions” thread on the Haskell subreddit; maybe I’ll ask there?</p>
<p>Sure enough, a while later, a very helpful <a href="https://reddit.com/u/philh">/u/philh</a> has a suggestion: I can import <code class="language-plaintext highlighter-rouge"><&></code> from <code class="language-plaintext highlighter-rouge">Data.Functor</code>, which is just <code class="language-plaintext highlighter-rouge"><$></code> with its arguments flipped!
This seems like a good deal to me.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">module</span> <span class="nn">Lib</span> <span class="p">(</span><span class="nf">yus</span><span class="p">)</span> <span class="kr">where</span>
<span class="kr">import</span> <span class="nn">Control.Monad</span> <span class="p">(</span><span class="nf">forever</span><span class="p">)</span>
<span class="kr">import</span> <span class="nn">Data.Functor</span> <span class="p">((</span><span class="o"><&></span><span class="p">))</span>
<span class="kr">import</span> <span class="nn">System.Environment</span> <span class="p">(</span><span class="nf">getArgs</span><span class="p">)</span>
<span class="n">yus</span> <span class="o">::</span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">yus</span> <span class="o">=</span> <span class="n">getArgs</span> <span class="o"><&></span> <span class="n">fetchString</span> <span class="o">>>=</span> <span class="n">writeForever</span>
<span class="n">writeForever</span> <span class="o">::</span> <span class="kt">String</span> <span class="o">-></span> <span class="kt">IO</span> <span class="nb">()</span>
<span class="n">writeForever</span> <span class="o">=</span> <span class="n">forever</span> <span class="o">.</span> <span class="n">putStrLn</span>
<span class="n">fetchString</span> <span class="o">::</span> <span class="p">[</span><span class="kt">String</span><span class="p">]</span> <span class="o">-></span> <span class="kt">String</span>
<span class="n">fetchString</span> <span class="kt">[]</span> <span class="o">=</span> <span class="s">"y"</span>
<span class="n">fetchString</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">unwords</span> <span class="n">xs</span>
</code></pre></div></div>
<p>Now <em>this</em> feels elegant.
The main <code class="language-plaintext highlighter-rouge">yus</code> function reads almost like English: “get arguments, fetch the string to print from them, then write it as output forever.”
<code class="language-plaintext highlighter-rouge">writeForever</code> is easy to read and understand intuitively as well, and it’s point-free to boot!
<code class="language-plaintext highlighter-rouge">fetchString</code> is unambiguous too; I think I even prefer the pattern matching to using <code class="language-plaintext highlighter-rouge">null</code>.</p>
<p>So what did I learn from this?
Well, I still have a bit of a tendency to think imperatively, as evidenced both by my function names and my worrying about the distinction between constants and functions.
I also learned about <code class="language-plaintext highlighter-rouge"><&></code> from <code class="language-plaintext highlighter-rouge">Data.Functor</code>, which I anticipate being helpful in the future.
My impression from reading the final result is that Haskell is extremely expressive, but finding the “words” to express what you want can be difficult at times, especially if you don’t know exactly what it is you’re looking for.
At any rate, this implementation was a lot of fun, and I’m very happy with the end result.
Onward!</p>Alex HamiltonThe first programming language I ever used was HTML. This was in the days where all-caps tag/attribute names were all the rage. My editor of choice? Notepad. HTML was satisfying to write because it offered immediately visible results, and it was just plain fun. I soon began perusing the plethora of learning materials available for HTML online and quickly discovered a technology called JavaScript that I was promised would provide my simple HTML pages with exciting dynamicity. Soon after, I discovered the marvelous technology CSS, and suddenly I could make pretty web pages with cool interactive effects. It was a period of joyful experimentation.